aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorjal2 <jal2>2003-03-21 20:21:20 +0000
committerjal2 <jal2>2003-03-21 20:21:20 +0000
commit66a398948dec930c0a1ead5a0b68c73485ac7075 (patch)
tree77282f0379670ca1dc748f2d0c9aef7d3eb73f9c
parent39fb196cdce478ea40c38b5587e9b3305e23d584 (diff)
-rw-r--r--Makefile128
-rw-r--r--README278
-rw-r--r--at76c503.c7536
-rw-r--r--at76c503.h519
-rw-r--r--at76c503fw.c362
-rw-r--r--externalr.h1500
-rw-r--r--ieee802_11.h223
-rw-r--r--internalr.h2170
-rw-r--r--rom2h.c39
-rw-r--r--usbdfu.c735
-rw-r--r--usbdfu.h19
11 files changed, 6879 insertions, 6630 deletions
diff --git a/Makefile b/Makefile
index e3667df..2eb9e46 100644
--- a/Makefile
+++ b/Makefile
@@ -1,103 +1,81 @@
-# Copyright (c) 2002 - 2003 Oliver Kurth
-# (c) 2003 - 2004 Jörg Albert <joerg.albert@gmx.de>
-#
-# This program is free software; you can redistribute it and/or
-# modify it under the terms of the GNU General Public License as
-# published by the Free Software Foundation; either version 2 of
-# the License, or (at your option) any later version.
-#
-
-# KERNEL_PATH is the path to the Linux kernel build tree. It is usually
-# the same as the kernel tree, except when a separate directory was used
-# for the binaries. By default, we try to compile the modules for the
-# currently running kernel.
-KERNEL_PATH ?= $(shell readlink -f /lib/modules/`uname -r`/build)
-
-ifeq (,$(KERNEL_PATH))
-$(error Kernel tree not found - please set KERNEL_PATH)
-endif
-
-VERSION_HEADER = $(KERNEL_PATH)/include/linux/utsrelease.h
-ifeq (,$(wildcard $(VERSION_HEADER)))
-VERSION_HEADER = $(KERNEL_PATH)/include/linux/version.h
-ifeq (,$(wildcard $(VERSION_HEADER)))
-$(error Kernel in $(KERNEL_PATH) is not configured)
-endif
-endif
+VERSION = 0.8
-# Kernel Makefile doesn't always know the exact kernel version, so we
-# get it from the kernel headers instead and pass it to make.
-KERNELRELEASE = $(shell sed -ne 's/"//g;s/^\#define UTS_RELEASE //p' \
- $(VERSION_HEADER))
+CC=gcc
+KERNEL_VERSION = $(shell uname -r)
-obj-m = at76_usb.o
+KERNEL_SRC = /lib/modules/$(KERNEL_VERSION)/build
+KERNEL_HEADERS = $(KERNEL_SRC)/include
-at76_usb-objs = at76c503.o
+MODULES = at76c503.o usbdfu.o
-SRCS = at76c503.c at76c503.h
+SRCS = at76c503.c usbdfu.c at76c503fw.c rom2h.c
+HDRS = internalr.h externalr.h at76c503.h ieee802_11.h usbdfu.h
+MODULE_DIR = $(DESTDIR)/lib/modules/$(KERNEL_VERSION)/kernel/drivers/usb/
+CPPFLAGS = -D__KERNEL__ \
+ -DMODULE -DEXPORT_SYMTAB \
+ -DDRIVER_VERSION=\"v$(VERSION)\" \
+ -I$(KERNEL_HEADERS)
+CFLAGS = -O2 -Wall -Wstrict-prototypes -pipe
-SPECFILE = at76c503a.spec
+MODVER = $(shell if cat $(KERNEL_HEADERS)/linux/autoconf.h 2>/dev/null | \
+grep -q '^[[:space:]]*\#define[[:space:]]*CONFIG_MODVERSIONS[[:space:]]*1'; \
+then echo 1; else echo 0; fi)
-DISTFILES = $(SRCS) Makefile README COPYING CHANGELOG kernel_patch.diff
-
-# get the version from at76c503.h
-ifndef M
-VERSION = $(shell sed -n 's/^\#define.*DRIVER_VERSION.*"\(.*\)".*$$/\1/p' at76c503.h)
-DISTNAME = at76_usb-$(VERSION)
-DISTDIR = $(DISTNAME)
+ifeq ($(MODVER),1)
+MFLAG = -DMODVERSIONS -include $(KERNEL_HEADERS)/linux/modversions.h
endif
-INSTALL_MOD_DIR = kernel/drivers/net/wireless
-MODULE_DIR = $(INSTALL_MOD_PATH)/lib/modules/$(KERNELRELEASE)/$(INSTALL_MOD_DIR)
-DEPMOD = /sbin/depmod
-
-SPARSE_FLAGS = -Wall -D__CHECK_ENDIAN__
+CCDEP = $(CC) $(CFLAGS) -M
+TAR = tar
-PWD = $(shell pwd)
-KBUILD_FLAGS = -C $(KERNEL_PATH) M=$(PWD) KERNELRELEASE=$(KERNELRELEASE)
+DISTFILES = $(SRCS) $(HDRS) Makefile README COPYING
+TOPDISTFILES =
+DISTNAME = at76c503-$(VERSION)
+DISTDIR = ../dist
+all: $(MODULES)
-all: modules
+at76c503fw: at76c503fw.c
+ $(CC) $(CFLAGS) -o $@ $< -lusb
-modules:
- $(MAKE) $(KBUILD_FLAGS) modules
+rom2h: rom2h.c
+ $(CC) $(CFLAGS) -o $@ $<
-check:
- $(MAKE) $(KBUILD_FLAGS) C=2 CF="$(SPARSE_FLAGS)"
+TAGS:
+ rm -f TAGS
+ find $(KERNEL_SRC)/ -name '*.[ch]' | xargs etags --append
+ etags --append $(SRCS) $(HDRS)
-install:
- rm -rf $(MODULE_DIR)/at76*
- $(MAKE) $(KBUILD_FLAGS) modules_install \
- INSTALL_MOD_DIR="$(INSTALL_MOD_DIR)"
- $(DEPMOD) -ae
+install: all
+ mkdir -p $(MODULE_DIR)
+ for f in $(MODULES); do install -m 644 -o 0 -g 0 $$f $(MODULE_DIR)/$$f; done
+ /sbin/depmod -a
uninstall:
- rm -rf $(MODULE_DIR)/at76*
-
-TAGS:
- rm -f TAGS
- etags --append $(SRCS)
+ for f in $(MODULES); do rm $(MODULE_DIR)/$$f; done
clean:
+ rm -f at76c503fw rom2h
rm -f core *.o *~ a.out *.d
- rm -f *.ko *.mod.c .*.cmd
rm -f *.s *.i
- rm -rf .tmp_versions
-
-ChangeLog: CVS/Entries
- cvs2cl
dist:
- rm -rf $(DISTNAME)
+ [ -d $(DISTNAME) ] && rm -rf $(DISTNAME) || true
mkdir $(DISTNAME)
- cp -f $(DISTFILES) $(DISTNAME)
- sed 's/^%define PACKVER.*$$/%define PACKVER $(VERSION)/' \
- $(SPECFILE) >$(DISTNAME)/$(SPECFILE)
+ cp -aR $(DISTFILES) $(DISTNAME)
tar zcvf $(DISTNAME).tar.gz $(DISTNAME)
rm -rf $(DISTNAME)
-rmmod:
- -rmmod $(obj-m:%.o=%)
+.PHONY: dist
+
+%.o: %.c
+ $(CC) -MD $(CFLAGS) $(CPPFLAGS) $(MFLAG) -c $<
+
+%.s: %.c
+ $(CC) -MD $(CFLAGS) $(CPPFLAGS) -S $<
+
+%.i: %.c
+ $(CC) -MD $(CPPFLAGS) -E $< -o $@
-.PHONY: all modules check install uninstall clean dist rmmod
+-include $(SRCS:%.c=%.d)
diff --git a/README b/README
index 1b34105..93c1984 100644
--- a/README
+++ b/README
@@ -1,250 +1,96 @@
-at76_usb - Linux Driver for Atmel Based USB WLAN Adapters
-=========================================================
+at76c503 - linux driver for Atmel at76c503 based usb wlan adapters
+------------------------------------------------------------------
-This is a Linux driver for the Atmel based USB WLAN adapters. Unlike
-the driver developed by Atmel (atmelwlandriver), this driver is intended
-to be accepted into the kernel, so it aims to be bloat-free, streamlined
-and modern.
-
-The authors of this driver are not associated with Atmel or any
-corporation that builds devices with this chip. The only information
-source about the hardware is the Atmel's driver from
-http://atmelwlandriver.sourceforge.net/
-
-Look at http://at76c503a.berlios.de/ for more accurate information,
-mailing lists and links.
-
-
-Hardware Compatibility
-----------------------
-
-This driver supports USB devices using Atmel at76c503, at76c505 and
-at76c505a chipsets. Known devices with this chip are:
+This is a another driver for the Atmel based USB WLAN adaptors. I am
+developing this driver in private. I am not associated with Atmel, or
+any cooperation that builds devices with this chip. My only
+information source is the driver from
+http://atmelwlandriver.sourceforge.net.
+Known devices with this chip are:
- Belkin F5D6050
- Dynalink/Askey WLL013
- Linksys WUSB11 v2.6
- Netgear MA101B
-and many more.
-
+It is early in development. Currently, it has some limitations:
-Requirements
-------------
+- to change the essid or channel, the network has to be restarted
+ (with ifconfig)
-Linux kernel 2.6.x (preferably current) with support for USB and
-wireless networking.
+If you are looking for a more complete driver, look at
+http://atmelwlandriver.sourceforge.net.
-Firmware for your device in the format compatible with this driver. To
-install the firmware, please read the README file included with the
-firmware package. The firmware can be downloaded from
-https://developer.berlios.de/projects/at76c503a/
-
-
-Installation
+Reqirements:
------------
-To compile the driver, just run "make". The build system defaults to
-compiling the driver against the sources of the currently running
-kernel. If you want to compile for a different kernel, you may need to
-specify KERNEL_PATH on the command line.
-
-If the kernel was compiled in a separate directory, KERNEL_PATH should
-point to that directory, not to the source tree. The driver itself will
-always compile in its source directory.
-
-When cross-compiling, you may also need to set ARCH and CROSS_COMPILE
-appropriately. See the top-level kernel Makefile for details.
-
-To install the driver, run "make install" as root. If you supplied any
-extra variables to "make", add them to "make install" as well.
-
-
-Running
--------
-
-First of all, please make sure that the firmware is installed. The
-driver will not work without the firmware.
-
-Once the firmware and the driver are installed, you can connect the
-device. On most modern distributions, the driver will be loaded
-automatically. The driver will load the firmware using hotplug or udev
-facility and will create a network interface for each device it finds.
-
-To make sure that it worked correctly, run "iwconfig". It will show all
-available wireless interfaces.
-
-To configure the device, use "iwconfig" for wireless specific settings
-and "ifconfig" or "ip" for network settings.
-
-If you want the device to be configured in a certain way on system
-startup, please use the facilities provided by your distribution.
-
-The driver supports managed, ad-hoc and monitor modes.
-
-
-Troubleshooting
----------------
-
-If you have any problems with the driver, it's always a good idea to
-check the messages from the kernel. Use "dmesg" to display them.
-
-If you are not sure whether the driver is loaded, use "lsmod" to see the
-list of the loaded modules. Look for "at76_usb". If it's not there,
-load it manually by "modprobe":
-
- modprobe at76_usb
-
-If the driver is loaded but a wireless interface doesn't appear, make
-sure that the firmware is loaded by the driver. If the driver cannot
-load the firmware, there will be a message from the driver in the kernel
-log. Make sure that you have a file with exactly that name and that
-it's located in the firmware directory known to hotplug or udev.
-
-If you see a wireless interface but you are not sure which driver
-created it, use "ethtool -i wlanX", where "wlanX" is the interface name.
-
-If the interface is up, but "iwconfig" shows that it's not associated to
-an access point, make sure that the card is in managed mode and that it
-uses the same ESSID and WEP key as the access point you want to connect
-to. If using WEP, make sure you are using an authentication method
-supported by the access point.
-
-When in the ad-hoc mode, make sure that all the participants are using
-the same channel.
-
-To learn about available access points, use "iwlist wlanX scan" where
-"wlanX" is the interface name.
-
-WPA is not currently supported by this driver, so you cannot connect to
-access points with WPA enabled.
-
-
-Module Parameters
------------------
-
-You can use "modinfo at76_usb" to see the complete list of the supported
-parameters with descriptions. Use module parameters on the "modprobe"
-command line. If the "at76_usb" module is loaded already, unload it
-first with "modprobe -r at76_usb".
-
-Once you know which parameters you need, use the "options" command in
-/etc/modprobe.conf to use them every time the module is loaded.
-
-For example, you can give the network device another name than wlanX by
-giving the module the "netdev_name" parameter:
-
- modprobe at76_usb netdev_name=eth%d
-
-If this parameter is used, the first device would be eth0 (unless it's
-already used by another driver, of course), the second eth1 and so on.
-
-
-Private Parameters
-------------------
-
-In addition to the wireless parameters set by "iwconfig", there are
-additional driver-specific parameters available via "iwpriv". Running
-"iwpriv wlanX" will list all of them.
-
-Following are some of the supported parameters:
-
-- long preamble: iwpriv wlanX short_preamble 0
-- short preamble: iwpriv wlanX short_preamble 1
-- amount of debug messages: iwpriv wlanX set_debug N
- with N a combination of bits, see DBG_* in at76c503.h
-- power save mode: iwpriv wlanX powersave_mode N (numbers 1, 2, 3 for
- for none, save and smart save respectively)
-- scan channel time: iwpriv wlanX scan_times <min_ch_time> <max_ch_time>
- (this may be required for 0.90.x firmware, i.e. Intersil radios)
-
-
-Power Save Modes in Managed Mode
---------------------------------
-
-You can activate 802.11 power save mode by executing
-
- iwconfig wlanX power on period N
-
-The default period value is 0 and the smallest possible period of power
-save (listen interval) is two beacon intervals. This should lower power
-consumption, but decrease data throughput and increase delays.
-
-There is an Atmel specific power save mode called "smart power save"
-which switches the device into active state (by a NULL packet to the AP)
-as soon as there are pending packets at the AP for the STA and put it
-back into doze state after the next beacon. This saves the need for
-sending PS_POLL packets.
-
-It can only be activated by
-
- iwpriv wlanX powersave_mode 3
+- Kernel 2.4.x. I am developing the driver on 2.4.20, but it
+ reportedly also works on 2.4.19, 2.4.18 and 2.4.16. I am not sure
+ about 2.5.x.
-I don't know if the listen_interval is used in this mode. If yes, you
-can only set it earlier by iwconfig, e.g.
+Installation:
+-------------
- iwconfig wlanX power on period N
- iwpriv wlanX powersave_mode 3
+make
+make install
+Running:
+--------
-Known Problems
---------------
+Plug in the adapter. If you already used it under Windows or with the
+driver from atmelwlandriver.sourceforge.net, replug the device
+(ie. plug out and in again).
-1) Bugs of the firmware 0.90.0-44 (the latest available for device with
- Intersil radio after Atmel stopped support for Intersil radio
- chipsets):
+If you have hotplug installed, the drivers should now be loaded. If not,
+load them by hand:
- - active scan doesn't send ProbeReq either in ad-hoc or in managed
- mode
+modprobe -v at76c503
+or
+insmod usbdfu.o; insmod at76c503
- * If your ad-hoc peer sends the beacon in longer intervals,
- the Atmel driver may not find it. Try to increase the max
- channel time to 500 or 1000 (default 120) by calling
+You can give the network device another name than eth by giving
+the module the eth_name parameter. Eg.
+insmod at76c50.o eth_name=wlan%d
+would give the first device the name wlan0, the second wlan1 etc...
- iwpriv wlanX scan_times 10 <max channel time>
+Check if the modules are loaded with lsmod. It should look like this:
- If you found a working value, use the module parameter
- scan_max_time.
+...
+at76c503 49972 0
+usbdfu 6164 0 [at76c503]
+...
- * You cannot connect to an access point which hides its ESSID and
- requires the STA to probe it!
+setup networking (replace <iface> with eth0, eth1, ..., <ch> with a
+channel number (1..14) <essid> with your network id (a string), <ip>
+with an IP address)
- - After joining an existing IBSS of a 2 Mbps card, the basic rates are
- wrong in the beacon, e.g. a 2 Mbps card broadcasts a basic rate set
- of 1 + 2 Mbps, but the Atmel device sends out basic rates of 1, 2,
- 5.5 and 11 Mbps. Subsequently it cannot connect to the 2 Mbps card,
- because it sends it's data packets to broadcast addresses with 11
- Mbps.
+iwconfig <iface> channel <ch> mode ad-hoc essid <essid>
+ifonfig <iface> <ip> up
- - power saving modes does not work
+Example:
+iwconfig eth2 mode ad-hoc channel 10 essid okuwlan
+ifconfig eth2 192.168.3.1 up
-2) firmware 1.101.0-84
+Test it by pinging another host with a wlan adaptor.
- - if a 2 Mbps card joins an IBSS (ad-hoc mode) initiated by the Atmel
- device (which currently broadcasts 1 + 2 Mbps as the basic rates and
- 5.5 and 11 Mbps as (additional) operational rates), the Atmel device
- sends out broadcast packets (e.g. ARP requests) with 11 Mbps. This
- may be fixed by changing the tx rate in iwconfig from "auto"
- (default) to 1M or 2M. I'm not sure if this is a firmware bug or a
- problem in the driver.
-
+To change a parameter with iwconfig, do:
+ifconfig <iface> down
+iwconfig ...
+ifconfig <iface> up
-Credits
--------
+Note that the firmware survives reboots of the computer, but not
+unplugging the device.
-Thanks to (in no particular order):
+If you get problems:
+Look with dmesg, if there are error messages
-- the authors (Stavros et.al.) of the usbvnet driver
- (atmelwlandriver.sourceforge.net)
+Thanks to:
+- the authors of the usbvnet driver (atmelwlandriver.sourceforge.net)
- Joerg Albert for lots of patches
-- Brad Hards and Bas Vermeulen for the firmware code, which I ported to
- kernel space
+- Brad Hards and Bas Vermeulen for the firmeware code, which I ported to kernel space
- David Gibson, I used his orinoco driver for learning
- the author(s) of the usbnet driver
- the author(s) of the rtl8150 driver
-- lots of other authors of USB and WLAN drivers, where I stole code from
-- Pavel Roskin for testing, debugging and his patches
-- Nick Jones for rewriting the iw_handler interface
+- lots of other authors of usb and wlan drivers, where I stole code from
-Oliver Kurth, Mon, 6 Jan 2003 22:39:47 +0100
-updated by Joerg Albert, Thu, 1 May 2003 and later
+Oliver Kurth <oku@masqmail.cx>, Mon, 6 Jan 2003 22:39:47 +0100
diff --git a/at76c503.c b/at76c503.c
index 2cf119a..5ca2244 100644
--- a/at76c503.c
+++ b/at76c503.c
@@ -1,120 +1,120 @@
/* -*- linux-c -*- */
/*
- * USB at76c503/at76c505 driver
+ * USB at76c503 driver
*
- * Copyright (c) 2002 - 2003 Oliver Kurth
- * Copyright (c) 2004 Joerg Albert <joerg.albert@gmx.de>
- * Copyright (c) 2004 Nick Jones
- * Copyright (c) 2004 Balint Seeber <n0_5p4m_p13453@hotmail.com>
+ * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * This file is part of the Berlios driver for WLAN USB devices based on the
- * Atmel AT76C503A/505/505A. See at76c503.h for details.
*
- * Some iw_handler code was taken from airo.c, (C) 1999 Benjamin Reed
+ * This driver is derived from usb-skeleton.c
+ *
+ * History:
+ *
+ * 2002_12_31:
+ * - first ping, ah-hoc mode works, fw version 0.90.2 only
+ *
+ * 2003_01_07 0.1:
+ * - first release
+ *
+ * 2003_01_08 0.2:
+ * - moved rx code into tasklet
+ * - added locking in keventd handler
+ * - support big endian in ieee802_11.h
+ * - external firmware downloader now in this module
+ *
+ * 2003_01_10 0.3:
+ * - now using 8 spaces for tab indentations
+ * - added tx rate settings (patch from Joerg Albert (jal))
+ * - created functions for mib settings
+ *
+ * 2003_01_19 0.4:
+ * - use usbdfu for the internal firmware
+ *
+ * 2003_01_27 0.5:
+ * - implemented WEP. Thanks to jal
+ * - added frag and rts ioctl calls (jal again)
+ * - module parameter to give names other than eth
+ *
+ * 2003_01_28 0.6:
+ * - make it compile with kernel < 2.4.20 (there is no owner field
+ * in struct usb_driver)
+ * - fixed a small bug for the module param eth_name
+ * - do not use GFP_DMA, GFP_KERNEL is enough
+ * - no down() in _tx() because that's in interrupt. Use
+ * spin_lock_irq() instead
+ * - should not stop net queue on urb errors
+ * - cleanup in ioctl(): locked it altogether, this makes it easier
+ * to maintain
+ * - tried to implement promisc. mode: does not work with this device
+ * - tried to implement setting mac address: does not
+ * seem to work with this device
+ * - now use fw version 0.90.2 #140 (prev. was #93). Does not help...
+ *
+ * 2003_01_30 0.7:
+ * - now works with fw 0.100.2 (solution was: wait for completion
+ * of commands)
+ * - setting MAC address now works (thx to a small fix by jal)
+ * - it turned out that promisc. mode is not possible. The firmware
+ * does not allow it. I hope that it will be implemented in a future
+ * version.
+ *
+ * 2003_02_13 0.8:
+ * - scan mode implemented by jal
+ * - infra structure mode by jal
+ * - some small cleanups (removed dead code)
+ *
+ * TODO:
+ * - monitor mode
+ * - should not need do drive device down, if changes are
+ * made with iwconfig
+ * - scan for BSS
+ * - infrastructure mode (if I can get an AP)
+ * - fw 0.100.x
+ * - optimize rx and tx (no memcpy)
+ *
*/
-#ifndef AUTOCONF_INCLUDED
#include <linux/config.h>
-#endif
-
-#include <linux/init.h>
#include <linux/kernel.h>
-#include <linux/version.h>
#include <linux/sched.h>
+#include <linux/signal.h>
#include <linux/errno.h>
#include <linux/poll.h>
+#include <linux/init.h>
#include <linux/slab.h>
+#include <linux/fcntl.h>
#include <linux/module.h>
#include <linux/spinlock.h>
#include <linux/list.h>
+#include <linux/smp_lock.h>
+#include <linux/devfs_fs_kernel.h>
#include <linux/usb.h>
#include <linux/netdevice.h>
#include <linux/if_arp.h>
#include <linux/etherdevice.h>
-#include <linux/ethtool.h>
#include <linux/wireless.h>
-#include <net/iw_handler.h>
-#include <linux/rtnetlink.h> /* for rtnl_lock() */
-#include <linux/firmware.h>
-
-#ifdef CONFIG_IPAQ_HANDHELD
-#include <asm/mach-types.h>
-#include <asm/arch/ipaq.h>
-#include <asm/arch-pxa/h5400-asic.h>
-#include <asm/arch-sa1100/h3600.h>
-#endif
#include "at76c503.h"
+#include "ieee802_11.h"
+#include "usbdfu.h"
-#if WIRELESS_EXT < 17
-#define IW_QUAL_QUAL_UPDATED 0x01
-#define IW_QUAL_LEVEL_UPDATED 0x02
-#define IW_QUAL_NOISE_UPDATED 0x04
-#define IW_QUAL_QUAL_INVALID 0x10
-#define IW_QUAL_LEVEL_INVALID 0x20
-#define IW_QUAL_NOISE_INVALID 0x40
-#endif
-
-#if WIRELESS_EXT < 19
-#define IW_QUAL_ALL_UPDATED 0x07
-#define IW_QUAL_DBM 0x08
-#define IW_QUAL_ALL_INVALID 0x70
-#endif
-
-/* timeout in seconds for the usb_control_msg in get_cmd_status
- * and set_card_command
- */
-#ifndef USB_CTRL_GET_TIMEOUT
-# define USB_CTRL_GET_TIMEOUT 5
-#endif
-
-/* number of endpoints of an interface */
-#define NUM_EP(intf) (intf)->altsetting[0].desc.bNumEndpoints
-#define EP(intf,nr) (intf)->altsetting[0].endpoint[(nr)].desc
-#define GET_DEV(udev) usb_get_dev((udev))
-#define PUT_DEV(udev) usb_put_dev((udev))
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 14)
-#define gfp_t int
-#endif
-
-/* Backwards compatibility for usb_kill_urb() */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 10)
-# define usb_kill_urb usb_unlink_urb
-#endif
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 9)
-# define eth_hdr(s) (s)->mac.ethernet
-# define set_eth_hdr(s,p) (s)->mac.ethernet=(p)
-#else
-# define set_eth_hdr(s,p) (s)->mac.raw=(unsigned char *)(p)
-#endif
+typedef unsigned char UCHAR;
+#include "internalr.h"
+#include "externalr.h"
-/* wireless extension level this source currently supports */
-#define WIRELESS_EXT_SUPPORTED 16
-
-#ifndef USB_ASYNC_UNLINK
-#ifdef URB_ASYNC_UNLINK
-#define USB_ASYNC_UNLINK URB_ASYNC_UNLINK
+#ifdef CONFIG_USB_DEBUG
+static int debug = 1;
#else
-#define USB_ASYNC_UNLINK 0
-#endif
+static int debug;
#endif
-#ifndef FILL_BULK_URB
-#define FILL_BULK_URB(a,b,c,d,e,f,g) usb_fill_bulk_urb(a,b,c,d,e,f,g)
-#endif
-
-int at76_debug = DBG_DEFAULTS;
-
-/* uncond. debug output */
-#define dbg_uc(format, arg...) \
- printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg)
+/* Use our own dbg macro */
+#undef dbg
+#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)
#ifndef min
#define min(x,y) ((x) < (y) ? (x) : (y))
@@ -123,7 +123,7 @@ int at76_debug = DBG_DEFAULTS;
#define assert(x) \
do {\
if (!(x)) \
- err("%d: assertion " #x " failed", __LINE__);\
+ err(__FILE__ ":%d assertion " #x " failed", __LINE__);\
} while (0)
/* how often do we re-try these packets ? */
@@ -131,556 +131,356 @@ int at76_debug = DBG_DEFAULTS;
#define ASSOC_RETRIES 3
#define DISASSOC_RETRIES 3
-
-
-static unsigned long spin_l_istate_flags;
-#define LOCK_ISTATE() spin_lock_irqsave(&dev->istate_spinlock,spin_l_istate_flags);
-#define UNLOCK_ISTATE() spin_unlock_irqrestore(&dev->istate_spinlock,spin_l_istate_flags);
-
-
#define NEW_STATE(dev,newstate) \
do {\
- scan_hook(newstate == SCANNING); \
- LOCK_ISTATE() \
- dbg(DBG_PROGRESS, "%s: state %d -> %d (" #newstate ")",\
+ dbg("%s: state %d -> %d (" #newstate ")",\
dev->netdev->name, dev->istate, newstate);\
dev->istate = newstate;\
- UNLOCK_ISTATE() \
} while (0)
/* the beacon timeout in infra mode when we are connected (in seconds) */
#define BEACON_TIMEOUT 10
-/* the interval in ticks we poll if scan is completed */
-#define SCAN_POLL_INTERVAL (HZ/4)
-
+/* after how many seconds do we re-scan the channels in infra mode */
+#define RESCAN_TIME 10
/* Version Information */
-#define DRIVER_NAME "at76_usb"
-#define DRIVER_AUTHOR \
-"Oliver Kurth <oku@masqmail.cx>, Joerg Albert <joerg.albert@gmx.de>, " \
-"Alex <alex@foogod.com>, Nick Jones, Balint Seeber <n0_5p4m_p13453@hotmail.com>"
-#define DRIVER_DESC "Atmel at76c50x USB Wireless LAN Driver"
-
+#define DRIVER_AUTHOR "Oliver Kurth <oku@masqmail.cx>, Joerg Albert <joerg.albert@gmx.de>"
+#define DRIVER_DESC "Atmel at76c503 Wireless LAN Driver"
/* Module paramaters */
-module_param_named(debug, at76_debug, int, 0600);
-MODULE_PARM_DESC(debug, "Debugging level");
-
-static int rx_copybreak = 200;
-module_param(rx_copybreak, int, 0400);
-MODULE_PARM_DESC(rx_copybreak, "rx packet copy threshold");
-
-static int scan_min_time = 10;
-module_param(scan_min_time, int, 0400);
-MODULE_PARM_DESC(scan_min_time, "scan min channel time (default: 10)");
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
-static int scan_max_time = 120;
-module_param(scan_max_time, int, 0400);
-MODULE_PARM_DESC(scan_max_time, "scan max channel time (default: 120)");
+static char eth_name[IFNAMSIZ+1] = "eth%d";
+MODULE_PARM(eth_name, "c" __MODULE_STRING(IFNAMSIZ));
+MODULE_PARM_DESC(eth_name,
+ "the device name (default is eth%d)");
-static int scan_mode = SCAN_TYPE_ACTIVE;
-module_param(scan_mode, int, 0400);
-MODULE_PARM_DESC(scan_mode, "scan mode: 0 active (with ProbeReq, default), 1 passive");
+/* except for belkin and netgear, none of these are tested: */
-static int preamble_type = PREAMBLE_TYPE_LONG;
-module_param(preamble_type, int, 0400);
-MODULE_PARM_DESC(preamble_type, "preamble type: 0 long (default), 1 short");
+#define VENDOR_ID_ATMEL 0x03eb
+#define PRODUCT_ID_ATMEL_503 0x7605
+#define PRODUCT_ID_ATMEL_505 0x7606 /* not yet supported, but there will be a time.. */
-static int auth_mode = 0;
-module_param(auth_mode, int, 0400);
-MODULE_PARM_DESC(auth_mode, "authentication mode: 0 open system (default), "
- "1 shared secret");
+#define VENDOR_ID_BELKIN 0x0d5c
+#define PRODUCT_ID_BELKIN 0xa002 /* Belkin F5D6050 */
-static int pm_mode = PM_ACTIVE;
-module_param(pm_mode, int, 0400);
-MODULE_PARM_DESC(pm_mode, "power management mode: 1 active (def.), 2 powersave, 3 smart save");
+#define VENDOR_ID_DYNALINK 0x069a
+#define PRODUCT_ID_DYNALINK 0x0321 /* Dynalink/Askey WLL013 */
-static int pm_period = 0;
-module_param(pm_period, int, 0400);
-MODULE_PARM_DESC(pm_period, "period of waking up the device in usec");
+#define VENDOR_ID_LINKSYS 0x077b
+#define PRODUCT_ID_LINKSYS 0x2219 /* Linksys WUSB11 v2.6 */
-static int international_roaming = IR_OFF;
-module_param(international_roaming, int, 0400);
-MODULE_PARM_DESC(international_roaming, "enable international roaming: 0 (no, default), 1 (yes)");
+#define VENDOR_ID_NETGEAR 0x0864
+#define PRODUCT_ID_NETGEAR_MA101B 0x4102 /* Netgear MA 101 Rev. B */
-static int default_iw_mode = IW_MODE_INFRA;
-module_param(default_iw_mode, int, 0400);
-MODULE_PARM_DESC(default_iw_mode, "default IW mode for a new device: "
- "1 (ad-hoc), 2 (infrastructure, def.), 6 (monitor mode)");
-
-static int monitor_scan_min_time = 50;
-module_param(monitor_scan_min_time, int, 0400);
-MODULE_PARM_DESC(monitor_scan_min_time, "scan min channel time in MONITOR MODE (default: 50)");
-
-static int monitor_scan_max_time = 600;
-module_param(monitor_scan_max_time, int, 0400);
-MODULE_PARM_DESC(monitor_scan_max_time, "scan max channel time in MONITOR MODE (default: 600)");
-
-static char* netdev_name = "wlan%d";
-module_param(netdev_name, charp, 0400);
-MODULE_PARM_DESC(netdev_name, "network device name (default is wlan%d)");
+static struct usb_device_id at76c503_table [] = {
+ { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503) },
+ { USB_DEVICE(VENDOR_ID_BELKIN, PRODUCT_ID_BELKIN) },
+ { USB_DEVICE(VENDOR_ID_DYNALINK, PRODUCT_ID_DYNALINK) },
+ { USB_DEVICE(VENDOR_ID_LINKSYS, PRODUCT_ID_LINKSYS) },
+ { USB_DEVICE(VENDOR_ID_NETGEAR, PRODUCT_ID_NETGEAR_MA101B) },
+ { }
+};
+MODULE_DEVICE_TABLE (usb, at76c503_table);
+
+struct header_struct {
+ /* 802.3 */
+ u8 dest[ETH_ALEN];
+ u8 src[ETH_ALEN];
+ u16 len;
+ /* 802.2 */
+ u8 dsap;
+ u8 ssap;
+ u8 ctrl;
+ /* SNAP */
+ u8 oui[3];
+ u16 ethertype;
+} __attribute__ ((packed));
#define DEF_RTS_THRESHOLD 1536
#define DEF_FRAG_THRESHOLD 1536
-#define DEF_SHORT_RETRY_LIMIT 8
+#define DEF_ESSID "okuwlan"
+#define DEF_ESSID_LEN 7
#define DEF_CHANNEL 10
-#define MAX_RTS_THRESHOLD (MAX_FRAG_THRESHOLD + 1)
+#define MAX_RTS_THRESHOLD 2347
+#define MAX_FRAG_THRESHOLD 2346
+#define MIN_FRAG_THRESHOLD 256
/* The frequency of each channel in MHz */
-static const long channel_frequency[] = {
+const long channel_frequency[] = {
2412, 2417, 2422, 2427, 2432, 2437, 2442,
2447, 2452, 2457, 2462, 2467, 2472, 2484
};
#define NUM_CHANNELS ( sizeof(channel_frequency) / sizeof(channel_frequency[0]) )
/* the broadcast address */
-static const u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-static const u8 off_addr[ETH_ALEN] = {0x00, 0x00, 0x00, 0x00, 0x00, 0x00};
+const u8 bc_addr[ETH_ALEN] = {0xff,0xff,0xff,0xff,0xff,0xff};
-/* the supported rates of this hardware, bit7 marks a basic rate */
-static const u8 hw_rates[4] = {0x82,0x84,0x0b,0x16};
+/* the basic rates of this hardware */
+const u8 hw_rates[4] = {0x82,0x84,0x8b,0x96};
-/* the max padding size for tx in bytes (see calc_padding)*/
+/* the max padding size for tx in bytes */
#define MAX_PADDING_SIZE 53
-/* the size of the ieee802.11 header (excl. the at76c503 tx header) */
-#define IEEE802_11_MGMT_HEADER_SIZE offsetof(struct ieee80211_hdr_3addr, payload)
+struct ieee802_11_mgmt {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[ETH_ALEN]; /* destination addr */
+ u8 addr2[ETH_ALEN]; /* source addr */
+ u8 addr3[ETH_ALEN]; /* BSSID */
+ u16 seq_ctl;
+ u8 data[1508];
+ u32 fcs;
+} __attribute__ ((packed));
+
+/* the size of the ieee802.11 header (incl. the at76c503 tx header) */
+#define IEEE802_11_MGMT_HEADER_SIZE \
+ (offsetof(struct at76c503_tx_buffer, packet) +\
+ offsetof(struct ieee802_11_mgmt, data))
-#define BEACON_MAX_DATA_LENGTH 1500
-/* beacon in ieee80211_hdr_3addr.payload */
+/* beacon in ieee802_11_mgmt.data */
struct ieee802_11_beacon_data {
- u8 timestamp[8]; /* TSFTIMER */
- __le16 beacon_interval; /* Kms between TBTTs (Target Beacon Transmission Times) */
- __le16 capability_information;
- u8 data[BEACON_MAX_DATA_LENGTH]; /* contains: SSID (tag,length,value),
- Supported Rates (tlv), channel */
+ u8 timestamp[8]; // TSFTIMER
+ u16 beacon_interval; // Kms between TBTTs (Target Beacon Transmission Times)
+ u16 capability_information;
+ u8 data[1500]; /* contains: SSID (tag,length,value),
+ Supported Rates (tlv), channel */
} __attribute__ ((packed));
-/* disassoc frame in ieee80211_hdr_3addr.payload */
+/* disassoc frame in ieee802_11_mgmt.data */
struct ieee802_11_disassoc_frame {
- __le16 reason;
+ u16 reason;
} __attribute__ ((packed));
#define DISASSOC_FRAME_SIZE \
- (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\
+ (IEEE802_11_MGMT_HEADER_SIZE +\
sizeof(struct ieee802_11_disassoc_frame))
-/* assoc request in ieee80211_hdr_3addr.payload */
+/* assoc request in ieee802_11_mgmt.data */
struct ieee802_11_assoc_req {
- __le16 capability;
- __le16 listen_interval;
- u8 data[1]; /* variable number of bytes for SSID
+ u16 capability;
+ u16 listen_interval;
+ u8 data[1]; /* variable number of bytes for SSID
and supported rates (tlv coded) */
};
/* the maximum size of an AssocReq packet */
#define ASSOCREQ_MAX_SIZE \
- (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\
+ (IEEE802_11_MGMT_HEADER_SIZE +\
offsetof(struct ieee802_11_assoc_req,data) +\
1+1+IW_ESSID_MAX_SIZE + 1+1+4)
-/* reassoc request in ieee80211_hdr_3addr.payload */
+/* reassoc request in ieee802_11_mgmt.data */
struct ieee802_11_reassoc_req {
- __le16 capability;
- __le16 listen_interval;
- u8 curr_ap[ETH_ALEN]; /* the bssid of the AP we are
+ u16 capability;
+ u16 listen_interval;
+ u8 curr_ap[ETH_ALEN]; /* the bssid of the AP we are
currently associated to */
- u8 data[1]; /* variable number of bytes for SSID
+ u8 data[1]; /* variable number of bytes for SSID
and supported rates (tlv coded) */
} __attribute__ ((packed));
/* the maximum size of an AssocReq packet */
#define REASSOCREQ_MAX_SIZE \
- (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\
+ (IEEE802_11_MGMT_HEADER_SIZE +\
offsetof(struct ieee802_11_reassoc_req,data) +\
1+1+IW_ESSID_MAX_SIZE + 1+1+4)
/* assoc/reassoc response */
struct ieee802_11_assoc_resp {
- __le16 capability;
- __le16 status;
- __le16 assoc_id;
- u8 data[1]; /* variable number of bytes for
+ u16 capability;
+ u16 status;
+ u16 assoc_id;
+ u8 data[1]; /* variable number of bytes for
supported rates (tlv coded) */
} __attribute__ ((packed));
-/* auth. request/response in ieee80211_hdr_3addr.payload */
+/* auth. request/response in ieee802_11_mgmt.data */
struct ieee802_11_auth_frame {
- __le16 algorithm;
- __le16 seq_nr;
- __le16 status;
- u8 challenge[0];
+ u16 algorithm;
+ u16 seq_nr;
+ u16 status;
+ /* no challenge text (yet) */
} __attribute__ ((packed));
-/* for shared secret auth, add the challenge text size */
-#define AUTH_FRAME_SIZE \
- (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\
- sizeof(struct ieee802_11_auth_frame))
-/* deauth frame in ieee80211_hdr_3addr.payload */
+/* deauth frame in ieee802_11_mgmt.data */
struct ieee802_11_deauth_frame {
- __le16 reason;
+ u16 reason;
} __attribute__ ((packed));
#define DEAUTH_FRAME_SIZE \
- (AT76C503_TX_HDRLEN + IEEE802_11_MGMT_HEADER_SIZE +\
+ (IEEE802_11_MGMT_HEADER_SIZE +\
sizeof(struct ieee802_11_disauth_frame))
+/* for shared key, add the challenge text size */
+#define AUTH_FRAME_SIZE \
+ (IEEE802_11_MGMT_HEADER_SIZE +\
+ sizeof(struct ieee802_11_auth_frame))
+
#define KEVENT_CTRL_HALT 1
#define KEVENT_NEW_BSS 2
#define KEVENT_SET_PROMISC 3
#define KEVENT_MGMT_TIMEOUT 4
-#define KEVENT_SCAN 5
-#define KEVENT_JOIN 6
-#define KEVENT_STARTIBSS 7
-#define KEVENT_SUBMIT_RX 8
-#define KEVENT_RESTART 9 /* restart the device */
-#define KEVENT_ASSOC_DONE 10 /* execute the power save settings:
- listen interval, pm mode, assoc id */
-#define KEVENT_EXTERNAL_FW 11
-#define KEVENT_INTERNAL_FW 12
-#define KEVENT_RESET_DEVICE 13
-
-
-static u8 snapsig[] = {0xaa, 0xaa, 0x03};
-/* RFC 1042 encapsulates Ethernet frames in 802.2 SNAP (0xaa, 0xaa, 0x03) with
- * a SNAP OID of 0 (0x00, 0x00, 0x00) */
-static u8 rfc1042sig[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00};
-
-/* local function prototypes */
-static void iwspy_update(struct at76c503 *dev, struct at76c503_rx_buffer *buf);
-
-static void at76c503_read_bulk_callback (struct urb *urb);
-static void at76c503_write_bulk_callback(struct urb *urb);
-static void defer_kevent (struct at76c503 *dev, int flag);
-static struct bss_info *find_matching_bss(struct at76c503 *dev,
- struct bss_info *curr);
-static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr,
- u8 *challenge);
-static int disassoc_req(struct at76c503 *dev, struct bss_info *bss);
-static int assoc_req(struct at76c503 *dev, struct bss_info *bss);
-static int reassoc_req(struct at76c503 *dev, struct bss_info *curr,
- struct bss_info *new);
-static void dump_bss_table(struct at76c503 *dev, int force_output);
-static int submit_rx_urb(struct at76c503 *dev);
-static int startup_device(struct at76c503 *dev);
-
-static int set_iroaming(struct at76c503 *dev, int onoff);
-static void set_monitor_mode(struct at76c503 *dev, int use_prism);
-
-/* second step of initialization (after fw download) */
-static int init_new_device(struct at76c503 *dev);
-
-/* DFU states */
-#define STATE_IDLE 0x00
-#define STATE_DETACH 0x01
-#define STATE_DFU_IDLE 0x02
-#define STATE_DFU_DOWNLOAD_SYNC 0x03
-#define STATE_DFU_DOWNLOAD_BUSY 0x04
-#define STATE_DFU_DOWNLOAD_IDLE 0x05
-#define STATE_DFU_MANIFEST_SYNC 0x06
-#define STATE_DFU_MANIFEST 0x07
-#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
-#define STATE_DFU_UPLOAD_IDLE 0x09
-#define STATE_DFU_ERROR 0x0a
-
-/* DFU commands */
-#define DFU_DETACH 0
-#define DFU_DNLOAD 1
-#define DFU_UPLOAD 2
-#define DFU_GETSTATUS 3
-#define DFU_CLRSTATUS 4
-#define DFU_GETSTATE 5
-#define DFU_ABORT 6
-
-#define DFU_PACKETSIZE 1024
-
-#define USB_SUCCESS(a) ((a) >= 0)
-
-struct dfu_status {
- unsigned char bStatus;
- unsigned char bwPollTimeout[3];
- unsigned char bState;
- unsigned char iString;
-} __attribute__ ((packed));
-
-/* driver independent download context */
-struct dfu_ctx {
- struct usb_device *udev;
- u8 dfu_state;
- struct dfu_status dfu_status;
- u8 *buf;
+#define KEVENT_SCANJOIN 5 /* SCAN and JOIN are used in infrastructure mode only */
+
+/* struct to store BSS info found during scan */
+#define MAX_RATE_LEN 32 /* 32 rates should be enough ... */
+
+struct bss_info{
+ u8 mac[ETH_ALEN]; /* real mac address, differs
+ for ad-hoc from bssid */
+ u8 bssid[ETH_ALEN]; /* bssid */
+ u8 ssid[IW_ESSID_MAX_SIZE+1]; /* ssid, +1 for trailing \0
+ to make it printable */
+ u8 ssid_len; /* length of ssid above */
+ u8 channel;
+ u16 capa; /* the capabilities of the BSS (in original endianess -
+ we only check IEEE802_11 bits in it) */
+ u16 beacon_interval; /* the beacon interval (in cpu endianess -
+ we must calc. values from it */
+ u8 rates[MAX_RATE_LEN]; /* supported rates (list of bytes:
+ (basic_rate ? 0x80 : 0) + rate/(500 Kbit/s); e.g.
+ x82,x84,x8b,x96 for basic rates 1,2,5.5,11 MBit/s) */
+ u8 rates_len;
+
+ /* quality of received beacon */
+ u8 rssi;
+ u8 link_qual;
+ u8 noise_level;
};
+#define NR_BSS_INFO 16 /* how many BSS do we record */
+
+/* states in infrastructure mode */
+enum infra_state {
+ INIT,
+ SCANNING,
+ AUTHENTICATING,
+ ASSOCIATING,
+ REASSOCIATING,
+ DISASSOCIATING,
+ JOINING,
+ CONNECTED
+};
-static
-int dfu_download_block(struct dfu_ctx *ctx, u8 *buffer,
- int bytes, int block)
-{
- int result;
- u8 *tmpbuf = ctx->buf;
- struct usb_device *udev = ctx->udev;
-
- dbg(DBG_DFU, "dfu_download_block(): buffer=%p, bytes=%d, block=%d", buffer, bytes, block);
-
- if(tmpbuf == NULL)
- return -ENOMEM;
-
- memcpy(tmpbuf, buffer, bytes);
-
- result = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
- DFU_DNLOAD,
- USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE,
- block, /* Value */
- 0, /* Index */
- tmpbuf, /* Buffer */
- bytes, /* Size */
- HZ);
- return result;
-}
-
-static
-int dfu_get_status(struct dfu_ctx *ctx, struct dfu_status *status)
-{
- int result;
- struct usb_device *udev = ctx->udev;
-
- result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- DFU_GETSTATUS,
- USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
- 0, /* Value */
- 0, /* Index */
- status, /* Buffer */
- sizeof(struct dfu_status), /* Size */
- HZ);
-
- return result;
-}
-
-static
-u8 dfu_get_state(struct usb_device *udev, u8 *state)
-{
- int result;
-
- result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
- DFU_GETSTATE, /* Request */
- USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
- 0, /* Value */
- 0, /* Index */
- state, /* Buffer */
- 1, /* Size */
- HZ);
-
- return result;
-}
-
-static inline
-u32 __get_timeout(struct dfu_status *s)
-{
- unsigned long ret = 0;
-
- ret = (unsigned long) (s->bwPollTimeout[2] << 16);
- ret |= (unsigned long) (s->bwPollTimeout[1] << 8);
- ret |= (unsigned long) (s->bwPollTimeout[0]);
-
- return ret;
-}
-
-static
-struct dfu_ctx *dfu_alloc_ctx(struct usb_device *udev)
-{
- struct dfu_ctx *ctx;
-
- ctx = kmalloc(sizeof(struct dfu_ctx) + DFU_PACKETSIZE, GFP_KERNEL|GFP_DMA);
- if(ctx){
- ctx->udev = udev;
- ctx->buf = (u8 *)&(ctx[1]);
- }
- return ctx;
-}
-
-/* == PROC usbdfu_download ==
- if manifest_sync_timeout > 0 use this timeout (in msec) instead of the
- one reported by the device in state MANIFEST_SYNC */
-static int usbdfu_download(struct usb_device *udev, u8 *dfu_buffer,
- u32 dfu_len, int manifest_sync_timeout)
-{
- struct dfu_ctx *ctx;
- struct dfu_status *dfu_stat_buf;
- int status = 0;
- int need_dfu_state = 1;
- int is_done = 0;
- u8 dfu_state = 0;
- u32 dfu_timeout = 0;
- int dfu_block_bytes = 0, dfu_bytes_left = dfu_len, dfu_buffer_offset = 0;
- int dfu_block_cnt = 0;
-
- dbg(DBG_DFU, "%s( %p, %u, %d)", __FUNCTION__, dfu_buffer,
- dfu_len, manifest_sync_timeout);
-
- if (dfu_len == 0) {
- err("FW Buffer length invalid!");
- return -EINVAL;
- }
-
- ctx = dfu_alloc_ctx(udev);
- if(ctx == NULL)
- return -ENOMEM;
-
- dfu_stat_buf = &ctx->dfu_status;
-
- do {
- if (need_dfu_state) {
- status = dfu_get_state(ctx->udev, &ctx->dfu_state);
- if (!USB_SUCCESS(status)) {
- err("DFU: Failed to get DFU state: %d", status);
- goto exit;
- }
- dfu_state = ctx->dfu_state;
- need_dfu_state = 0;
- }
-
- switch (dfu_state) {
- case STATE_DFU_DOWNLOAD_SYNC:
- dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_SYNC");
- status = dfu_get_status(ctx, dfu_stat_buf);
- if (USB_SUCCESS(status)) {
- dfu_state = dfu_stat_buf->bState;
- dfu_timeout = __get_timeout(dfu_stat_buf);
- need_dfu_state = 0;
- } else
- err("dfu_get_status failed with %d", status);
- break;
-
- case STATE_DFU_DOWNLOAD_BUSY:
- dbg(DBG_DFU, "STATE_DFU_DOWNLOAD_BUSY");
- need_dfu_state = 1;
-
- if (dfu_timeout >= 0){
- dbg(DBG_DFU, "DFU: Resetting device");
- set_current_state( TASK_INTERRUPTIBLE );
- schedule_timeout(1+dfu_timeout*HZ/1000);
- }else
- dbg(DBG_DFU, "DFU: In progress");
-
- break;
-
- case STATE_DFU_DOWNLOAD_IDLE:
- dbg(DBG_DFU, "DOWNLOAD...");
- /* fall through */
- case STATE_DFU_IDLE:
- dbg(DBG_DFU, "DFU IDLE");
-
- if (dfu_bytes_left <= DFU_PACKETSIZE)
- dfu_block_bytes = dfu_bytes_left;
- else
- dfu_block_bytes = DFU_PACKETSIZE;
-
- dfu_bytes_left -= dfu_block_bytes;
- status = dfu_download_block(ctx,
- dfu_buffer +
- dfu_buffer_offset,
- dfu_block_bytes,
- dfu_block_cnt);
- dfu_buffer_offset += dfu_block_bytes;
- dfu_block_cnt++;
-
- if (!USB_SUCCESS(status))
- err("dfu_download_block failed with %d", status);
- need_dfu_state = 1;
- break;
-
- case STATE_DFU_MANIFEST_SYNC:
- dbg(DBG_DFU, "STATE_DFU_MANIFEST_SYNC");
-
- status = dfu_get_status(ctx, dfu_stat_buf);
+struct at76c503 {
+ struct usb_device *udev; /* save off the usb device pointer */
+ struct net_device *netdev; /* save off the net device pointer */
+ struct net_device_stats stats;
+ struct iw_statistics wstats;
+ struct usb_interface *interface; /* the interface for this device */
+
+ unsigned char num_ports; /* the number of ports this device has */
+ char num_interrupt_in; /* number of interrupt in endpoints we have */
+ char num_bulk_in; /* number of bulk in endpoints we have */
+ char num_bulk_out; /* number of bulk out endpoints we have */
+
+ unsigned char * bulk_in_buffer; /* the buffer to receive data */
+ int bulk_in_size; /* the size of the receive buffer */
+ __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
+
+ unsigned char * bulk_out_buffer; /* the buffer to send data */
+ int bulk_out_size; /* the size of the send buffer */
+ struct urb * write_urb; /* the urb used to send data */
+ struct urb * read_urb;
+ __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
- if (USB_SUCCESS(status)) {
- dfu_state = dfu_stat_buf->bState;
- dfu_timeout = __get_timeout(dfu_stat_buf);
- need_dfu_state = 0;
+ struct tq_struct tqueue; /* task queue for line discipline waking up */
+ int open_count; /* number of times this port has been opened */
+ struct semaphore sem; /* locks this structure */
- /* override the timeout from the status response,
- needed for AT76C505A */
- if (manifest_sync_timeout > 0)
- dfu_timeout = manifest_sync_timeout;
- if (dfu_timeout >= 0){
- dbg(DBG_DFU, "DFU: Waiting for manifest phase");
+ u32 kevent_flags;
+ struct tq_struct kevent;
- set_current_state( TASK_INTERRUPTIBLE );
- schedule_timeout((dfu_timeout*HZ+999)/1000);
- }else
- dbg(DBG_DFU, "DFU: In progress");
- }
- break;
+ struct tasklet_struct tasklet;
+ struct urb *rx_urb; /* tmp urb pointer for rx_tasklet */
- case STATE_DFU_MANIFEST:
- dbg(DBG_DFU, "STATE_DFU_MANIFEST");
- is_done = 1;
- break;
+ unsigned char *ctrl_buffer;
+ struct urb *ctrl_urb;
- case STATE_DFU_MANIFEST_WAIT_RESET:
- dbg(DBG_DFU, "STATE_DFU_MANIFEST_WAIT_RESET");
- is_done = 1;
- break;
-
- case STATE_DFU_UPLOAD_IDLE:
- dbg(DBG_DFU, "STATE_DFU_UPLOAD_IDLE");
- break;
-
- case STATE_DFU_ERROR:
- dbg(DBG_DFU, "STATE_DFU_ERROR");
- status = -EPIPE;
- break;
-
- default:
- dbg(DBG_DFU, "DFU UNKNOWN STATE (%d)", dfu_state);
- status = -EINVAL;
- break;
- }
- } while (!is_done && USB_SUCCESS(status));
+ u8 op_mode;
- exit:
- kfree(ctx);
- if (status < 0)
- return status;
- else
- return 0;
-}
+ /* the WEP stuff */
+ int wep_excl_unencr; /* 1 if unencrypted packets shall be discarded */
+ int wep_enabled; /* 1 if WEP is enabled */
+ int wep_key_id; /* key id to be used */
+ u8 wep_keys[NR_WEP_KEYS][WEP_KEY_SIZE]; /* the four WEP keys,
+ 5 or 13 bytes are used */
+ u8 wep_keys_len[NR_WEP_KEYS]; /* the length of the above keys */
+
+ int channel;
+ int iw_mode;
+ int curr_ap;
+ u8 bssid[ETH_ALEN];
+ u8 essid[IW_ESSID_MAX_SIZE];
+ int essid_size;
+ int radio_on;
+ int promisc;
-/* some abbrev. for wireless events */
-static inline void iwevent_scan_complete(struct net_device *dev)
-{
- union iwreq_data wrqu;
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- wireless_send_event(dev, SIOCGIWSCAN, &wrqu, NULL);
- dbg(DBG_WE_EVENTS, "%s: SIOCGIWSCAN sent", dev->name);
-}
-static inline void iwevent_bss_connect(struct net_device *dev, u8 *bssid)
-{
- union iwreq_data wrqu;
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- memcpy(wrqu.ap_addr.sa_data, bssid, ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
- dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", dev->name, __FUNCTION__);
-}
+ int preamble_type; /* 0 - long preamble, 1 - short preamble */
+ int txrate; /* 0,1,2,3 = 1,2,5.5,11 MBit, 4 is auto-fallback */
+ int frag_threshold; /* threshold for fragmentation of tx packets */
+ int rts_threshold; /* threshold for RTS mechanism */
+
+ struct bss_info bss[NR_BSS_INFO]; /* the list we got from scanning */
+ int bss_nr; /* how many valid entries in bss[] (from 0)? */
+
+ /* some data for infrastructure mode only */
+ spinlock_t mgmt_spinlock; /* this spinlock protects access to
+ next_mgmt_bulk and istate */
+ struct at76c503_tx_buffer *next_mgmt_bulk; /* pending management msg to
+ send via bulk out */
+ enum infra_state istate;
+ int curr_bss; /* if istate == AUTH, ASSOC, REASSOC, JOIN or CONN
+ dev->bss[curr_bss] is the currently selected BSS
+ we operate on */
+ int new_bss; /* if istate == REASSOC dev->bss[new_bss] is the new bss
+ we want to reassoc to */
+ struct timer_list mgmt_timer; /* the timer we use to repeat auth_req etc. */
+ int retries; /* counts backwards while re-trying to send auth/assoc_req's */
+ u16 assoc_id; /* the assoc_id for states JOINING, REASSOCIATING, CONNECTED */
+
+ /* provide hooks for non-rfmd */
+ union{
+ struct hwcfg_rfmd rfmd;
+ struct hwcfg_r505 r505;
+ struct hwcfg_other other;
+ }hwcfg;
+
+ struct at76c503_card_config card_config;
+ struct mib_fw_version fw_version;
+};
-static inline void iwevent_bss_disconnect(struct net_device *dev)
-{
- union iwreq_data wrqu;
- wrqu.data.length = 0;
- wrqu.data.flags = 0;
- memset(wrqu.ap_addr.sa_data, '\0', ETH_ALEN);
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- wireless_send_event(dev, SIOCGIWAP, &wrqu, NULL);
- dbg(DBG_WE_EVENTS, "%s: %s: SIOCGIWAP sent", dev->name, __FUNCTION__);
-}
+static DECLARE_WAIT_QUEUE_HEAD(wait_queue);
+/* local function prototypes */
+
+static void * at76c503_probe(struct usb_device *dev, unsigned int ifnum,
+ const struct usb_device_id *id);
+static void at76c503_disconnect(struct usb_device *dev, void *ptr);
+static void at76c503_write_bulk_callback(struct urb *urb);
+static void defer_kevent (struct at76c503 *dev, int flag);
+static int find_matching_bss(struct at76c503 *dev, int start);
+static int auth_req(struct at76c503 *dev, int idx);
+static int disassoc_req(struct at76c503 *dev, int idx);
+static int assoc_req(struct at76c503 *dev, int idx);
+static int reassoc_req(struct at76c503 *dev, int curr, int new);
+static void dump_bss_table(struct at76c503 *dev);
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver at76c503_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
+ owner: THIS_MODULE,
+#endif
+ name: "at76c503",
+ probe: at76c503_probe,
+ disconnect: at76c503_disconnect,
+ id_table: at76c503_table,
+};
/* hexdump len many bytes from buf into obuf, separated by delim,
add a trailing \0 into obuf */
@@ -697,44 +497,12 @@ static char *hex2str(char *obuf, u8 *buf, int len, char delim)
buf++;
}
if (delim != '\0' && obuf > ret)
- obuf--; /* remove last inserted delimiter */
+ obuf--; // remove last inserted delimiter
*obuf = '\0';
return ret;
}
-/* == PROC is_cloaked_ssid ==
- returns != 0, if the given SSID is a cloaked one:
- - length 0
- - length > 0, all bytes are \0
- - length == 1, SSID ' '
-*/
-static inline int is_cloaked_ssid(u8 *ssid, int length)
-{
- static const u8 zeros[32];
-
- return (length == 0) ||
- (length == 1 && *ssid == ' ') ||
- (length > 0 && !memcmp(ssid,zeros,length));
-}
-
-static inline void free_bss_list(struct at76c503 *dev)
-{
- struct list_head *next, *ptr;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
-
- dev->curr_bss = dev->new_bss = NULL;
-
- list_for_each_safe(ptr, next, &dev->bss_list) {
- list_del(ptr);
- kfree(list_entry(ptr, struct bss_info, list));
- }
-
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
-}
-
static inline char *mac2str(u8 *mac)
{
static char str [6*3];
@@ -744,396 +512,106 @@ static inline char *mac2str(u8 *mac)
return str;
}
-static void scan_hook(int blink)
-{
-#ifdef CONFIG_IPAQ_HANDHELD
- if (machine_is_h5400()) {
- if (blink)
- ipaq_led_blink (RED_LED, 1, 2);
- else
- ipaq_led_off (RED_LED);
- }
-#endif
-}
-
-
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
-
-/* == PROC analyze_usb_config ==
- This procedure analyzes the configuration after the
- USB device got reset and find the start of the interface and the
- two endpoint descriptors.
- Returns < 0 if the descriptors seems to be wrong. */
-static int analyze_usb_config(u8 *cfgd, int cfgd_len,
- int *intf_idx, int *ep0_idx, int *ep1_idx)
+static inline void usb_debug_data (const char *function, const unsigned char *data, int size)
{
- u8 *cfgd_start = cfgd;
- u8 *cfgd_end = cfgd + cfgd_len; /* first byte after config descriptor */
- int nr_intf=0, nr_ep=0; /* number of interface, number of endpoint descr.
- found */
-
- assert(cfgd_len >= 2);
- if (cfgd_len < 2)
- return -1;
-
- if (*(cfgd+1) != USB_DT_CONFIG) {
- err("not a config descriptor");
- return -2;
- }
-
- if (*cfgd != USB_DT_CONFIG_SIZE) {
- err("invalid length for config descriptor: %d", *cfgd);
- return -3;
- }
-
- /* scan the config descr */
- while ((cfgd+1) < cfgd_end) {
-
- switch (*(cfgd+1)) {
-
- case USB_DT_INTERFACE:
- nr_intf++;
- if (nr_intf == 1)
- *intf_idx = cfgd - cfgd_start;
- break;
-
- case USB_DT_ENDPOINT:
- nr_ep++;
- if (nr_ep == 1)
- *ep0_idx = cfgd - cfgd_start;
- else
- if (nr_ep == 2)
- *ep1_idx = cfgd - cfgd_start;
- break;
- default:
- ;
- }
- cfgd += *cfgd;
- } /* while ((cfgd+1) < cfgd_end) */
-
- if (nr_ep != 2 || nr_intf != 1) {
- err("unexpected nr of intf (%d) or endpoints (%d)",
- nr_intf, nr_ep);
- return -4;
- }
-
- return 0;
-} /* end of analyze_usb_config */
-
-
-
-/* == PROC update_usb_intf_descr ==
- currently (2.6.0-test2) usb_reset_device() does not recognize that
- the interface descr. are changed.
- This procedure reads the configuration and does a limited parsing of
- the interface and endpoint descriptors.
- This is IMHO needed until usb_reset_device() is changed inside the
- kernel's USB subsystem.
- Copied from usb/core/config.c:usb_get_configuration()
-
- THIS IS VERY UGLY CODE - DO NOT COPY IT ! */
-
-#define AT76C503A_USB_CONFDESCR_LEN 0x20
-/* the short configuration descriptor before reset */
-//#define AT76C503A_USB_SHORT_CONFDESCR_LEN 0x19
-
-static int update_usb_intf_descr(struct at76c503 *dev)
-{
- int intf0; /* begin of intf descriptor in configuration */
- int ep0, ep1; /* begin of endpoint descriptors */
-
- struct usb_device *udev = dev->udev;
- struct usb_config_descriptor *cfg_desc;
- int result = 0, size;
- u8 *buffer;
- struct usb_host_interface *ifp;
int i;
- dbg(DBG_DEVSTART, "%s: ENTER", __FUNCTION__);
-
- cfg_desc = (struct usb_config_descriptor *)
- kmalloc(AT76C503A_USB_CONFDESCR_LEN, GFP_KERNEL);
- if (!cfg_desc) {
- err("cannot kmalloc config desc");
- return -ENOMEM;
- }
-
- result = usb_get_descriptor(udev, USB_DT_CONFIG, 0,
- cfg_desc, AT76C503A_USB_CONFDESCR_LEN);
- if (result < AT76C503A_USB_CONFDESCR_LEN) {
- if (result < 0)
- err("unable to get descriptor");
- else {
- err("config descriptor too short (expected >= %i, got %i)",
- AT76C503A_USB_CONFDESCR_LEN, result);
- result = -EINVAL;
- }
- goto err;
- }
-
- /* now check the config descriptor */
- le16_to_cpus(&cfg_desc->wTotalLength);
- size = cfg_desc->wTotalLength;
- buffer = (u8 *)cfg_desc;
+ if (!debug)
+ return;
- if (cfg_desc->bNumInterfaces > 1) {
- err("found %d interfaces", cfg_desc->bNumInterfaces);
- result = - EINVAL;
- goto err;
- }
-
- if ((result=analyze_usb_config(buffer, size, &intf0, &ep0, &ep1))) {
-
- err("analyze_usb_config returned %d for config desc %s",
- result,
- hex2str(dev->obuf, (u8 *)cfg_desc,
- min((int)(sizeof(dev->obuf)-1)/2,size), '\0'));
- result=-EINVAL;
- goto err;
- }
-
- /* we got the correct config descriptor - update the interface's endpoints */
- ifp = &udev->actconfig->interface[0]->altsetting[0];
-
- if (ifp->endpoint)
- kfree(ifp->endpoint);
-
- memcpy(&ifp->desc, buffer+intf0, USB_DT_INTERFACE_SIZE);
-
- if (!(ifp->endpoint = kmalloc(2 * sizeof(struct usb_host_endpoint),
- GFP_KERNEL))) {
- result = -ENOMEM;
- goto err;
- }
- memset(ifp->endpoint, 0, 2 * sizeof(struct usb_host_endpoint));
- memcpy(&ifp->endpoint[0].desc, buffer+ep0, USB_DT_ENDPOINT_SIZE);
- le16_to_cpus(&ifp->endpoint[0].desc.wMaxPacketSize);
- memcpy(&ifp->endpoint[1].desc, buffer+ep1, USB_DT_ENDPOINT_SIZE);
- le16_to_cpus(&ifp->endpoint[1].desc.wMaxPacketSize);
-
- /* we must set the max packet for the new ep (see usb_set_maxpacket() ) */
-
-#define usb_endpoint_out(ep_dir) (!((ep_dir) & USB_DIR_IN))
- for(i=0; i < ifp->desc.bNumEndpoints; i++) {
- struct usb_endpoint_descriptor *d = &ifp->endpoint[i].desc;
- int b = d->bEndpointAddress & USB_ENDPOINT_NUMBER_MASK;
- if (usb_endpoint_out(d->bEndpointAddress)) {
- if (d->wMaxPacketSize > udev->epmaxpacketout[b])
- udev->epmaxpacketout[b] = d->wMaxPacketSize;
- } else {
- if (d->wMaxPacketSize > udev->epmaxpacketin[b])
- udev->epmaxpacketin[b] = d->wMaxPacketSize;
- }
+ printk (KERN_DEBUG __FILE__": %s - length = %d, data = ",
+ function, size);
+ for (i = 0; i < size; ++i) {
+ if((i % 8) == 0)
+ printk ("\n");
+ printk ("%.2x ", data[i]);
}
-
- dbg(DBG_DEVSTART, "%s: ifp %p num_altsetting %d "
- "endpoint addr x%x, x%x", __FUNCTION__,
- ifp, udev->actconfig->interface[0]->num_altsetting,
- ifp->endpoint[0].desc.bEndpointAddress,
- ifp->endpoint[1].desc.bEndpointAddress);
- result = 0;
-err:
- kfree(cfg_desc);
- dbg(DBG_DEVSTART, "%s: EXIT with %d", __FUNCTION__, result);
- return result;
-} /* update_usb_intf_descr */
-
-#endif /* #if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8) */
-
+ printk ("\n");
+}
-static int at76c503_remap(struct usb_device *udev)
+static inline
+int remap(struct usb_device *udev)
{
- int ret;
- ret = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
- 0x0a, INTERFACE_VENDOR_REQUEST_OUT,
- 0, 0,
- NULL, 0, HZ * USB_CTRL_GET_TIMEOUT);
- if (ret < 0)
- return ret;
-
- return 0;
+ return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+ 0x0a, INTERFACE_VENDOR_REQUEST_OUT,
+ 0, 0,
+ NULL, 0, HZ);
}
-
-static int get_op_mode(struct usb_device *udev)
+static inline
+int get_op_mode(struct at76c503 *dev)
{
int ret;
- u8 op_mode;
-
- ret = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ ret = usb_control_msg(dev->udev, usb_rcvctrlpipe(dev->udev,0),
0x33, INTERFACE_VENDOR_REQUEST_IN,
0x01, 0,
- &op_mode, 1, HZ * USB_CTRL_GET_TIMEOUT);
+ &dev->op_mode, 1, HZ);
if(ret < 0)
return ret;
- return op_mode;
+ return dev->op_mode;
}
/* this loads a block of the second part of the firmware */
-static inline int load_ext_fw_block(struct usb_device *udev,
+static inline
+int load_ext_fw_block(struct usb_device *udev,
int i, unsigned char *buf, int bsize)
{
return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
0x0e, DEVICE_VENDOR_REQUEST_OUT,
0x0802, i,
- buf, bsize, HZ * USB_CTRL_GET_TIMEOUT);
+ buf, bsize, HZ);
}
-static inline int get_hw_cfg_rfmd(struct usb_device *udev,
+static inline
+int get_hw_cfg(struct usb_device *udev,
unsigned char *buf, int buf_size)
{
return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),
0x33, INTERFACE_VENDOR_REQUEST_IN,
((0x0a << 8) | 0x02), 0,
- buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT);
+ buf, buf_size, HZ);
}
-/* Intersil boards use a different "value" for GetHWConfig requests */
static inline
-int get_hw_cfg_intersil(struct usb_device *udev,
- unsigned char *buf, int buf_size)
-{
- return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),
- 0x33, INTERFACE_VENDOR_REQUEST_IN,
- ((0x09 << 8) | 0x02), 0,
- buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT);
-}
-
-/* Get the hardware configuration for the adapter and place the appropriate
- * data in the appropriate fields of 'dev' (the GetHWConfig request and
- * interpretation of the result depends on the type of board we're dealing
- * with) */
-static int get_hw_config(struct at76c503 *dev)
-{
- int ret;
- union {
- struct hwcfg_intersil i;
- struct hwcfg_rfmd r3;
- struct hwcfg_r505 r5;
- } *hwcfg = kmalloc(sizeof(*hwcfg), GFP_KERNEL);
-
- if (!hwcfg)
- return -ENOMEM;
-
- switch (dev->board_type) {
-
- case BOARDTYPE_503_INTERSIL_3861:
- case BOARDTYPE_503_INTERSIL_3863:
- ret = get_hw_cfg_intersil(dev->udev, (unsigned char *)&hwcfg->i, sizeof(hwcfg->i));
- if (ret < 0) break;
- memcpy(dev->mac_addr, hwcfg->i.mac_addr, ETH_ALEN);
- memcpy(dev->cr31_values, hwcfg->i.cr31_values, 14);
- memcpy(dev->cr58_values, hwcfg->i.cr58_values, 14);
- memcpy(dev->pidvid, hwcfg->i.pidvid, 4);
- dev->regulatory_domain = hwcfg->i.regulatory_domain;
- break;
-
- case BOARDTYPE_503_RFMD:
- case BOARDTYPE_503_RFMD_ACC:
- ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r3, sizeof(hwcfg->r3));
- if (ret < 0) break;
- memcpy(dev->cr20_values, hwcfg->r3.cr20_values, 14);
- memcpy(dev->cr21_values, hwcfg->r3.cr21_values, 14);
- memcpy(dev->bb_cr, hwcfg->r3.bb_cr, 14);
- memcpy(dev->pidvid, hwcfg->r3.pidvid, 4);
- memcpy(dev->mac_addr, hwcfg->r3.mac_addr, ETH_ALEN);
- dev->regulatory_domain = hwcfg->r3.regulatory_domain;
- memcpy(dev->low_power_values, hwcfg->r3.low_power_values, 14);
- memcpy(dev->normal_power_values, hwcfg->r3.normal_power_values, 14);
- break;
-
- case BOARDTYPE_505_RFMD:
- case BOARDTYPE_505_RFMD_2958:
- case BOARDTYPE_505A_RFMD_2958:
- ret = get_hw_cfg_rfmd(dev->udev, (unsigned char *)&hwcfg->r5, sizeof(hwcfg->r5));
- if (ret < 0) break;
- memcpy(dev->cr39_values, hwcfg->r5.cr39_values, 14);
- memcpy(dev->bb_cr, hwcfg->r5.bb_cr, 14);
- memcpy(dev->pidvid, hwcfg->r5.pidvid, 4);
- memcpy(dev->mac_addr, hwcfg->r5.mac_addr, ETH_ALEN);
- dev->regulatory_domain = hwcfg->r5.regulatory_domain;
- memcpy(dev->cr15_values, hwcfg->r5.cr15_values, 14);
- break;
-
- default:
- err("Bad board type set (%d). Unable to get hardware config.", dev->board_type);
- ret = -EINVAL;
- }
-
- kfree(hwcfg);
-
- if (ret < 0) {
- err("Get HW Config failed (%d)", ret);
- }
- return ret;
-}
-
-/* == PROC getRegDomain == */
-static struct reg_domain const *getRegDomain(u16 code)
-{
- static struct reg_domain const fd_tab[] = {
- {0x10, "FCC (U.S)", 0x7ff}, /* ch 1-11 */
- {0x20, "IC (Canada)", 0x7ff}, /* ch 1-11 */
- {0x30, "ETSI (Europe - (Spain+France)", 0x1fff}, /* ch 1-13 */
- {0x31, "Spain", 0x600}, /* ch 10,11 */
- {0x32, "France", 0x1e00}, /* ch 10-13 */
- {0x40, "MKK (Japan)", 0x2000}, /* ch 14 */
- {0x41, "MKK1 (Japan)", 0x3fff}, /* ch 1-14 */
- {0x50, "Israel", 0x3fc}, /* ch 3-9 */
- };
- static int const tab_len = sizeof(fd_tab) / sizeof(struct reg_domain);
-
- /* use this if an unknown code comes in */
- static struct reg_domain const unknown =
- {0, "<unknown>", 0xffffffff};
-
- int i;
-
- for(i=0; i < tab_len; i++)
- if (code == fd_tab[i].code)
- break;
-
- return (i >= tab_len) ? &unknown : &fd_tab[i];
-} /* getFreqDomain */
-
-static inline int get_mib(struct usb_device *udev,
+int get_mib(struct usb_device *udev,
u16 mib, u8 *buf, int buf_size)
{
return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),
0x33, INTERFACE_VENDOR_REQUEST_IN,
mib << 8, 0,
- buf, buf_size, HZ * USB_CTRL_GET_TIMEOUT);
+ buf, buf_size, HZ);
}
-static inline int get_cmd_status(struct usb_device *udev,
+static inline
+int get_cmd_status(struct usb_device *udev,
u8 cmd, u8 *cmd_status)
{
return usb_control_msg(udev, usb_rcvctrlpipe(udev,0),
0x22, INTERFACE_VENDOR_REQUEST_IN,
cmd, 0,
- cmd_status, 40, HZ * USB_CTRL_GET_TIMEOUT);
+ cmd_status, 40, HZ);
}
#define EXT_FW_BLOCK_SIZE 1024
-static int download_external_fw(struct usb_device *udev, u8 *buf, int size)
+static int
+download_external_fw(struct usb_device *udev, u8 *buf, int size)
{
int i = 0, ret = 0;
u8 *block;
- if (size < 0) return -EINVAL;
- if ((size > 0) && (buf == NULL)) return -EFAULT;
+ if(size < 0) return -EINVAL;
+ if((size > 0) && (buf == NULL)) return -EFAULT;
block = kmalloc(EXT_FW_BLOCK_SIZE, GFP_KERNEL);
- if (block == NULL) return -ENOMEM;
+ if(block == NULL) return -ENOMEM;
- dbg(DBG_DEVSTART, "downloading external firmware");
+ info("downloading external firmware");
while(size > 0){
int bsize = size > EXT_FW_BLOCK_SIZE ? EXT_FW_BLOCK_SIZE : size;
memcpy(block, buf, bsize);
- dbg(DBG_DEVSTART,
- "ext fw, size left = %5d, bsize = %4d, i = %2d", size, bsize, i);
+ dbg("ext fw, size left = %5d, bsize = %4d, i = %2d", size, bsize, i);
if((ret = load_ext_fw_block(udev, i, block, bsize)) < 0){
err("load_ext_fw_block failed: %d, i = %d", ret, i);
goto exit;
@@ -1155,7 +633,8 @@ static int download_external_fw(struct usb_device *udev, u8 *buf, int size)
return ret;
}
-static int set_card_command(struct usb_device *udev, int cmd,
+static
+int set_card_command(struct usb_device *udev, int cmd,
unsigned char *buf, int buf_size)
{
int ret;
@@ -1175,7 +654,7 @@ static int set_card_command(struct usb_device *udev, int cmd,
0, 0,
cmd_buf,
sizeof(struct at76c503_command) + buf_size,
- HZ * USB_CTRL_GET_TIMEOUT);
+ HZ);
kfree(cmd_buf);
return ret;
}
@@ -1183,28 +662,8 @@ static int set_card_command(struct usb_device *udev, int cmd,
return -ENOMEM;
}
-#define MAKE_CMD_STATUS_CASE(c) case (c): return #c
-
-static const char* get_cmd_status_string(u8 cmd_status)
-{
- switch (cmd_status)
- {
- MAKE_CMD_STATUS_CASE(CMD_STATUS_IDLE);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_COMPLETE);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_UNKNOWN);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_INVALID_PARAMETER);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_FUNCTION_NOT_SUPPORTED);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_TIME_OUT);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_IN_PROGRESS);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_HOST_FAILURE);
- MAKE_CMD_STATUS_CASE(CMD_STATUS_SCAN_FAILED);
- }
-
- return "UNKNOWN";
-}
-
/* TODO: should timeout */
-static int wait_completion(struct at76c503 *dev, int cmd)
+int wait_completion(struct at76c503 *dev, int cmd)
{
u8 *cmd_status = kmalloc(40, GFP_KERNEL);
struct net_device *netdev = dev->netdev;
@@ -1216,17 +675,16 @@ static int wait_completion(struct at76c503 *dev, int cmd)
err("%s: get_cmd_status failed: %d", netdev->name, ret);
break;
}
-
- dbg(DBG_WAIT_COMPLETE, "%s: Waiting on cmd %d, cmd_status[5] = %d (%s)",
- dev->netdev->name, cmd, cmd_status[5], get_cmd_status_string(cmd_status[5]));
+#if 0
+ info("cmd %d,cmd_status[5] = %d", cmd,cmd_status[5]);
+#endif
if(cmd_status[5] == CMD_STATUS_IN_PROGRESS ||
cmd_status[5] == CMD_STATUS_IDLE){
set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/10); /* 100 ms */
+ schedule_timeout(HZ/10); // 100 ms
}else break;
}while(1);
-
if (ret >= 0)
/* if get_cmd_status did not fail, return the status
retrieved */
@@ -1235,9 +693,9 @@ static int wait_completion(struct at76c503 *dev, int cmd)
return ret;
}
-static int set_mib(struct at76c503 *dev, struct set_mib_buffer *buf)
+static inline
+int set_mib(struct usb_device *udev, struct set_mib_buffer *buf)
{
- struct usb_device *udev = dev->udev;
int ret;
struct at76c503_command *cmd_buf =
(struct at76c503_command *)kmalloc(
@@ -1254,14 +712,7 @@ static int set_mib(struct at76c503 *dev, struct set_mib_buffer *buf)
0, 0,
cmd_buf,
sizeof(struct at76c503_command) + buf->size + 4,
- HZ * USB_CTRL_GET_TIMEOUT);
- if (ret >= 0)
- if ((ret=wait_completion(dev, CMD_SET_MIB)) !=
- CMD_STATUS_COMPLETE) {
- info("%s: set_mib: wait_completion failed with %d",
- dev->netdev->name, ret);
- ret = -156; /* ??? */
- }
+ HZ);
kfree(cmd_buf);
return ret;
}
@@ -1269,146 +720,88 @@ static int set_mib(struct at76c503 *dev, struct set_mib_buffer *buf)
return -ENOMEM;
}
-/* return < 0 on error, == 0 if no command sent, == 1 if cmd sent */
-static int set_radio(struct at76c503 *dev, int on_off)
+static
+int set_radio(struct at76c503 *dev, int on_off)
{
- int ret;
+ int ret = 0;
if(dev->radio_on != on_off){
ret = set_card_command(dev->udev, CMD_RADIO, NULL, 0);
if(ret < 0){
err("%s: set_card_command(CMD_RADIO) failed: %d", dev->netdev->name, ret);
- } else
- ret = 1;
+ }
dev->radio_on = on_off;
- } else
- ret = 0;
- return ret;
-}
-
-
-/* == PROC set_pm_mode ==
- sets power save modi (PM_ACTIVE/PM_SAVE/PM_SMART_SAVE) */
-static int set_pm_mode(struct at76c503 *dev, u8 mode)
-{
- int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_MGMT;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = POWER_MGMT_MODE_OFFSET;
-
- dev->mib_buf.data[0] = mode;
-
- ret = set_mib(dev, &dev->mib_buf);
- if(ret < 0){
- err("%s: set_mib (pm_mode) failed: %d", dev->netdev->name, ret);
}
return ret;
}
-/* == PROC set_associd ==
- sets the assoc id for power save mode */
-static int set_associd(struct at76c503 *dev, u16 id)
-{
- int ret = 0;
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_MGMT;
- dev->mib_buf.size = 2;
- dev->mib_buf.index = STATION_ID_OFFSET;
-
- dev->mib_buf.data[0] = id & 0xff;
- dev->mib_buf.data[1] = id >> 8;
-
- ret = set_mib(dev, &dev->mib_buf);
- if(ret < 0){
- err("%s: set_mib (associd) failed: %d", dev->netdev->name, ret);
- }
- return ret;
-}
-
-/* == PROC set_listen_interval ==
- sets the listen interval for power save mode.
- really needed, as we have a similar parameter in the assocreq ??? */
-static int set_listen_interval(struct at76c503 *dev, u16 interval)
-{
- int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC;
- dev->mib_buf.size = 2;
- dev->mib_buf.index = STATION_ID_OFFSET;
-
- dev->mib_buf.data[0] = interval & 0xff;
- dev->mib_buf.data[1] = interval >> 8;
-
- ret = set_mib(dev, &dev->mib_buf);
- if(ret < 0){
- err("%s: set_mib (listen_interval) failed: %d",
- dev->netdev->name, ret);
- }
- return ret;
-}
-
-static int set_preamble(struct at76c503 *dev, u8 type)
+static
+int set_preamble(struct at76c503 *dev, u8 type)
{
int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_LOCAL;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = PREAMBLE_TYPE_OFFSET;
- dev->mib_buf.data[0] = type;
- ret = set_mib(dev, &dev->mib_buf);
+ struct set_mib_buffer mib_buf;
+
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_LOCAL;
+ mib_buf.size = 1;
+ mib_buf.index = PREAMBLE_TYPE_OFFSET;
+ mib_buf.data[0] = type;
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (preamble) failed: %d", dev->netdev->name, ret);
}
return ret;
}
-static int set_frag(struct at76c503 *dev, u16 size)
+static
+int set_frag(struct at76c503 *dev, u16 size)
{
int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC;
- dev->mib_buf.size = 2;
- dev->mib_buf.index = FRAGMENTATION_OFFSET;
- *(__le16*)dev->mib_buf.data = cpu_to_le16(size);
- ret = set_mib(dev, &dev->mib_buf);
+ struct set_mib_buffer mib_buf;
+
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC;
+ mib_buf.size = 2;
+ mib_buf.index = FRAGMENTATION_OFFSET;
+ *(u16*)mib_buf.data = cpu_to_le16(size);
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (frag threshold) failed: %d", dev->netdev->name, ret);
}
return ret;
}
-static int set_rts(struct at76c503 *dev, u16 size)
+static
+int set_rts(struct at76c503 *dev, u16 size)
{
int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC;
- dev->mib_buf.size = 2;
- dev->mib_buf.index = RTS_OFFSET;
- *(__le16*)dev->mib_buf.data = cpu_to_le16(size);
- ret = set_mib(dev, &dev->mib_buf);
+ struct set_mib_buffer mib_buf;
+
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC;
+ mib_buf.size = 2;
+ mib_buf.index = RTS_OFFSET;
+ *(u16*)mib_buf.data = cpu_to_le16(size);
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (rts) failed: %d", dev->netdev->name, ret);
}
return ret;
}
-static int set_autorate_fallback(struct at76c503 *dev, int onoff)
+static
+int set_autorate_fallback(struct at76c503 *dev, int onoff)
{
int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_LOCAL;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = TX_AUTORATE_FALLBACK_OFFSET;
- dev->mib_buf.data[0] = onoff;
- ret = set_mib(dev, &dev->mib_buf);
+ struct set_mib_buffer mib_buf;
+
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_LOCAL;
+ mib_buf.size = 1;
+ mib_buf.index = TX_AUTORATE_FALLBACK_OFFSET;
+ mib_buf.data[0] = onoff;
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (autorate fallback) failed: %d", dev->netdev->name, ret);
}
@@ -1417,14 +810,15 @@ static int set_autorate_fallback(struct at76c503 *dev, int onoff)
static int set_mac_address(struct at76c503 *dev, void *addr)
{
+ struct set_mib_buffer mib_buf;
int ret = 0;
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_ADD;
- dev->mib_buf.size = ETH_ALEN;
- dev->mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
- memcpy(dev->mib_buf.data, addr, ETH_ALEN);
- ret = set_mib(dev, &dev->mib_buf);
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC_ADD;
+ mib_buf.size = ETH_ALEN;
+ mib_buf.index = offsetof(struct mib_mac_addr, mac_addr);
+ memcpy(mib_buf.data, addr, ETH_ALEN);
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (MAC_ADDR, mac_addr) failed: %d",
dev->netdev->name, ret);
@@ -1437,27 +831,30 @@ static int set_mac_address(struct at76c503 *dev, void *addr)
May still be useful for multicast eventually. */
static int set_group_address(struct at76c503 *dev, u8 *addr, int n)
{
+ struct set_mib_buffer mib_buf;
int ret = 0;
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_ADD;
- dev->mib_buf.size = ETH_ALEN;
- dev->mib_buf.index = offsetof(struct mib_mac_addr, group_addr) + n*ETH_ALEN;
- memcpy(dev->mib_buf.data, addr, ETH_ALEN);
- ret = set_mib(dev, &dev->mib_buf);
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC_ADD;
+ mib_buf.size = ETH_ALEN;
+ mib_buf.index = offsetof(struct mib_mac_addr, group_addr) + n*ETH_ALEN;
+ memcpy(mib_buf.data, addr, ETH_ALEN);
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (MIB_MAC_ADD, group_addr) failed: %d",
dev->netdev->name, ret);
}
#if 1
- /* I do not know anything about the group_addr_status field... (oku) */
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_ADD;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = offsetof(struct mib_mac_addr, group_addr_status) + n;
- dev->mib_buf.data[0] = 1;
- ret = set_mib(dev, &dev->mib_buf);
+ /* I do not know anything about the group_addr_status field... (oku)*/
+ wait_completion(dev, CMD_SET_MIB);
+
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC_ADD;
+ mib_buf.size = 1;
+ mib_buf.index = offsetof(struct mib_mac_addr, group_addr_status) + n;
+ mib_buf.data[0] = 1;
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (MIB_MAC_ADD, group_addr_status) failed: %d",
dev->netdev->name, ret);
@@ -1467,320 +864,24 @@ static int set_group_address(struct at76c503 *dev, u8 *addr, int n)
}
#endif
-static int set_promisc(struct at76c503 *dev, int onoff)
-{
- int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_LOCAL;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
- dev->mib_buf.data[0] = onoff ? 1 : 0;
- ret = set_mib(dev, &dev->mib_buf);
- if(ret < 0){
- err("%s: set_mib (promiscuous_mode) failed: %d", dev->netdev->name, ret);
- }
- return ret;
-}
-
-static int dump_mib_mac_addr(struct at76c503 *dev)
-{
- int ret = 0;
- struct mib_mac_addr *mac_addr =
- kmalloc(sizeof(struct mib_mac_addr), GFP_KERNEL);
-
- if(!mac_addr){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_MAC_ADD,
- (u8*)mac_addr, sizeof(struct mib_mac_addr));
- if(ret < 0){
- err("%s: get_mib (MAC_ADDR) failed: %d", dev->netdev->name, ret);
- goto err;
- }
-
- dbg_uc("%s: MIB MAC_ADDR: mac_addr %s res 0x%x 0x%x group_addr %s status %d %d %d %d",
- dev->netdev->name, mac2str(mac_addr->mac_addr),
- mac_addr->res[0], mac_addr->res[1],
- hex2str(dev->obuf, (u8 *)mac_addr->group_addr,
- min((int)(sizeof(dev->obuf)-1)/2, 4*ETH_ALEN), '\0'),
- mac_addr->group_addr_status[0], mac_addr->group_addr_status[1],
- mac_addr->group_addr_status[2], mac_addr->group_addr_status[3]);
-
- err:
- kfree(mac_addr);
- exit:
- return ret;
-}
-
-static int dump_mib_mac_wep(struct at76c503 *dev)
-{
- int ret = 0;
- struct mib_mac_wep *mac_wep =
- kmalloc(sizeof(struct mib_mac_wep), GFP_KERNEL);
-
- if(!mac_wep){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_MAC_WEP,
- (u8*)mac_wep, sizeof(struct mib_mac_wep));
- if(ret < 0){
- err("%s: get_mib (MAC_WEP) failed: %d", dev->netdev->name, ret);
- goto err;
- }
-
- dbg_uc("%s: MIB MAC_WEP: priv_invoked %u def_key_id %u key_len %u "
- "excl_unencr %u wep_icv_err %u wep_excluded %u encr_level %u key %d: %s",
- dev->netdev->name, mac_wep->privacy_invoked,
- mac_wep->wep_default_key_id, mac_wep->wep_key_mapping_len,
- mac_wep->exclude_unencrypted,le32_to_cpu( mac_wep->wep_icv_error_count),
- le32_to_cpu(mac_wep->wep_excluded_count),
- mac_wep->encryption_level, mac_wep->wep_default_key_id,
- mac_wep->wep_default_key_id < 4 ?
- hex2str(dev->obuf,
- mac_wep->wep_default_keyvalue[mac_wep->wep_default_key_id],
- min((int)(sizeof(dev->obuf)-1)/2,
- mac_wep->encryption_level == 2 ? 13 : 5), '\0') :
- "<invalid key id>");
-
- err:
- kfree(mac_wep);
- exit:
- return ret;
-}
-
-static int dump_mib_mac_mgmt(struct at76c503 *dev)
-{
- int ret = 0;
- struct mib_mac_mgmt *mac_mgmt =
- kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
- char country_string[4];
-
- if(!mac_mgmt){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_MAC_MGMT,
- (u8*)mac_mgmt, sizeof(struct mib_mac_mgmt));
- if(ret < 0){
- err("%s: get_mib failed: %d", dev->netdev->name, ret);
- goto err;
- }
-
- memcpy(&country_string, mac_mgmt->country_string, 3);
- country_string[3] = '\0';
-
- dbg_uc("%s: MIB MAC_MGMT: beacon_period %d CFP_max_duration %d "
- "medium_occupancy_limit %d station_id 0x%x ATIM_window %d "
- "CFP_mode %d privacy_opt_impl %d DTIM_period %d CFP_period %d "
- "current_bssid %s current_essid %s current_bss_type %d "
- "pm_mode %d ibss_change %d res %d "
- "multi_domain_capability_implemented %d "
- "international_roaming %d country_string %s",
- dev->netdev->name,
- le16_to_cpu(mac_mgmt->beacon_period),
- le16_to_cpu(mac_mgmt->CFP_max_duration),
- le16_to_cpu(mac_mgmt->medium_occupancy_limit),
- le16_to_cpu(mac_mgmt->station_id),
- le16_to_cpu(mac_mgmt->ATIM_window),
- mac_mgmt->CFP_mode,
- mac_mgmt->privacy_option_implemented,
- mac_mgmt->DTIM_period,
- mac_mgmt->CFP_period,
- mac2str(mac_mgmt->current_bssid),
- hex2str(dev->obuf, (u8 *)mac_mgmt->current_essid,
- min((int)(sizeof(dev->obuf)-1)/2,
- IW_ESSID_MAX_SIZE), '\0'),
- mac_mgmt->current_bss_type,
- mac_mgmt->power_mgmt_mode,
- mac_mgmt->ibss_change,
- mac_mgmt->res,
- mac_mgmt->multi_domain_capability_implemented,
- mac_mgmt->multi_domain_capability_enabled,
- country_string);
- err:
- kfree(mac_mgmt);
- exit:
- return ret;
-}
-
-static int dump_mib_mac(struct at76c503 *dev)
-{
- int ret = 0;
- struct mib_mac *mac =
- kmalloc(sizeof(struct mib_mac), GFP_KERNEL);
-
- if(!mac){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_MAC,
- (u8*)mac, sizeof(struct mib_mac));
- if(ret < 0){
- err("%s: get_mib failed: %d", dev->netdev->name, ret);
- goto err;
- }
-
- dbg_uc("%s: MIB MAC: max_tx_msdu_lifetime %d max_rx_lifetime %d "
- "frag_threshold %d rts_threshold %d cwmin %d cwmax %d "
- "short_retry_time %d long_retry_time %d scan_type %d "
- "scan_channel %d probe_delay %u min_channel_time %d "
- "max_channel_time %d listen_int %d desired_ssid %s "
- "desired_bssid %s desired_bsstype %d",
- dev->netdev->name,
- le32_to_cpu(mac->max_tx_msdu_lifetime),
- le32_to_cpu(mac->max_rx_lifetime),
- le16_to_cpu(mac->frag_threshold),
- le16_to_cpu(mac->rts_threshold),
- le16_to_cpu(mac->cwmin),
- le16_to_cpu(mac->cwmax),
- mac->short_retry_time,
- mac->long_retry_time,
- mac->scan_type,
- mac->scan_channel,
- le16_to_cpu(mac->probe_delay),
- le16_to_cpu(mac->min_channel_time),
- le16_to_cpu(mac->max_channel_time),
- le16_to_cpu(mac->listen_interval),
- hex2str(dev->obuf, mac->desired_ssid,
- min((int)(sizeof(dev->obuf)-1)/2,
- IW_ESSID_MAX_SIZE), '\0'),
- mac2str(mac->desired_bssid),
- mac->desired_bsstype);
- err:
- kfree(mac);
- exit:
- return ret;
-}
-
-static int dump_mib_phy(struct at76c503 *dev)
+static
+int set_promisc(struct at76c503 *dev, int onoff)
{
int ret = 0;
- struct mib_phy *phy =
- kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-
- if(!phy){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_PHY,
- (u8*)phy, sizeof(struct mib_phy));
+ struct set_mib_buffer mib_buf;
+
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_LOCAL;
+ mib_buf.size = 1;
+ mib_buf.index = offsetof(struct mib_local, promiscuous_mode);
+ mib_buf.data[0] = onoff ? 1 : 0;
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
- err("%s: get_mib failed: %d", dev->netdev->name, ret);
- goto err;
+ err("%s: set_mib (promiscous_mode) failed: %d", dev->netdev->name, ret);
}
-
- dbg_uc("%s: MIB PHY: ed_threshold %d slot_time %d sifs_time %d "
- "preamble_length %d plcp_header_length %d mpdu_max_length %d "
- "cca_mode_supported %d operation_rate_set "
- "0x%x 0x%x 0x%x 0x%x channel_id %d current_cca_mode %d "
- "phy_type %d current_reg_domain %d",
- dev->netdev->name,
- le32_to_cpu(phy->ed_threshold),
- le16_to_cpu(phy->slot_time),
- le16_to_cpu(phy->sifs_time),
- le16_to_cpu(phy->preamble_length),
- le16_to_cpu(phy->plcp_header_length),
- le16_to_cpu(phy->mpdu_max_length),
- le16_to_cpu(phy->cca_mode_supported),
- phy->operation_rate_set[0], phy->operation_rate_set[1],
- phy->operation_rate_set[2], phy->operation_rate_set[3],
- phy->channel_id,
- phy->current_cca_mode,
- phy->phy_type,
- phy->current_reg_domain);
- err:
- kfree(phy);
- exit:
return ret;
}
-static int dump_mib_local(struct at76c503 *dev)
-{
- int ret = 0;
- struct mib_local *local =
- kmalloc(sizeof(struct mib_phy), GFP_KERNEL);
-
- if(!local){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_LOCAL,
- (u8*)local, sizeof(struct mib_local));
- if(ret < 0){
- err("%s: get_mib failed: %d", dev->netdev->name, ret);
- goto err;
- }
-
- dbg_uc("%s: MIB PHY: beacon_enable %d txautorate_fallback %d "
- "ssid_size %d promiscuous_mode %d preamble_type %d",
- dev->netdev->name,
- local->beacon_enable,
- local->txautorate_fallback,
- local->ssid_size,
- local->promiscuous_mode,
- local->preamble_type);
- err:
- kfree(local);
- exit:
- return ret;
-}
-
-
-static int get_mib_mdomain(struct at76c503 *dev, struct mib_mdomain *val)
-{
- int ret = 0;
- struct mib_mdomain *mdomain =
- kmalloc(sizeof(struct mib_mdomain), GFP_KERNEL);
-
- if(!mdomain){
- ret = -ENOMEM;
- goto exit;
- }
-
- ret = get_mib(dev->udev, MIB_MDOMAIN,
- (u8*)mdomain, sizeof(struct mib_mdomain));
- if(ret < 0){
- err("%s: get_mib failed: %d", dev->netdev->name, ret);
- goto err;
- }
-
- memcpy(val, mdomain, sizeof(*val));
-
- err:
- kfree(mdomain);
- exit:
- return ret;
-}
-
-static void dump_mib_mdomain(struct at76c503 *dev)
-{
- char obuf1[2*14+1], obuf2[2*14+1]; /* to hexdump tx_powerlevel,
- channel_list */
- int ret;
- struct mib_mdomain mdomain;
-
- if ((ret=get_mib_mdomain(dev, &mdomain)) < 0) {
- err("%s: get_mib_mdomain returned %d", __FUNCTION__, ret);
- return;
- }
-
- dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s tx_powerlevel %s",
- dev->netdev->name,
- hex2str(obuf1, mdomain.channel_list,
- (sizeof(obuf1)-1)/2,'\0'),
- hex2str(obuf2, mdomain.tx_powerlevel,
- (sizeof(obuf2)-1)/2,'\0'));
-}
-
static
int get_current_bssid(struct at76c503 *dev)
{
@@ -1807,7 +908,8 @@ int get_current_bssid(struct at76c503 *dev)
return ret;
}
-static int get_current_channel(struct at76c503 *dev)
+static
+int get_current_channel(struct at76c503 *dev)
{
int ret = 0;
struct mib_phy *phy =
@@ -1830,70 +932,38 @@ static int get_current_channel(struct at76c503 *dev)
return ret;
}
-/* == PROC start_scan ==
- start a scan. use_essid is != 0 if any probe_delay (if scan mode is not
- passive) should contain the ESSID configured. ir_step describes the
- international roaming step (0, 1) */
-static int start_scan(struct at76c503 *dev, int use_essid, int ir_step)
+static
+int start_scan(struct at76c503 *dev)
{
struct at76c503_start_scan scan;
+ dev->bss_nr = 0; /* empty the table dev->bss[] */
+ dev->curr_bss = dev->new_bss = -1;
+
memset(&scan, 0, sizeof(struct at76c503_start_scan));
memset(scan.bssid, 0xff, ETH_ALEN);
-
- if (use_essid) {
- memcpy(scan.essid, dev->essid, IW_ESSID_MAX_SIZE);
- scan.essid_size = dev->essid_size;
- } else
- scan.essid_size = 0;
-
- /* jal: why should we start at a certain channel? we do scan the whole range
- allowed by reg domain. */
+ //jal: we scan for all SSID and choose the right one later
+ // to see our env etc.
+ //memcpy(scan.essid, dev->essid, IW_ESSID_MAX_SIZE);
+ scan.essid_size = 0;
+ scan.probe_delay = 10000;
+ //jal: why should we start at a certain channel? we do scan the whole range
+ //allowed by reg domain.
scan.channel = dev->channel;
- /* atmelwlandriver differs between scan type 0 and 1 (active/passive)
+ /* atmelwlandriver differs between scan type 0 and 1.
For ad-hoc mode, it uses type 0 only.*/
- if ((dev->international_roaming == IR_ON && ir_step == 0) ||
- dev->iw_mode == IW_MODE_MONITOR)
- scan.scan_type = SCAN_TYPE_PASSIVE;
- else
- scan.scan_type = dev->scan_mode;
-
- /* INFO: For probe_delay, not multiplying by 1024 as this will be
- slightly less than min_channel_time
- (per spec: probe delay < min. channel time) */
- LOCK_ISTATE()
- if (dev->istate == MONITORING) {
- scan.min_channel_time = cpu_to_le16(dev->monitor_scan_min_time);
- scan.max_channel_time = cpu_to_le16(dev->monitor_scan_max_time);
- scan.probe_delay = cpu_to_le16(dev->monitor_scan_min_time * 1000);
- } else {
- scan.min_channel_time = cpu_to_le16(dev->scan_min_time);
- scan.max_channel_time = cpu_to_le16(dev->scan_max_time);
- scan.probe_delay = cpu_to_le16(dev->scan_min_time * 1000);
- }
- UNLOCK_ISTATE()
- if (dev->international_roaming == IR_ON && ir_step == 1)
- scan.international_scan = 0;
- else
- scan.international_scan = dev->international_roaming;
+ scan.min_channel_time = 10;
+ scan.max_channel_time = 120;
/* other values are set to 0 for type 0 */
- dbg(DBG_PROGRESS, "%s: start_scan (use_essid = %d, intl = %d, "
- "channel = %d, probe_delay = %d, scan_min_time = %d, "
- "scan_max_time = %d)",
- dev->netdev->name, use_essid,
- scan.international_scan, scan.channel,
- le16_to_cpu(scan.probe_delay),
- le16_to_cpu(scan.min_channel_time),
- le16_to_cpu(scan.max_channel_time));
-
return set_card_command(dev->udev, CMD_SCAN,
(unsigned char*)&scan, sizeof(scan));
}
-static int start_ibss(struct at76c503 *dev)
+static
+int start_ibss(struct at76c503 *dev)
{
struct at76c503_start_bss bss;
@@ -1909,11 +979,14 @@ static int start_ibss(struct at76c503 *dev)
}
/* idx points into dev->bss */
-static int join_bss(struct at76c503 *dev, struct bss_info *ptr)
+static
+int join_bss(struct at76c503 *dev, int idx)
{
struct at76c503_join join;
+ struct bss_info *ptr;
- assert(ptr != NULL);
+ assert(idx < dev->bss_nr);
+ ptr = dev->bss+idx;
memset(&join, 0, sizeof(struct at76c503_join));
memcpy(join.bssid, ptr->bssid, ETH_ALEN);
@@ -1921,243 +994,69 @@ static int join_bss(struct at76c503 *dev, struct bss_info *ptr)
join.essid_size = ptr->ssid_len;
join.bss_type = (dev->iw_mode == IW_MODE_ADHOC ? 1 : 2);
join.channel = ptr->channel;
- join.timeout = cpu_to_le16(2000);
+ join.timeout = 2000;
- dbg(DBG_PROGRESS, "%s join addr %s ssid %s type %d ch %d timeout %d",
+ dbg("%s join addr %s ssid %d:%s type %d ch %d timeout %d",
dev->netdev->name, mac2str(join.bssid),
- join.essid, join.bss_type, join.channel, le16_to_cpu(join.timeout));
+ join.essid_size, join.essid,
+ join.bss_type, join.channel, join.timeout);
return set_card_command(dev->udev, CMD_JOIN,
(unsigned char*)&join,
sizeof(struct at76c503_join));
} /* join_bss */
-/* the firmware download timeout (after remap) */
-static void fw_dl_timeout(unsigned long par)
-{
- struct at76c503 *dev = (struct at76c503 *)par;
- defer_kevent(dev, KEVENT_RESET_DEVICE);
-}
-
-
-/* the restart timer timed out */
-static void restart_timeout(unsigned long par)
-{
- struct at76c503 *dev = (struct at76c503 *)par;
- defer_kevent(dev, KEVENT_RESTART);
-}
-
-/* we got to check the bss_list for old entries */
-static void bss_list_timeout(unsigned long par)
-{
- struct at76c503 *dev = (struct at76c503 *)par;
- unsigned long flags;
- struct list_head *lptr, *nptr;
- struct bss_info *ptr;
-
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
-
- list_for_each_safe(lptr, nptr, &dev->bss_list) {
-
- ptr = list_entry(lptr, struct bss_info, list);
-
- if (ptr != dev->curr_bss && ptr != dev->new_bss &&
- time_after(jiffies, ptr->last_rx+BSS_LIST_TIMEOUT)) {
- dbg(DBG_BSS_TABLE_RM,
- "%s: bss_list: removing old BSS %s ch %d",
- dev->netdev->name, mac2str(ptr->bssid), ptr->channel);
- list_del(&ptr->list);
- kfree(ptr);
- }
- }
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
- /* restart the timer */
- mod_timer(&dev->bss_list_timer, jiffies+BSS_LIST_TIMEOUT);
-
-}
-
/* we got a timeout for a infrastructure mgmt packet */
-static void mgmt_timeout(unsigned long par)
+void mgmt_timeout(unsigned long par)
{
struct at76c503 *dev = (struct at76c503 *)par;
defer_kevent(dev, KEVENT_MGMT_TIMEOUT);
}
-/* == PROC handle_mgmt_timeout_scan == */
-/* called in istate SCANNING on expiry of the mgmt_timer, when a scan was run before
- (dev->scan_runs > 0) */
-static void handle_mgmt_timeout_scan(struct at76c503 *dev)
-{
-
- u8 *cmd_status;
- int ret;
- struct mib_mdomain mdomain;
-
- cmd_status = kmalloc(40, GFP_KERNEL);
- if (cmd_status == NULL) {
- err("%s: %s: cmd_status kmalloc returned NULL",
- dev->netdev->name, __FUNCTION__);
- return;
- }
-
-
- if ((ret=get_cmd_status(dev->udev, CMD_SCAN, cmd_status)) < 0) {
- err("%s: %s: get_cmd_status failed with %d",
- dev->netdev->name, __FUNCTION__, ret);
- cmd_status[5] = CMD_STATUS_IN_PROGRESS;
- /* INFO: Hope it was a one off error - if not, scanning
- further down the line and stop this cycle */
- }
- LOCK_ISTATE()
- dbg(DBG_PROGRESS, "%s %s:%d got cmd_status %d (istate %d, "
- "scan_runs %d)",
- dev->netdev->name, __FUNCTION__, __LINE__, cmd_status[5],
- dev->istate, dev->scan_runs);
- UNLOCK_ISTATE()
- if (cmd_status[5] == CMD_STATUS_COMPLETE) {
- LOCK_ISTATE()
- if (dev->istate == SCANNING) {
- UNLOCK_ISTATE()
- dump_bss_table(dev,0);
- switch (dev->scan_runs) {
-
- case 1:
- assert(dev->international_roaming);
- if ((ret=get_mib_mdomain(dev, &mdomain)) < 0) {
- err("get_mib_mdomain returned %d", ret);
- } else {
- char obuf1[2*14+1], obuf2[2*14+1];
-
- dbg(DBG_MIB, "%s: MIB MDOMAIN: channel_list %s "
- "tx_powerlevel %s",
- dev->netdev->name,
- hex2str(obuf1, mdomain.channel_list,
- (sizeof(obuf1)-1)/2,'\0'),
- hex2str(obuf2, mdomain.tx_powerlevel,
- (sizeof(obuf2)-1)/2,'\0'));
- }
- if ((ret = start_scan(dev, 0, 1)) < 0) {
- err("%s: %s: start_scan (ANY) failed with %d",
- dev->netdev->name, __FUNCTION__, ret);
- }
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",
- __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);
- mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);
- break;
-
- case 2:
- if ((ret = start_scan(dev, 1, 1)) < 0) {
- err("%s: %s: start_scan (SSID) failed with %d",
- dev->netdev->name, __FUNCTION__, ret);
- }
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",
- __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);
- mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);
- break;
-
- case 3:
- dev->site_survey_state = SITE_SURVEY_COMPLETED;
- /* report the end of scan to user space */
- iwevent_scan_complete(dev->netdev);
- NEW_STATE(dev,JOINING);
- assert(dev->curr_bss == NULL); /* done in free_bss_list,
- find_bss will start with first bss */
- /* call join_bss immediately after
- re-run of all other threads in kevent */
- defer_kevent(dev,KEVENT_JOIN);
- break;
-
- default:
- err("unexpected dev->scan_runs %d", dev->scan_runs);
- } /* switch (dev->scan_runs)*/
- dev->scan_runs++;
- } else {
-
- assert(dev->istate == MONITORING);
- UNLOCK_ISTATE()
- dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE: restart scan",
- dev->netdev->name);
- start_scan(dev, 0, 0);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",
- __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);
- mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);
- }
-
- } else {
- if ((cmd_status[5] != CMD_STATUS_IN_PROGRESS) &&
- (cmd_status[5] != CMD_STATUS_IDLE))
- err("%s: %s: Bad scan status: %s",
- dev->netdev->name, __FUNCTION__,
- get_cmd_status_string(cmd_status[5]));
-
- /* the first cmd status after scan start is always a IDLE ->
- start the timer to poll again until COMPLETED */
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",
- __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);
- mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);
- }
-
- kfree(cmd_status);
-}
-
/* the deferred procedure called from kevent() */
-static void handle_mgmt_timeout(struct at76c503 *dev)
+void handle_mgmt_timeout(struct at76c503 *dev)
{
- LOCK_ISTATE()
- if ((dev->istate != SCANNING && dev->istate != MONITORING) ||
- (at76_debug & DBG_MGMT_TIMER))
- /* this is normal behavior in states MONITORING, SCANNING ... */
- dbg(DBG_PROGRESS, "%s: timeout, state %d", dev->netdev->name,
- dev->istate);
+
+ dbg("%s: timeout, state %d", dev->netdev->name, dev->istate);
switch(dev->istate) {
- case MONITORING:
- case SCANNING:
- UNLOCK_ISTATE()
- handle_mgmt_timeout_scan(dev);
+ case SCANNING: /* we use the mgmt_timer to delay the next scan for some time */
+ defer_kevent(dev, KEVENT_SCANJOIN);
break;
case JOINING:
- UNLOCK_ISTATE()
assert(0);
break;
case CONNECTED: /* we haven't received the beacon of this BSS for
BEACON_TIMEOUT seconds */
- UNLOCK_ISTATE()
info("%s: lost beacon bssid %s",
- dev->netdev->name, mac2str(dev->curr_bss->bssid));
- /* jal: starting mgmt_timer in ad-hoc mode is questionable,
- but I'll leave it here to track down another lockup problem */
- if (dev->iw_mode != IW_MODE_ADHOC) {
- netif_carrier_off(dev->netdev);
- netif_stop_queue(dev->netdev);
- iwevent_bss_disconnect(dev->netdev);
- NEW_STATE(dev,SCANNING);
- defer_kevent(dev,KEVENT_SCAN);
- }
+ dev->netdev->name, mac2str(dev->bss[dev->curr_bss].bssid));
+ netif_carrier_off(dev->netdev); /* disable running netdev watchdog */
+ netif_stop_queue(dev->netdev); /* stop tx data packets */
+ NEW_STATE(dev,SCANNING);
+ defer_kevent(dev,KEVENT_SCANJOIN);
break;
case AUTHENTICATING:
- UNLOCK_ISTATE()
if (dev->retries-- >= 0) {
- auth_req(dev, dev->curr_bss, 1, NULL);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
+ auth_req(dev,dev->curr_bss);
mod_timer(&dev->mgmt_timer, jiffies+HZ);
} else {
/* try to get next matching BSS */
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
+ dev->curr_bss = find_matching_bss(dev,dev->curr_bss+1);
+ if (dev->curr_bss >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ }
+ defer_kevent(dev,KEVENT_SCANJOIN);
}
break;
case ASSOCIATING:
- UNLOCK_ISTATE()
if (dev->retries-- >= 0) {
assoc_req(dev,dev->curr_bss);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
mod_timer(&dev->mgmt_timer, jiffies+HZ);
} else {
/* jal: TODO: we may be authenticated to several
@@ -2165,13 +1064,17 @@ static void handle_mgmt_timeout(struct at76c503 *dev)
in the future ... */
/* try to get next matching BSS */
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
+ dev->curr_bss = find_matching_bss(dev,dev->curr_bss+1);
+ if (dev->curr_bss >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ }
+ defer_kevent(dev,KEVENT_SCANJOIN);
}
break;
case REASSOCIATING:
- UNLOCK_ISTATE()
if (dev->retries-- >= 0)
reassoc_req(dev, dev->curr_bss, dev->new_bss);
else {
@@ -2181,42 +1084,35 @@ static void handle_mgmt_timeout(struct at76c503 *dev)
dev->retries = DISASSOC_RETRIES;
disassoc_req(dev, dev->curr_bss);
}
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
mod_timer(&dev->mgmt_timer, jiffies+HZ);
break;
case DISASSOCIATING:
- UNLOCK_ISTATE()
if (dev->retries-- >= 0) {
disassoc_req(dev, dev->curr_bss);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
mod_timer(&dev->mgmt_timer,jiffies+HZ);
} else {
/* we scan again ... */
NEW_STATE(dev,SCANNING);
- defer_kevent(dev,KEVENT_SCAN);
+ defer_kevent(dev,KEVENT_SCANJOIN);
}
break;
case INIT:
- UNLOCK_ISTATE()
+ assert(0);
break;
default:
- UNLOCK_ISTATE()
assert(0);
} /* switch (dev->istate) */
}/* handle_mgmt_timeout */
-/* calc. the padding from txbuf->wlength (which excludes the USB TX header)
- guess this is needed to compensate a flaw in the AT76C503A USB part ... */
-static inline int calc_padding(int wlen)
+/* calc. the padding from txbuf->wlength (which excludes the USB TX header) */
+static inline
+int calc_padding(int wlen)
{
- /* add the USB TX header */
- wlen += AT76C503_TX_HDRLEN;
+ wlen += offsetof(struct at76c503_tx_buffer,packet); /* add the USB TX header */
wlen = wlen % 64;
@@ -2224,16 +1120,17 @@ static inline int calc_padding(int wlen)
return 50 - wlen;
if (wlen >=61)
- return 64 + 50 - wlen;
+ return 114 - wlen;
return 0;
}
-/* send a management frame on bulk-out.
- txbuf->wlength must be set (in LE format !) */
-static int send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf)
+/* send a management frame on bulk-out */
+static
+int send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf)
{
unsigned long flags;
+ char obuf[3*64+1] __attribute__ ((unused));
int ret = 0;
int urb_status;
void *oldbuf = NULL;
@@ -2243,7 +1140,7 @@ static int send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf
spin_lock_irqsave(&dev->mgmt_spinlock, flags);
- if ((urb_status=dev->write_urb->status) == -EINPROGRESS) {
+ if ((urb_status=dev->write_urb->status) == USB_ST_URB_PENDING) {
oldbuf=dev->next_mgmt_bulk; /* to kfree below */
dev->next_mgmt_bulk = txbuf;
txbuf = NULL;
@@ -2254,45 +1151,48 @@ static int send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf
/* a data/mgmt tx is already pending in the URB -
if this is no error in some situations we must
implement a queue or silently modify the old msg */
- err("%s: %s removed pending mgmt buffer %s",
- dev->netdev->name, __FUNCTION__,
- hex2str(dev->obuf, (u8 *)dev->next_mgmt_bulk,
- min((int)(sizeof(dev->obuf))/3, 64),' '));
+ err("%s:" __FUNCTION__ " removed pending mgmt buffer "
+ "%s",
+ dev->netdev->name,
+ hex2str(obuf, (u8 *)dev->next_mgmt_bulk, 64,' '));
kfree(dev->next_mgmt_bulk);
}
if (txbuf) {
txbuf->tx_rate = 0;
- txbuf->padding = calc_padding(le16_to_cpu(txbuf->wlength));
-
+ txbuf->padding = 0;
+// txbuf->padding =
+// cpu_to_le16(calc_padding(le16_to_cpu(txbuf->wlength)));
if (dev->next_mgmt_bulk) {
- err("%s: %s URB status %d, but mgmt is pending",
- dev->netdev->name, __FUNCTION__, urb_status);
+ err("%s:" __FUNCTION__ " URB status %d, "
+ "but mgmt is pending",
+ dev->netdev->name, urb_status);
}
-
- dbg(DBG_TX_MGMT, "%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
+#if 0
+ dbg("%s: tx mgmt: wlen %d tx_rate %d pad %d %s",
dev->netdev->name, le16_to_cpu(txbuf->wlength),
txbuf->tx_rate, txbuf->padding,
- hex2str(dev->obuf, txbuf->packet,
- min((sizeof(dev->obuf)-1)/2,
+ hex2str(obuf,txbuf->packet,
+ min((sizeof(obuf)-1)/2,
(size_t)le16_to_cpu(txbuf->wlength)),'\0'));
-
+#endif
/* txbuf was not consumed above -> send mgmt msg immediately */
memcpy(dev->bulk_out_buffer, txbuf,
- le16_to_cpu(txbuf->wlength) + AT76C503_TX_HDRLEN);
+ le16_to_cpu(txbuf->wlength) +
+ offsetof(struct at76c503_tx_buffer,packet));
FILL_BULK_URB(dev->write_urb, dev->udev,
usb_sndbulkpipe(dev->udev,
dev->bulk_out_endpointAddr),
dev->bulk_out_buffer,
le16_to_cpu(txbuf->wlength) +
- txbuf->padding +
- AT76C503_TX_HDRLEN,
- (usb_complete_t)at76c503_write_bulk_callback, dev);
- ret = usb_submit_urb(dev->write_urb, GFP_ATOMIC);
+ le16_to_cpu(txbuf->padding) +
+ offsetof(struct at76c503_tx_buffer,packet),
+ at76c503_write_bulk_callback, dev);
+ ret = usb_submit_urb(dev->write_urb);
if (ret) {
- err("%s: %s error in tx submit urb: %d",
- dev->netdev->name, __FUNCTION__, ret);
+ err("%s:" __FUNCTION__ " error in tx submit urb: %d",
+ dev->netdev->name, ret);
}
kfree(txbuf);
} /* if (txbuf) */
@@ -2301,39 +1201,42 @@ static int send_mgmt_bulk(struct at76c503 *dev, struct at76c503_tx_buffer *txbuf
} /* send_mgmt_bulk */
-static int disassoc_req(struct at76c503 *dev, struct bss_info *bss)
+static
+int disassoc_req(struct at76c503 *dev, int idx)
{
struct at76c503_tx_buffer *tx_buffer;
- struct ieee80211_hdr_3addr *mgmt;
+ struct ieee802_11_mgmt *mgmt;
struct ieee802_11_disassoc_frame *req;
+ struct bss_info *bss = dev->bss+idx;
- assert(bss != NULL);
- if (bss == NULL)
- return -EFAULT;
+ assert(idx >= 0 && idx < dev->bss_nr);
- tx_buffer = kmalloc(DISASSOC_FRAME_SIZE + MAX_PADDING_SIZE,
- GFP_ATOMIC);
+ tx_buffer = kmalloc(DISASSOC_FRAME_SIZE, GFP_ATOMIC);
if (!tx_buffer)
return -ENOMEM;
- mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet);
- req = (struct ieee802_11_disassoc_frame *)&(mgmt->payload);
+ mgmt = (struct ieee802_11_mgmt *)&(tx_buffer->packet);
+ req = (struct ieee802_11_disassoc_frame *)&(mgmt->data);
/* make wireless header */
- mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_AUTH);
+ /* no need to care about endianness of constants - is taken care
+ of in ieee802_11.h */
+ mgmt->frame_ctl = IEEE802_11_FTYPE_MGMT|IEEE802_11_STYPE_AUTH;
+ if (dev->wep_enabled)
+ mgmt->frame_ctl |= IEEE802_11_FCTL_WEP;
mgmt->duration_id = cpu_to_le16(0x8000);
memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN);
memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
- mgmt->seq_ctl = cpu_to_le16(0);
+ mgmt->seq_ctl = 0;
req->reason = 0;
/* init. at76c503 tx header */
tx_buffer->wlength = cpu_to_le16(DISASSOC_FRAME_SIZE -
- AT76C503_TX_HDRLEN);
+ offsetof(struct at76c503_tx_buffer, packet));
- dbg(DBG_TX_MGMT, "%s: DisAssocReq bssid %s",
+ dbg("%s: DisAssocReq bssid %s",
dev->netdev->name, mac2str(mgmt->addr3));
/* either send immediately (if no data tx is pending
@@ -2342,59 +1245,45 @@ static int disassoc_req(struct at76c503 *dev, struct bss_info *bss)
} /* disassoc_req */
-/* challenge is the challenge string (in TLV format)
- we got with seq_nr 2 for shared secret authentication only and
- send in seq_nr 3 WEP encrypted to prove we have the correct WEP key;
- otherwise it is NULL */
-static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr, u8 *challenge)
+static
+int auth_req(struct at76c503 *dev, int idx)
{
struct at76c503_tx_buffer *tx_buffer;
- struct ieee80211_hdr_3addr *mgmt;
+ struct ieee802_11_mgmt *mgmt;
struct ieee802_11_auth_frame *req;
-
- int buf_len = (seq_nr != 3 ? AUTH_FRAME_SIZE :
- AUTH_FRAME_SIZE + 1 + 1 + challenge[1]);
+ struct bss_info *bss = dev->bss+idx;
- assert(bss != NULL);
- assert(seq_nr != 3 || challenge != NULL);
-
- tx_buffer = kmalloc(buf_len + MAX_PADDING_SIZE, GFP_ATOMIC);
+ assert(idx >= 0 && idx < dev->bss_nr);
+
+ tx_buffer = kmalloc(AUTH_FRAME_SIZE+MAX_PADDING_SIZE, GFP_ATOMIC);
if (!tx_buffer)
return -ENOMEM;
- mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet);
- req = (struct ieee802_11_auth_frame *)&(mgmt->payload);
+ mgmt = (struct ieee802_11_mgmt *)&(tx_buffer->packet);
+ req = (struct ieee802_11_auth_frame *)&(mgmt->data);
/* make wireless header */
- /* first auth msg is not encrypted, only the second (seq_nr == 3) */
- mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT | IEEE80211_STYPE_AUTH |
- (seq_nr == 3 ? IEEE80211_FCTL_PROTECTED : 0));
-
+ /* no need to care about endianness of constants - is taken care
+ of in ieee802_11.h */
+ /* first auth msg is not encrypted */
+ mgmt->frame_ctl = IEEE802_11_FTYPE_MGMT|IEEE802_11_STYPE_AUTH;
mgmt->duration_id = cpu_to_le16(0x8000);
memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN);
memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
- mgmt->seq_ctl = cpu_to_le16(0);
-
- req->algorithm = cpu_to_le16(dev->auth_mode);
- req->seq_nr = cpu_to_le16(seq_nr);
- req->status = cpu_to_le16(0);
+ mgmt->seq_ctl = 0;
- if (seq_nr == 3)
- memcpy(req->challenge, challenge, 1+1+challenge[1]);
+ req->algorithm = IEEE802_11_AUTH_ALG_OPEN_SYSTEM;
+ req->seq_nr = cpu_to_le16(1);
+ req->status = 0;
/* init. at76c503 tx header */
- tx_buffer->wlength = cpu_to_le16(buf_len - AT76C503_TX_HDRLEN);
+ tx_buffer->wlength = cpu_to_le16(AUTH_FRAME_SIZE -
+ offsetof(struct at76c503_tx_buffer, packet));
- dbg(DBG_TX_MGMT, "%s: AuthReq bssid %s alg %d seq_nr %d",
+ dbg("%s: AuthReq bssid %s algorithm %d trans_seq %d",
dev->netdev->name, mac2str(mgmt->addr3),
- le16_to_cpu(req->algorithm), le16_to_cpu(req->seq_nr));
- if (seq_nr == 3) {
- dbg(DBG_TX_MGMT, "%s: AuthReq challenge: %s ...",
- dev->netdev->name,
- hex2str(dev->obuf, req->challenge,
- min((int)sizeof(dev->obuf)/3, 18),' '));
- }
+ req->algorithm, req->seq_nr);
/* either send immediately (if no data tx is pending
or put it in pending list */
@@ -2402,52 +1291,59 @@ static int auth_req(struct at76c503 *dev, struct bss_info *bss, int seq_nr, u8 *
} /* auth_req */
-static int assoc_req(struct at76c503 *dev, struct bss_info *bss)
+static
+int assoc_req(struct at76c503 *dev, int idx)
{
struct at76c503_tx_buffer *tx_buffer;
- struct ieee80211_hdr_3addr *mgmt;
+ struct ieee802_11_mgmt *mgmt;
struct ieee802_11_assoc_req *req;
+ struct bss_info *bss = dev->bss+idx;
u8 *tlv;
- assert(bss != NULL);
+ assert(idx >= 0 && idx < dev->bss_nr);
- tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE,
- GFP_ATOMIC);
+ tx_buffer = kmalloc(ASSOCREQ_MAX_SIZE, GFP_ATOMIC);
if (!tx_buffer)
return -ENOMEM;
- mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet);
- req = (struct ieee802_11_assoc_req *)&(mgmt->payload);
+ mgmt = (struct ieee802_11_mgmt *)&(tx_buffer->packet);
+ req = (struct ieee802_11_assoc_req *)&(mgmt->data);
tlv = req->data;
/* make wireless header */
- mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_ASSOC_REQ);
+ /* no need to care about endianness of constants - is taken care
+ of in ieee802_11.h */
+ mgmt->frame_ctl = IEEE802_11_FTYPE_MGMT|IEEE802_11_STYPE_ASSOC_REQ;
+ if (dev->wep_enabled)
+ mgmt->frame_ctl |= IEEE802_11_FCTL_WEP;
mgmt->duration_id = cpu_to_le16(0x8000);
memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN);
memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
- mgmt->seq_ctl = cpu_to_le16(0);
+ mgmt->seq_ctl = 0;
+
+ req->capability = bss->capa;
- /* we must set the Privacy bit in the capabilities to assure an
+ /* we must set the Privacy bit in the capabilites to assure an
Agere-based AP with optional WEP transmits encrypted frames
to us. AP only set the Privacy bit in their capabilities
if WEP is mandatory in the BSS! */
- req->capability = cpu_to_le16(bss->capa |
- (dev->wep_enabled ? WLAN_CAPABILITY_PRIVACY : 0) |
- (dev->preamble_type == PREAMBLE_TYPE_SHORT ?
- WLAN_CAPABILITY_SHORT_PREAMBLE : 0));
-
+ if (dev->wep_enabled)
+ req->capability |= IEEE802_11_CAPA_PRIVACY;
+ if (dev->preamble_type == PREAMBLE_TYPE_SHORT)
+ req->capability |= IEEE802_11_CAPA_SHORT_PREAMBLE;
+
req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
/* write TLV data elements */
- *tlv++ = MFIE_TYPE_SSID;
+ *tlv++ = IE_ID_SSID;
*tlv++ = bss->ssid_len;
- memcpy(tlv, bss->ssid, bss->ssid_len);
+ memcpy(tlv,bss->ssid, bss->ssid_len);
tlv += bss->ssid_len;
- *tlv++ = MFIE_TYPE_RATES;
+ *tlv++ = IE_ID_SUPPORTED_RATES;
*tlv++ = sizeof(hw_rates);
memcpy(tlv, hw_rates, sizeof(hw_rates));
tlv += sizeof(hw_rates); /* tlv points behind the supp_rates field */
@@ -2457,17 +1353,18 @@ static int assoc_req(struct at76c503 *dev, struct bss_info *bss)
{
/* output buffer for ssid and rates */
- char orates[4*2+1];
+ char ossid[IW_ESSID_MAX_SIZE+1] __attribute__ ((unused));
+ char orates[4*2+1] __attribute__ ((unused));
int len;
tlv = req->data;
- len = min(IW_ESSID_MAX_SIZE, (int)*(tlv+1));
- memcpy(dev->obuf, tlv+2, len);
- dev->obuf[len] = '\0';
+ len = min(sizeof(ossid)-1,(size_t)*(tlv+1));
+ memcpy(ossid, tlv+2, len);
+ ossid[len] = '\0';
tlv += (1 + 1 + *(tlv+1)); /* points to IE of rates now */
- dbg(DBG_TX_MGMT, "%s: AssocReq bssid %s capa x%04x ssid %s rates %s",
+ dbg("%s: AssocReq bssid %s capa x%04x ssid %s rates %s",
dev->netdev->name, mac2str(mgmt->addr3),
- le16_to_cpu(req->capability), dev->obuf,
+ req->capability, ossid,
hex2str(orates,tlv+2,min((sizeof(orates)-1)/2,(size_t)*(tlv+1)),
'\0'));
}
@@ -2478,61 +1375,64 @@ static int assoc_req(struct at76c503 *dev, struct bss_info *bss)
} /* assoc_req */
-/* we are currently associated to curr_bss and
- want to reassoc to new_bss */
-static int reassoc_req(struct at76c503 *dev, struct bss_info *curr_bss,
- struct bss_info *new_bss)
+/* we are currently associated to dev->bss[curr] and
+ want to reassoc to dev->bss[idx] */
+static
+int reassoc_req(struct at76c503 *dev, int curr, int idx)
{
struct at76c503_tx_buffer *tx_buffer;
- struct ieee80211_hdr_3addr *mgmt;
+ struct ieee802_11_mgmt *mgmt;
struct ieee802_11_reassoc_req *req;
-
+ struct bss_info *bss = dev->bss+idx;
u8 *tlv;
- assert(curr_bss != NULL);
- assert(new_bss != NULL);
- if (curr_bss == NULL || new_bss == NULL)
- return -EFAULT;
+ assert(curr >= 0 && curr < dev->bss_nr);
+ assert(idx >= 0 && idx < dev->bss_nr);
- tx_buffer = kmalloc(REASSOCREQ_MAX_SIZE + MAX_PADDING_SIZE,
- GFP_ATOMIC);
+ tx_buffer = kmalloc(REASSOCREQ_MAX_SIZE, GFP_ATOMIC);
if (!tx_buffer)
return -ENOMEM;
- mgmt = (struct ieee80211_hdr_3addr *)&(tx_buffer->packet);
- req = (struct ieee802_11_reassoc_req *)&(mgmt->payload);
+ mgmt = (struct ieee802_11_mgmt *)&(tx_buffer->packet);
+ req = (struct ieee802_11_reassoc_req *)&(mgmt->data);
tlv = req->data;
/* make wireless header */
+ /* no need to care about endianness of constants - is taken care
+ of in ieee802_11.h */
/* jal: encrypt this packet if wep_enabled is TRUE ??? */
- mgmt->frame_ctl = cpu_to_le16(IEEE80211_FTYPE_MGMT|IEEE80211_STYPE_REASSOC_REQ);
+ mgmt->frame_ctl = IEEE802_11_FTYPE_MGMT|IEEE802_11_STYPE_REASSOC_REQ;
+ if (dev->wep_enabled)
+ mgmt->frame_ctl |= IEEE802_11_FCTL_WEP;
mgmt->duration_id = cpu_to_le16(0x8000);
- memcpy(mgmt->addr1, new_bss->bssid, ETH_ALEN);
+ memcpy(mgmt->addr1, bss->bssid, ETH_ALEN);
memcpy(mgmt->addr2, dev->netdev->dev_addr, ETH_ALEN);
- memcpy(mgmt->addr3, new_bss->bssid, ETH_ALEN);
- mgmt->seq_ctl = cpu_to_le16(0);
+ memcpy(mgmt->addr3, bss->bssid, ETH_ALEN);
+ mgmt->seq_ctl = 0;
+
+ req->capability = bss->capa;
- /* we must set the Privacy bit in the capabilities to assure an
+ /* we must set the Privacy bit in the capabilites to assure an
Agere-based AP with optional WEP transmits encrypted frames
to us. AP only set the Privacy bit in their capabilities
if WEP is mandatory in the BSS! */
- req->capability = cpu_to_le16(new_bss->capa |
- (dev->wep_enabled ? WLAN_CAPABILITY_PRIVACY : 0) |
- (dev->preamble_type == PREAMBLE_TYPE_SHORT ?
- WLAN_CAPABILITY_SHORT_PREAMBLE : 0));
-
- req->listen_interval = cpu_to_le16(2 * new_bss->beacon_interval);
+ if (dev->wep_enabled)
+ req->capability |= IEEE802_11_CAPA_PRIVACY;
+ if (dev->preamble_type == PREAMBLE_TYPE_SHORT)
+ req->capability |= IEEE802_11_CAPA_SHORT_PREAMBLE;
+
+ req->listen_interval = cpu_to_le16(2 * bss->beacon_interval);
- memcpy(req->curr_ap, curr_bss->bssid, ETH_ALEN);
+ memcpy(req->curr_ap, dev->bss[curr].bssid, ETH_ALEN);
/* write TLV data elements */
- *tlv++ = MFIE_TYPE_SSID;
- *tlv++ = new_bss->ssid_len;
- memcpy(tlv,new_bss->ssid, new_bss->ssid_len);
- tlv += new_bss->ssid_len;
+ *tlv++ = IE_ID_SSID;
+ *tlv++ = bss->ssid_len;
+ memcpy(tlv,bss->ssid, bss->ssid_len);
+ tlv += bss->ssid_len;
- *tlv++ = MFIE_TYPE_RATES;
+ *tlv++ = IE_ID_SUPPORTED_RATES;
*tlv++ = sizeof(hw_rates);
memcpy(tlv, hw_rates, sizeof(hw_rates));
tlv += sizeof(hw_rates); /* tlv points behind the supp_rates field */
@@ -2541,17 +1441,18 @@ static int reassoc_req(struct at76c503 *dev, struct bss_info *curr_bss,
tx_buffer->wlength = cpu_to_le16(tlv-(u8 *)mgmt);
{
- /* output buffer for rates and bssid */
- char orates[4*2+1];
- char ocurr[6*3+1];
+ /* output buffer for ssid and rates */
+ char ossid[IW_ESSID_MAX_SIZE+1] __attribute__ ((unused));
+ char orates[4*2+1] __attribute__ ((unused));
+ char ocurr[6*3+1] __attribute__ ((unused));
tlv = req->data;
- memcpy(dev->obuf, tlv+2, min(sizeof(dev->obuf),(size_t)*(tlv+1)));
- dev->obuf[IW_ESSID_MAX_SIZE] = '\0';
+ memcpy(ossid, tlv+2, min(sizeof(ossid),(size_t)*(tlv+1)));
+ ossid[sizeof(ossid)-1] = '\0';
tlv += (1 + 1 + *(tlv+1)); /* points to IE of rates now */
- dbg(DBG_TX_MGMT, "%s: ReAssocReq curr %s new %s capa x%04x ssid %s rates %s",
+ dbg("%s: ReAssocReq curr %s new %s capa x%04x ssid %s rates %s",
dev->netdev->name,
hex2str(ocurr, req->curr_ap, ETH_ALEN, ':'),
- mac2str(mgmt->addr3), le16_to_cpu(req->capability), dev->obuf,
+ mac2str(mgmt->addr3), req->capability, ossid,
hex2str(orates,tlv+2,min((sizeof(orates)-1)/2,(size_t)*(tlv+1)),
'\0'));
}
@@ -2567,26 +1468,24 @@ static int reassoc_req(struct at76c503 *dev, struct bss_info *curr_bss,
static void defer_kevent (struct at76c503 *dev, int flag)
{
set_bit (flag, &dev->kevent_flags);
- if (!schedule_work (&dev->kevent))
- dbg(DBG_KEVENT, "%s: kevent %d may have been dropped",
+ if (!schedule_task (&dev->kevent))
+ err ("%s: kevent %d may have been dropped",
dev->netdev->name, flag);
else
- dbg(DBG_KEVENT, "%s: kevent %d scheduled",
- dev->netdev->name, flag);
+ dbg ("%s: kevent %d scheduled", dev->netdev->name, flag);
}
-static void kevent(struct work_struct *work)
+static void
+kevent(void *data)
{
- struct at76c503 *dev = container_of(work, struct at76c503, kevent);
+ struct at76c503 *dev = data;
int ret;
- unsigned long flags;
/* on errors, bits aren't cleared, but no reschedule
is done. So work will be done next time something
else has to be done. This is ugly. TODO! (oku) */
- dbg(DBG_KEVENT, "%s: kevent entry flags: 0x%lx", dev->netdev->name,
- dev->kevent_flags);
+ dbg("%s: kevent flags=x%x", dev->netdev->name, dev->kevent_flags);
down(&dev->sem);
@@ -2599,12 +1498,13 @@ static void kevent(struct work_struct *work)
err("usb_clear_halt() failed: %d", ret);
else{
clear_bit(KEVENT_CTRL_HALT, &dev->kevent_flags);
- info("usb_clear_halt() successful");
+ info("usb_clear_halt() succesful");
}
}
if(test_bit(KEVENT_NEW_BSS, &dev->kevent_flags)){
struct net_device *netdev = dev->netdev;
struct mib_mac_mgmt *mac_mgmt = kmalloc(sizeof(struct mib_mac_mgmt), GFP_KERNEL);
+ struct set_mib_buffer mib_buf;
ret = get_mib(dev->udev, MIB_MAC_MGMT, (u8*)mac_mgmt,
sizeof(struct mib_mac_mgmt));
@@ -2612,392 +1512,142 @@ static void kevent(struct work_struct *work)
err("%s: get_mib failed: %d", netdev->name, ret);
goto new_bss_clean;
}
+ // usb_debug_data(__FUNCTION__, (unsigned char *)mac_mgmt, sizeof(struct mib_mac_mgmt));
+
- dbg(DBG_PROGRESS, "ibss_change = 0x%2x", mac_mgmt->ibss_change);
+ dbg("ibss_change = 0x%2x", mac_mgmt->ibss_change);
memcpy(dev->bssid, mac_mgmt->current_bssid, ETH_ALEN);
- dbg(DBG_PROGRESS, "using BSSID %s", mac2str(dev->bssid));
+ info("using BSSID %s", mac2str(dev->bssid));
- iwevent_bss_connect(dev->netdev, dev->bssid);
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_MGMT;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = IBSS_CHANGE_OK_OFFSET;
- ret = set_mib(dev, &dev->mib_buf);
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC_MGMT;
+ mib_buf.size = 1;
+ mib_buf.index = IBSS_CHANGE_OK_OFFSET;
+ ret = set_mib(dev->udev, &mib_buf);
if(ret < 0){
err("%s: set_mib (ibss change ok) failed: %d", netdev->name, ret);
goto new_bss_clean;
}
+
+ wait_completion(dev, CMD_SET_MIB);
+
clear_bit(KEVENT_NEW_BSS, &dev->kevent_flags);
new_bss_clean:
kfree(mac_mgmt);
}
-
if(test_bit(KEVENT_SET_PROMISC, &dev->kevent_flags)){
info("%s: KEVENT_SET_PROMISC", dev->netdev->name);
set_promisc(dev, dev->promisc);
+ wait_completion(dev, CMD_SET_MIB);
clear_bit(KEVENT_SET_PROMISC, &dev->kevent_flags);
}
- /* check this _before_ KEVENT_JOIN, 'cause _JOIN sets _STARTIBSS bit */
- if (test_bit(KEVENT_STARTIBSS, &dev->kevent_flags)) {
- clear_bit(KEVENT_STARTIBSS, &dev->kevent_flags);
- LOCK_ISTATE()
- assert(dev->istate == STARTIBSS);
- UNLOCK_ISTATE()
- ret = start_ibss(dev);
- if(ret < 0){
- err("%s: start_ibss failed: %d", dev->netdev->name, ret);
- goto end_startibss;
- }
-
- ret = wait_completion(dev, CMD_START_IBSS);
- if (ret != CMD_STATUS_COMPLETE) {
- err("%s start_ibss failed to complete,%d",
- dev->netdev->name, ret);
- goto end_startibss;
- }
-
- ret = get_current_bssid(dev);
- if(ret < 0) goto end_startibss;
-
- ret = get_current_channel(dev);
- if(ret < 0) goto end_startibss;
-
- /* not sure what this is good for ??? */
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_MGMT;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = IBSS_CHANGE_OK_OFFSET;
- ret = set_mib(dev, &dev->mib_buf);
- if(ret < 0){
- err("%s: set_mib (ibss change ok) failed: %d", dev->netdev->name, ret);
- goto end_startibss;
- }
-
- netif_carrier_on(dev->netdev);
- netif_start_queue(dev->netdev);
- }
-end_startibss:
-
- /* check this _before_ KEVENT_SCAN, 'cause _SCAN sets _JOIN bit */
- if (test_bit(KEVENT_JOIN, &dev->kevent_flags)) {
- clear_bit(KEVENT_JOIN, &dev->kevent_flags);
- LOCK_ISTATE()
- if (dev->istate == INIT){
- UNLOCK_ISTATE()
- goto end_join;
- }
- assert(dev->istate == JOINING);
- UNLOCK_ISTATE()
- /* dev->curr_bss == NULL signals a new round,
- starting with list_entry(dev->bss_list.next, ...) */
-
- /* secure the access to dev->curr_bss ! */
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
- dev->curr_bss=find_matching_bss(dev, dev->curr_bss);
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
-
- if (dev->curr_bss != NULL) {
- if ((ret=join_bss(dev,dev->curr_bss)) < 0) {
- err("%s: join_bss failed with %d",
- dev->netdev->name, ret);
- goto end_join;
- }
-
- ret=wait_completion(dev,CMD_JOIN);
- if (ret != CMD_STATUS_COMPLETE) {
- if (ret != CMD_STATUS_TIME_OUT)
- err("%s join_bss completed with %d",
- dev->netdev->name, ret);
- else
- info("%s join_bss ssid %s timed out",
- dev->netdev->name,
- mac2str(dev->curr_bss->bssid));
-
- /* retry next BSS immediately */
- defer_kevent(dev,KEVENT_JOIN);
- goto end_join;
- }
-
- /* here we have joined the (I)BSS */
- if (dev->iw_mode == IW_MODE_ADHOC) {
- struct bss_info *bptr = dev->curr_bss;
- NEW_STATE(dev,CONNECTED);
- /* get ESSID, BSSID and channel for dev->curr_bss */
- dev->essid_size = bptr->ssid_len;
- memcpy(dev->essid, bptr->ssid, bptr->ssid_len);
- memcpy(dev->bssid, bptr->bssid, ETH_ALEN);
- dev->channel = bptr->channel;
- iwevent_bss_connect(dev->netdev,bptr->bssid);
- netif_carrier_on(dev->netdev);
- netif_start_queue(dev->netdev);
- /* just to be sure */
- del_timer_sync(&dev->mgmt_timer);
- } else {
- /* send auth req */
- NEW_STATE(dev,AUTHENTICATING);
- auth_req(dev, dev->curr_bss, 1, NULL);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
- mod_timer(&dev->mgmt_timer, jiffies+HZ);
- }
- goto end_join;
- } /* if (dev->curr_bss != NULL) */
-
- /* here we haven't found a matching (i)bss ... */
- if (dev->iw_mode == IW_MODE_ADHOC) {
- NEW_STATE(dev,STARTIBSS);
- defer_kevent(dev,KEVENT_STARTIBSS);
- goto end_join;
- }
- /* haven't found a matching BSS in infra mode - try again */
- NEW_STATE(dev,SCANNING);
- defer_kevent(dev, KEVENT_SCAN);
- } /* if (test_bit(KEVENT_JOIN, &dev->kevent_flags)) */
-end_join:
-
if(test_bit(KEVENT_MGMT_TIMEOUT, &dev->kevent_flags)){
clear_bit(KEVENT_MGMT_TIMEOUT, &dev->kevent_flags);
handle_mgmt_timeout(dev);
}
- if (test_bit(KEVENT_SCAN, &dev->kevent_flags)) {
- clear_bit(KEVENT_SCAN, &dev->kevent_flags);
- LOCK_ISTATE()
- assert(dev->istate == SCANNING);
-
- /* only clear the bss list when a scan is actively initiated,
- * otherwise simply rely on bss_list_timeout */
- if( dev->site_survey_state == SITE_SURVEY_IN_PROGRESS)
- free_bss_list(dev);
- UNLOCK_ISTATE()
-
- dev->scan_runs=3;
- if ((ret=start_scan(dev, 0, 1)) < 0) {
- err("%s: %s: start_scan failed with %d",
- dev->netdev->name, __FUNCTION__, ret);
- } else {
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",
- __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);
- mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);
- }
-
- } /* if (test_bit(KEVENT_SCAN, &dev->kevent_flags)) */
-
-
- if (test_bit(KEVENT_SUBMIT_RX, &dev->kevent_flags)) {
- clear_bit(KEVENT_SUBMIT_RX, &dev->kevent_flags);
- submit_rx_urb(dev);
- }
-
-
- if (test_bit(KEVENT_RESTART, &dev->kevent_flags)) {
- clear_bit(KEVENT_RESTART, &dev->kevent_flags);
- LOCK_ISTATE()
- assert(dev->istate == INIT);
- UNLOCK_ISTATE()
- startup_device(dev);
-
- /* call it here for default_iw_mode == IW_MODE_MONITOR and
- no subsequent "iwconfig wlanX mode monitor" or
- "iwpriv wlanX monitor 1|2 C" to set dev->netdev->type
- correctly */
- set_monitor_mode(dev, dev->monitor_prism_header);
-
-
- netif_carrier_off(dev->netdev); /* disable running netdev watchdog */
- netif_stop_queue(dev->netdev); /* stop tx data packets */
- if (dev->iw_mode != IW_MODE_MONITOR) {
- NEW_STATE(dev,SCANNING);
- defer_kevent(dev,KEVENT_SCAN);
- } else {
- NEW_STATE(dev,MONITORING);
- start_scan(dev,0,0);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer for %d ticks",
- __FUNCTION__, __LINE__, SCAN_POLL_INTERVAL);
- mod_timer(&dev->mgmt_timer, jiffies + SCAN_POLL_INTERVAL);
- }
- }
-
- if (test_bit(KEVENT_ASSOC_DONE, &dev->kevent_flags)) {
- clear_bit(KEVENT_ASSOC_DONE, &dev->kevent_flags);
- LOCK_ISTATE()
- assert(dev->istate == ASSOCIATING ||
- dev->istate == REASSOCIATING);
- UNLOCK_ISTATE()
- if (dev->iw_mode == IW_MODE_INFRA) {
- assert(dev->curr_bss != NULL);
- if (dev->curr_bss != NULL &&
- dev->pm_mode != PM_ACTIVE) {
- /* calc the listen interval in units of
- beacon intervals of the curr_bss */
- dev->pm_period_beacon = (dev->pm_period_us >> 10) /
- dev->curr_bss->beacon_interval;
-
-#ifdef DEBUG /* only to check if we need to set the listen interval here
- or could do it in the (re)assoc_req parameter */
- dump_mib_mac(dev);
-#endif
-
- if (dev->pm_period_beacon < 2)
- dev->pm_period_beacon = 2;
- else
- if ( dev->pm_period_beacon > 0xffff)
- dev->pm_period_beacon = 0xffff;
-
- dbg(DBG_PM, "%s: pm_mode %d assoc id x%x listen int %d",
- dev->netdev->name, dev->pm_mode,
- dev->curr_bss->assoc_id, dev->pm_period_beacon);
-
- set_associd(dev, dev->curr_bss->assoc_id);
- set_listen_interval(dev, (u16)dev->pm_period_beacon);
- set_pm_mode(dev, dev->pm_mode);
-#ifdef DEBUG
- dump_mib_mac(dev);
- dump_mib_mac_mgmt(dev);
-#endif
+ if (test_bit(KEVENT_SCANJOIN, &dev->kevent_flags)) {
+ clear_bit(KEVENT_SCANJOIN, &dev->kevent_flags);
+ if (dev->istate == SCANNING) {
+ if ((ret=start_scan(dev)) < 0)
+ err("%s: start_scan failed with %d",
+ dev->netdev->name, ret);
+ else {
+ if ((ret=wait_completion(dev,CMD_SCAN)) !=
+ CMD_STATUS_COMPLETE) {
+ err("%s start_scan completed with %d",
+ dev->netdev->name, ret);
+ }
}
- }
-
- netif_carrier_on(dev->netdev);
- netif_wake_queue(dev->netdev); /* _start_queue ??? */
- NEW_STATE(dev,CONNECTED);
- iwevent_bss_connect(dev->netdev,dev->curr_bss->bssid);
- dbg(DBG_PROGRESS, "%s: connected to BSSID %s",
- dev->netdev->name, mac2str(dev->curr_bss->bssid));
- }
-
-
- if (test_bit(KEVENT_RESET_DEVICE, &dev->kevent_flags)) {
-
- clear_bit(KEVENT_RESET_DEVICE, &dev->kevent_flags);
-
- dbg(DBG_DEVSTART, "resetting the device");
-
- usb_reset_device(dev->udev);
-
-/* with 2.6.8 the reset above will cause a disconnect as the USB subsys
- recognizes the change in the config descriptors. Subsequently the device
- will be registered again. */
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,8)
-
- //jal: patch the state (patch by Dmitri)
- dev->udev->state = USB_STATE_CONFIGURED;
-
- /* jal: currently (2.6.0-test2 and 2.4.23)
- usb_reset_device() does not recognize that
- the interface descr. are changed.
- This procedure reads the configuration and does a limited parsing of
- the interface and endpoint descriptors */
- update_usb_intf_descr(dev);
-
- /* continue immediately with external fw download */
- set_bit (KEVENT_EXTERNAL_FW, &dev->kevent_flags);
-#else
- /* kernel >= 2.6.8 */
- NEW_STATE(dev, WAIT_FOR_DISCONNECT);
-#endif
- }
-
- if (test_bit(KEVENT_EXTERNAL_FW, &dev->kevent_flags)) {
- u8 op_mode;
-
- clear_bit(KEVENT_EXTERNAL_FW, &dev->kevent_flags);
-
- op_mode = get_op_mode(dev->udev);
- dbg(DBG_DEVSTART, "opmode %d", op_mode);
-
- if (op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
- err("unexpected opmode %d", op_mode);
- goto end_external_fw;
- }
-
- if (dev->extfw && dev->extfw_size) {
- ret = download_external_fw(dev->udev, dev->extfw,
- dev->extfw_size);
- if (ret < 0) {
- err("Downloading external firmware failed: %d", ret);
- goto end_external_fw;
+ /* if start_scan failed above, the bss table is empty ... */
+ dump_bss_table(dev);
+ if ((dev->curr_bss=find_matching_bss(dev,0)) >= 0) {
+ NEW_STATE(dev,JOINING);
+ /* call join_bss immediately after
+ re-schedule in kevent */
+ defer_kevent(dev,KEVENT_SCANJOIN);
+ } else {
+ /* haven't found a matching BSS -
+ use timer to try again in 10 seconds */
+ mod_timer(&dev->mgmt_timer,jiffies+RESCAN_TIME*HZ);
}
- if (dev->board_type == BOARDTYPE_505A_RFMD_2958) {
- info("200 ms delay for board type 7");
- /* jal: can I do this in kevent ??? */
- set_current_state(TASK_INTERRUPTIBLE);
- schedule_timeout(HZ/5+1);
+ } else {
+ assert(dev->istate == JOINING);
+ assert(dev->curr_bss >= 0 &&
+ dev->curr_bss < dev->bss_nr);
+ if ((ret=join_bss(dev,dev->curr_bss)) < 0)
+ err("%s: join_bss failed with %d",
+ dev->netdev->name, ret);
+ else {
+ ret=wait_completion(dev,CMD_JOIN);
+ if (ret != CMD_STATUS_COMPLETE) {
+ if (ret != CMD_STATUS_TIME_OUT)
+ err("%s join_bss completed with %d",
+ dev->netdev->name, ret);
+ else
+ info("%s join_bss timed out",
+ dev->netdev->name);
+ if ((dev->curr_bss=
+ find_matching_bss(dev,dev->curr_bss+1)) >= 0) {
+ /* try to join the next bss immediately */
+ defer_kevent(dev,KEVENT_SCANJOIN);
+ } else {
+ /* scan again, after 10 seconds */
+ NEW_STATE(dev,SCANNING);
+ mod_timer(&dev->mgmt_timer,jiffies+
+ RESCAN_TIME*HZ);
+ }
+ } else {
+ /* send auth req */
+ NEW_STATE(dev,AUTHENTICATING);
+ auth_req(dev,dev->curr_bss);
+ mod_timer(&dev->mgmt_timer, jiffies+HZ);
+ }
}
}
- NEW_STATE(dev,INIT);
- init_new_device(dev);
- }
-end_external_fw:
-
- if (test_bit(KEVENT_INTERNAL_FW, &dev->kevent_flags)) {
- clear_bit(KEVENT_INTERNAL_FW, &dev->kevent_flags);
-
- dbg(DBG_DEVSTART, "downloading internal firmware");
-
- ret=usbdfu_download(dev->udev, dev->intfw,
- dev->intfw_size,
- dev->board_type == BOARDTYPE_505A_RFMD_2958 ? 2000: 0);
-
- if (ret < 0) {
- err("downloading internal fw failed with %d",ret);
- goto end_internal_fw;
- }
-
- dbg(DBG_DEVSTART, "sending REMAP");
-
- /* no REMAP for 505A (see SF driver) */
- if (dev->board_type != BOARDTYPE_505A_RFMD_2958)
- if ((ret=at76c503_remap(dev->udev)) < 0) {
- err("sending REMAP failed with %d",ret);
- goto end_internal_fw;
- }
-
- dbg(DBG_DEVSTART, "sleeping for 2 seconds");
- NEW_STATE(dev,EXTFW_DOWNLOAD);
- mod_timer(&dev->fw_dl_timer, jiffies+2*HZ+1);
- }
-end_internal_fw:
+ } /* if (test_bit(KEVENT_SCANJOIN, &dev->kevent_flags)) */
up(&dev->sem);
- dbg(DBG_KEVENT, "%s: kevent exit flags: 0x%lx", dev->netdev->name,
- dev->kevent_flags);
-
return;
}
-static int essid_matched(struct at76c503 *dev, struct bss_info *ptr)
+static
+int essid_matched(struct at76c503 *dev, struct bss_info *ptr)
{
- /* common criteria for both modi */
+ u8 zeros[32];
- int retval = (dev->essid_size == 0 /* ANY ssid */ ||
- (dev->essid_size == ptr->ssid_len &&
- !memcmp(dev->essid, ptr->ssid, ptr->ssid_len)));
- if (!retval)
- dbg(DBG_BSS_MATCH, "%s bss table entry %p: essid didn't match",
- dev->netdev->name, ptr);
- return retval;
+ memset(zeros, 0, 32);
+
+ if (dev->iw_mode != IW_MODE_ADHOC) {
+ if (ptr->ssid_len == 0)
+ return 1; /* bss cloaked its ssid */
+ if (ptr->ssid_len == 1 && ptr->ssid == '\0')
+ return 1; /* Agere APs cloaking method */
+ if (ptr->ssid_len == dev->essid_size &&
+ !memcmp(ptr->ssid, zeros, ptr->ssid_len))
+ return 1; /* Belkin AP cloaking method */
+ }
+
+ /* common criteria for both modi */
+ return dev->essid_size == 0 ||
+ (dev->essid_size == ptr->ssid_len &&
+ !memcmp(dev->essid, ptr->ssid, ptr->ssid_len));
}
-static inline int mode_matched(struct at76c503 *dev, struct bss_info *ptr)
+static inline
+int mode_matched(struct at76c503 *dev, struct bss_info *ptr)
{
- int retval;
-
if (dev->iw_mode == IW_MODE_ADHOC)
- retval = ptr->capa & WLAN_CAPABILITY_IBSS;
+ return ptr->capa & IEEE802_11_CAPA_IBSS;
else
- retval = ptr->capa & WLAN_CAPABILITY_ESS;
- if (!retval)
- dbg(DBG_BSS_MATCH, "%s bss table entry %p: mode didn't match",
- dev->netdev->name, ptr);
- return retval;
+ return ptr->capa & IEEE802_11_CAPA_ESS;
}
-static int rates_matched(struct at76c503 *dev, struct bss_info *ptr)
+static
+int rates_matched(struct at76c503 *dev, struct bss_info *ptr)
{
int i;
u8 *rate;
@@ -3006,120 +1656,88 @@ static int rates_matched(struct at76c503 *dev, struct bss_info *ptr)
if (*rate & 0x80) {
/* this is a basic rate we have to support
(see IEEE802.11, ch. 7.3.2.2) */
- if (*rate != (0x80|hw_rates[0]) && *rate != (0x80|hw_rates[1]) &&
- *rate != (0x80|hw_rates[2]) && *rate != (0x80|hw_rates[3])) {
- dbg(DBG_BSS_MATCH,
- "%s: bss table entry %p: basic rate %02x not supported",
- dev->netdev->name, ptr, *rate);
+ if (*rate != hw_rates[0] && *rate != hw_rates[1] &&
+ *rate != hw_rates[2] && *rate != hw_rates[3]) {
+ info("%s: bssid %s: basic rate %02x not supported",
+ dev->netdev->name, mac2str(ptr->bssid),*rate);
return 0;
}
}
- /* if we use short preamble, the bss must support it */
- if (dev->preamble_type == PREAMBLE_TYPE_SHORT &&
- !(ptr->capa & WLAN_CAPABILITY_SHORT_PREAMBLE)) {
- dbg(DBG_BSS_MATCH, "%s: %p does not support short preamble",
- dev->netdev->name, ptr);
- return 0;
- } else
- return 1;
+ return 1;
}
-static inline int wep_matched(struct at76c503 *dev, struct bss_info *ptr)
+static inline
+int wep_matched(struct at76c503 *dev, struct bss_info *ptr)
{
if (!dev->wep_enabled &&
- ptr->capa & WLAN_CAPABILITY_PRIVACY) {
+ ptr->capa & IEEE802_11_CAPA_PRIVACY)
/* we have disabled WEP, but the BSS signals privacy */
- dbg(DBG_BSS_MATCH, "%s: bss table entry %p: requires encryption",
- dev->netdev->name, ptr);
return 0;
- }
/* otherwise if the BSS does not signal privacy it may well
- accept encrypted packets from us ... */
+ except encrypted packets from us ... */
return 1;
}
-static inline int bssid_matched(struct at76c503 *dev, struct bss_info *ptr)
-{
- if (!dev->wanted_bssid_valid ||
- !memcmp(ptr->bssid, dev->wanted_bssid, ETH_ALEN)) {
- return 1;
- } else {
- if (at76_debug & DBG_BSS_MATCH) {
- dbg_uc("%s: requested bssid - %s does not match",
- dev->netdev->name, mac2str(dev->wanted_bssid));
- dbg_uc(" AP bssid - %s of bss table entry %p",
- mac2str(ptr->bssid), ptr);
- }
- return 0;
- }
-}
-
-static void dump_bss_table(struct at76c503 *dev, int force_output)
+static void dump_bss_table(struct at76c503 *dev)
{
struct bss_info *ptr;
/* hex dump output buffer for debug */
- unsigned long flags;
- struct list_head *lptr;
-
- if ((at76_debug & DBG_BSS_TABLE) || (force_output)) {
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
-
- dbg_uc("%s BSS table (curr=%p, new=%p):", dev->netdev->name,
- dev->curr_bss, dev->new_bss);
-
- list_for_each(lptr, &dev->bss_list) {
- ptr = list_entry(lptr, struct bss_info, list);
- dbg_uc("0x%p: bssid %s channel %d ssid %s (%s)"
- " capa x%04x rates %s rssi %d link %d noise %d",
- ptr, mac2str(ptr->bssid),
- ptr->channel,
- ptr->ssid,
- hex2str(dev->obuf, ptr->ssid,
- min((sizeof(dev->obuf)-1)/2,
- (size_t)ptr->ssid_len),'\0'),
- ptr->capa,
- hex2str(dev->obuf_s, ptr->rates,
- min(sizeof(dev->obuf_s)/3,
- (size_t)ptr->rates_len), ' '),
- ptr->rssi, ptr->link_qual, ptr->noise_level);
- }
+ char hexssid[IW_ESSID_MAX_SIZE*2+1] __attribute__ ((unused));
+ char hexrates[MAX_RATE_LEN*3+1] __attribute__ ((unused));
+ int i;
+ int nr=dev->bss_nr; /* copy it in case the rx callback adds
+ a new BSS */
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
+ dbg("%s BSS table:", dev->netdev->name);
+ for(i=0,ptr=dev->bss; i < nr; i++,ptr++) {
+ dbg("%d.BSS %s channel %d ssid %s (%d:%s)"
+ " capa x%04x rates %s rssi %d link %d noise %d",
+ i, mac2str(ptr->bssid),
+ ptr->channel,
+ ptr->ssid, ptr->ssid_len,
+ hex2str(hexssid,ptr->ssid,ptr->ssid_len,'\0'),
+ le16_to_cpu(ptr->capa),
+ hex2str(hexrates, ptr->rates,
+ ptr->rates_len, ' '),
+ ptr->rssi, ptr->link_qual, ptr->noise_level);
}
}
-/* try to find a matching bss in dev->bss, starting at position start.
- returns the ptr to a matching bss in the list or
- NULL if none found */
-/* last is the last bss tried, last == NULL signals a new round,
- starting with list_entry(dev->bss_list.next, ...) */
-/* this proc must be called inside an acquired dev->bss_list_spinlock
- otherwise the timeout on bss may remove the newly chosen entry ! */
-static struct bss_info *find_matching_bss(struct at76c503 *dev,
- struct bss_info *last)
+/* try to find a matching bss in dev->bss, starting at index start.
+ returns the first index of a matching bss in the array or
+ -1 if none found */
+static int find_matching_bss(struct at76c503 *dev, int start)
{
- struct bss_info *ptr = NULL;
- struct list_head *curr;
+ struct bss_info *ptr;
+ int i, ret;
+ int nr = dev->bss_nr; /* copy it in case the rx callback adds
+ a new BSS */
+ char hexssid[IW_ESSID_MAX_SIZE*2+1] __attribute__ ((unused));
+ char ossid[IW_ESSID_MAX_SIZE+1];
- curr = last != NULL ? last->list.next : dev->bss_list.next;
- while (curr != &dev->bss_list) {
- ptr = list_entry(curr, struct bss_info, list);
+ for(i=start, ptr = dev->bss + start; i < nr; i++, ptr++) {
if (essid_matched(dev,ptr) &&
mode_matched(dev,ptr) &&
wep_matched(dev,ptr) &&
- rates_matched(dev,ptr) &&
- bssid_matched(dev,ptr))
+ rates_matched(dev,ptr))
break;
- curr = curr->next;
}
- if (curr == &dev->bss_list)
- ptr = NULL;
- /* otherwise ptr points to the struct bss_info we have chosen */
+ ret = i < nr ? i : -1;
+
+ /* make dev->essid printable */
+ assert(dev->essid_size <= IW_ESSID_MAX_SIZE);
+ memcpy(ossid, dev->essid, dev->essid_size);
+ ossid[dev->essid_size] = '\0';
+
+ dbg("%s " __FUNCTION__ ": try to match ssid %s (%s) mode %s wep %s, start at %d,"
+ " return %d",
+ dev->netdev->name, ossid,
+ hex2str(hexssid,dev->essid,dev->essid_size,'\0'),
+ dev->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
+ dev->wep_enabled ? "enabled" : "disabled", start, ret);
- dbg(DBG_BSS_TABLE, "%s %s: returned %p", dev->netdev->name,
- __FUNCTION__, ptr);
- return ptr;
+ return ret;
} /* find_matching_bss */
@@ -3127,163 +1745,121 @@ static struct bss_info *find_matching_bss(struct at76c503 *dev,
static void rx_mgmt_assoc(struct at76c503 *dev,
struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
+ struct ieee802_11_mgmt *mgmt = (struct ieee802_11_mgmt *)buf->packet;
struct ieee802_11_assoc_resp *resp =
- (struct ieee802_11_assoc_resp *)mgmt->payload;
- u16 assoc_id = le16_to_cpu(resp->assoc_id);
- u16 status = le16_to_cpu(resp->status);
- u16 capa = le16_to_cpu(resp->capability);
- dbg(DBG_RX_MGMT, "%s: rx AssocResp bssid %s capa x%04x status x%04x "
+ (struct ieee802_11_assoc_resp *)mgmt->data;
+ char orates[2*8+1] __attribute__((unused));
+
+ dbg("%s: rx AssocResp bssid %s capa x%04x status x%04x "
"assoc_id x%04x rates %s",
- dev->netdev->name, mac2str(mgmt->addr3), capa, status, assoc_id,
- hex2str(dev->obuf, resp->data+2,
- min((size_t)*(resp->data+1),(sizeof(dev->obuf)-1)/2), '\0'));
- LOCK_ISTATE()
- if (dev->istate == ASSOCIATING) {
- UNLOCK_ISTATE()
- assert(dev->curr_bss != NULL);
- if (dev->curr_bss == NULL)
- return;
+ dev->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->capability), le16_to_cpu(resp->status),
+ le16_to_cpu(resp->assoc_id),
+ hex2str(orates, resp->data+2,
+ min((size_t)*(resp->data+1),(sizeof(orates)-1)/2), '\0'));
- if (status == WLAN_STATUS_SUCCESS) {
- struct bss_info *ptr = dev->curr_bss;
- ptr->assoc_id = assoc_id & 0x3fff;
+ if (dev->istate == ASSOCIATING) {
+ if (resp->status == IEEE802_11_STATUS_SUCCESS) {
+ struct bss_info *ptr = dev->bss+dev->curr_bss;
+ dev->assoc_id = le16_to_cpu(resp->assoc_id);
+ netif_carrier_on(dev->netdev);
+ netif_wake_queue(dev->netdev); /* _start_queue ??? */
+ NEW_STATE(dev,CONNECTED);
+ dbg("%s: connected to BSSID %s",
+ dev->netdev->name, mac2str(dev->bss[dev->curr_bss].bssid));
/* update iwconfig params */
memcpy(dev->bssid, ptr->bssid, ETH_ALEN);
memcpy(dev->essid, ptr->ssid, ptr->ssid_len);
dev->essid_size = ptr->ssid_len;
dev->channel = ptr->channel;
- defer_kevent(dev,KEVENT_ASSOC_DONE);
} else {
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
+ if ((dev->curr_bss=
+ find_matching_bss(dev,dev->curr_bss+1)) >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ }
+ defer_kevent(dev,KEVENT_SCANJOIN);
}
del_timer_sync(&dev->mgmt_timer);
- } else {
- UNLOCK_ISTATE()
+ } else
info("%s: AssocResp in state %d ignored",
dev->netdev->name, dev->istate);
- }
} /* rx_mgmt_assoc */
static void rx_mgmt_reassoc(struct at76c503 *dev,
struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
+ struct ieee802_11_mgmt *mgmt = (struct ieee802_11_mgmt *)buf->packet;
struct ieee802_11_assoc_resp *resp =
- (struct ieee802_11_assoc_resp *)mgmt->payload;
- unsigned long flags;
- u16 capa = le16_to_cpu(resp->capability);
- u16 status = le16_to_cpu(resp->status);
- u16 assoc_id = le16_to_cpu(resp->assoc_id);
+ (struct ieee802_11_assoc_resp *)mgmt->data;
+ char orates[2*8+1] __attribute__((unused));
- dbg(DBG_RX_MGMT, "%s: rx ReAssocResp bssid %s capa x%04x status x%04x "
+ dbg("%s: rx ReAssocResp bssid %s capa x%04x status x%04x "
"assoc_id x%04x rates %s",
- dev->netdev->name, mac2str(mgmt->addr3), capa, status, assoc_id,
- hex2str(dev->obuf, resp->data+2,
- min((size_t)*(resp->data+1),(sizeof(dev->obuf)-1)/2), '\0'));
- LOCK_ISTATE()
- if (dev->istate == REASSOCIATING) {
- UNLOCK_ISTATE()
- assert(dev->new_bss != NULL);
- if (dev->new_bss == NULL)
- return;
-
- if (status == WLAN_STATUS_SUCCESS) {
- struct bss_info *bptr = dev->new_bss;
- bptr->assoc_id = assoc_id;
- NEW_STATE(dev,CONNECTED);
+ dev->netdev->name, mac2str(mgmt->addr3),
+ le16_to_cpu(resp->capability), le16_to_cpu(resp->status),
+ le16_to_cpu(resp->assoc_id),
+ hex2str(orates, resp->data+2,
+ min((size_t)*(resp->data+1),(sizeof(orates)-1)/2), '\0'));
- iwevent_bss_connect(dev->netdev,bptr->bssid);
-
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
- dev->curr_bss = dev->new_bss;
- dev->new_bss = NULL;
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
-
- /* get ESSID, BSSID and channel for dev->curr_bss */
- dev->essid_size = bptr->ssid_len;
- memcpy(dev->essid, bptr->ssid, bptr->ssid_len);
- memcpy(dev->bssid, bptr->bssid, ETH_ALEN);
- dev->channel = bptr->channel;
- dbg(DBG_PROGRESS, "%s: reassociated to BSSID %s",
- dev->netdev->name, mac2str(dev->bssid));
- defer_kevent(dev, KEVENT_ASSOC_DONE);
+ if (dev->istate == REASSOCIATING) {
+ if (resp->status == IEEE802_11_STATUS_SUCCESS) {
+ dev->assoc_id = le16_to_cpu(resp->assoc_id);
+ NEW_STATE(dev,JOINING);
+ join_bss(dev,dev->curr_bss);
+ mod_timer(&dev->mgmt_timer, jiffies+HZ);
} else {
+ if ((dev->curr_bss=
+ find_matching_bss(dev,dev->curr_bss+1)) >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ }
del_timer_sync(&dev->mgmt_timer);
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
+ defer_kevent(dev,KEVENT_SCANJOIN);
}
- } else {
+ } else
info("%s: ReAssocResp in state %d ignored",
dev->netdev->name, dev->istate);
- UNLOCK_ISTATE()
- }
} /* rx_mgmt_reassoc */
static void rx_mgmt_disassoc(struct at76c503 *dev,
struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
+ struct ieee802_11_mgmt *mgmt = (struct ieee802_11_mgmt *)buf->packet;
struct ieee802_11_disassoc_frame *resp =
- (struct ieee802_11_disassoc_frame *)mgmt->payload;
+ (struct ieee802_11_disassoc_frame *)mgmt->data;
+ char obuf[ETH_ALEN*3+1] __attribute__ ((unused));
- dbg(DBG_RX_MGMT, "%s: rx DisAssoc bssid %s reason x%04x destination %s",
+ dbg("%s: rx DisAssoc bssid %s reason x%04x destination %s",
dev->netdev->name, mac2str(mgmt->addr3),
le16_to_cpu(resp->reason),
- hex2str(dev->obuf, mgmt->addr1,
- min((int)sizeof(dev->obuf)/3, ETH_ALEN), ':'));
- LOCK_ISTATE()
- if (dev->istate == SCANNING || dev->istate == INIT) {
- UNLOCK_ISTATE()
- return;
- }
- UNLOCK_ISTATE()
+ hex2str(obuf, mgmt->addr1, ETH_ALEN, ':'));
- assert(dev->curr_bss != NULL);
- if (dev->curr_bss == NULL)
- return;
- LOCK_ISTATE()
- if (dev->istate == REASSOCIATING) {
- UNLOCK_ISTATE()
- assert(dev->new_bss != NULL);
- if (dev->new_bss == NULL)
- return;
- } else
- UNLOCK_ISTATE()
- if (!memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN) &&
+ if (!memcmp(mgmt->addr3,dev->bss[dev->curr_bss].bssid, ETH_ALEN) &&
(!memcmp(dev->netdev->dev_addr, mgmt->addr1, ETH_ALEN) ||
!memcmp(bc_addr, mgmt->addr1, ETH_ALEN))) {
/* this is a DisAssoc from the BSS we are connected or
trying to connect to, directed to us or broadcasted */
- /* jal: TODO: can the DisAssoc also come from the BSS
- we've sent a ReAssocReq to (i.e. from dev->new_bss) ? */
- LOCK_ISTATE()
+
if (dev->istate == DISASSOCIATING ||
- dev->istate == ASSOCIATING ||
dev->istate == REASSOCIATING ||
dev->istate == CONNECTED ||
dev->istate == JOINING)
{
- if (dev->istate == CONNECTED) {
- UNLOCK_ISTATE()
- netif_carrier_off(dev->netdev);
- netif_stop_queue(dev->netdev);
- iwevent_bss_disconnect(dev->netdev);
- } else UNLOCK_ISTATE()
+ if ((dev->curr_bss=
+ find_matching_bss(dev,dev->curr_bss+1)) >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ }
del_timer_sync(&dev->mgmt_timer);
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
- } else {
-
- /* ignore DisAssoc in states AUTH, ASSOC */
- info("%s: DisAssoc in state %d ignored",
- dev->netdev->name, dev->istate);
- UNLOCK_ISTATE()
- }
+ defer_kevent(dev,KEVENT_SCANJOIN);
+ } else
+ /* ignore DisAssoc in states SCANNING, AUTH, ASSOC */
+ info("%s: DisAssoc in state %d ignored",
+ dev->netdev->name, dev->istate);
}
/* ignore DisAssoc to other STA or from other BSSID */
} /* rx_mgmt_disassoc */
@@ -3291,435 +1867,193 @@ static void rx_mgmt_disassoc(struct at76c503 *dev,
static void rx_mgmt_auth(struct at76c503 *dev,
struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
+ struct ieee802_11_mgmt *mgmt = (struct ieee802_11_mgmt *)buf->packet;
struct ieee802_11_auth_frame *resp =
- (struct ieee802_11_auth_frame *)mgmt->payload;
- int seq_nr = le16_to_cpu(resp->seq_nr);
- int alg = le16_to_cpu(resp->algorithm);
- int status = le16_to_cpu(resp->status);
+ (struct ieee802_11_auth_frame *)mgmt->data;
+ char obuf[ETH_ALEN*3+1] __attribute__ ((unused));
- dbg(DBG_RX_MGMT, "%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
+ dbg("%s: rx AuthFrame bssid %s alg %d seq_nr %d status %d "
"destination %s",
dev->netdev->name, mac2str(mgmt->addr3),
- alg, seq_nr, status,
- hex2str(dev->obuf, mgmt->addr1,
- min((int)sizeof(dev->obuf)/3, ETH_ALEN), ':'));
+ le16_to_cpu(resp->algorithm),
+ le16_to_cpu(resp->seq_nr),
+ le16_to_cpu(resp->status),
+ hex2str(obuf, mgmt->addr1, ETH_ALEN, ':'));
- if (alg == WLAN_AUTH_SHARED_KEY &&
- seq_nr == 2) {
- dbg(DBG_RX_MGMT, "%s: AuthFrame challenge %s ...",
- dev->netdev->name,
- hex2str(dev->obuf, resp->challenge,
- min((int)sizeof(dev->obuf)/3,18), ' '));
- }
- LOCK_ISTATE()
- if (dev->istate != AUTHENTICATING) {
- info("%s: ignored AuthFrame in state %d",
- dev->netdev->name, dev->istate);
- UNLOCK_ISTATE()
+ if (dev->istate != AUTHENTICATING)
return;
- }
- UNLOCK_ISTATE()
- if (dev->auth_mode != alg) {
- info("%s: ignored AuthFrame for alg %d",
- dev->netdev->name, alg);
- return;
- }
-
- assert(dev->curr_bss != NULL);
- if (dev->curr_bss == NULL)
- return;
-
- if (!memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN) &&
+ if (!memcmp(mgmt->addr3,dev->bss[dev->curr_bss].bssid, ETH_ALEN) &&
!memcmp(dev->netdev->dev_addr, mgmt->addr1, ETH_ALEN)) {
/* this is a AuthFrame from the BSS we are connected or
trying to connect to, directed to us */
- if (status != WLAN_STATUS_SUCCESS) {
+ if (resp->status != IEEE802_11_STATUS_SUCCESS) {
+ if ((dev->curr_bss=
+ find_matching_bss(dev,dev->curr_bss+1)) >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ defer_kevent(dev,KEVENT_SCANJOIN);
+ }
del_timer_sync(&dev->mgmt_timer);
- /* try to join next bss */
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
- return;
- }
-
- if (dev->auth_mode == WLAN_AUTH_OPEN ||
- seq_nr == 4) {
+ } else {
dev->retries = ASSOC_RETRIES;
NEW_STATE(dev,ASSOCIATING);
assoc_req(dev, dev->curr_bss);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
mod_timer(&dev->mgmt_timer,jiffies+HZ);
- return;
}
-
- assert(seq_nr == 2);
- auth_req(dev, dev->curr_bss, seq_nr+1, resp->challenge);
- dbg(DBG_MGMT_TIMER, "%s:%d: starting mgmt_timer + HZ",
- __FUNCTION__, __LINE__);
- mod_timer(&dev->mgmt_timer,jiffies+HZ);
}
- /* else: ignore AuthFrames to other recipients */
+ /* else: ignore AuthFrames to other receipients */
} /* rx_mgmt_auth */
static void rx_mgmt_deauth(struct at76c503 *dev,
struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
+ struct ieee802_11_mgmt *mgmt = (struct ieee802_11_mgmt *)buf->packet;
struct ieee802_11_deauth_frame *resp =
- (struct ieee802_11_deauth_frame *)mgmt->payload;
+ (struct ieee802_11_deauth_frame *)mgmt->data;
+ char obuf[ETH_ALEN*3+1] __attribute__ ((unused));
- dbg(DBG_RX_MGMT|DBG_PROGRESS,
- "%s: rx DeAuth bssid %s reason x%04x destination %s",
+ dbg("%s: rx DeAuth bssid %s reason x%04x destination %s",
dev->netdev->name, mac2str(mgmt->addr3),
le16_to_cpu(resp->reason),
- hex2str(dev->obuf, mgmt->addr1,
- min((int)sizeof(dev->obuf)/3,ETH_ALEN), ':'));
- LOCK_ISTATE()
- if (dev->istate == DISASSOCIATING ||
- dev->istate == AUTHENTICATING ||
- dev->istate == ASSOCIATING ||
- dev->istate == REASSOCIATING ||
- dev->istate == CONNECTED) {
- UNLOCK_ISTATE()
- assert(dev->curr_bss != NULL);
- if (dev->curr_bss == NULL)
- return;
+ hex2str(obuf, mgmt->addr1, ETH_ALEN, ':'));
- if (!memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN) &&
+ if (!memcmp(mgmt->addr3,dev->bss[dev->curr_bss].bssid, ETH_ALEN) &&
(!memcmp(dev->netdev->dev_addr, mgmt->addr1, ETH_ALEN) ||
- !memcmp(bc_addr, mgmt->addr1, ETH_ALEN))) {
- /* this is a DeAuth from the BSS we are connected or
- trying to connect to, directed to us or broadcasted */
- LOCK_ISTATE()
- if (dev->istate == CONNECTED) {
- UNLOCK_ISTATE()
- iwevent_bss_disconnect(dev->netdev);
- } else UNLOCK_ISTATE()
- NEW_STATE(dev,JOINING);
- defer_kevent(dev,KEVENT_JOIN);
+ !memcmp(bc_addr, mgmt->addr1, ETH_ALEN))) {
+ /* this is a DeAuth from the BSS we are connected or
+ trying to connect to, directed to us or broadcasted */
+
+ if (dev->istate == DISASSOCIATING ||
+ dev->istate == AUTHENTICATING ||
+ dev->istate == ASSOCIATING ||
+ dev->istate == REASSOCIATING ||
+ dev->istate == CONNECTED ||
+ dev->istate == JOINING)
+ {
+ if ((dev->curr_bss=
+ find_matching_bss(dev,dev->curr_bss+1)) >= 0) {
+ NEW_STATE(dev,JOINING);
+ } else {
+ NEW_STATE(dev,SCANNING);
+ defer_kevent(dev,KEVENT_SCANJOIN);
+ }
del_timer_sync(&dev->mgmt_timer);
- }
- /* ignore DeAuth to other STA or from other BSSID */
- } else {
+ } else
/* ignore DeAuth in states SCANNING */
info("%s: DeAuth in state %d ignored",
dev->netdev->name, dev->istate);
- UNLOCK_ISTATE()
}
+ /* ignore DeAuth to other STA or from other BSSID */
} /* rx_mgmt_deauth */
static void rx_mgmt_beacon(struct at76c503 *dev,
struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
-
- /* beacon content */
+ struct ieee802_11_mgmt *mgmt = (struct ieee802_11_mgmt *)buf->packet;
struct ieee802_11_beacon_data *bdata =
- (struct ieee802_11_beacon_data *)mgmt->payload;
-
- /* length of var length beacon parameters */
- int varpar_len = min(le16_to_cpu(buf->wlength) -
- (int)(IEEE802_11_MGMT_HEADER_SIZE +
- offsetof(struct ieee802_11_beacon_data, data)),
- BEACON_MAX_DATA_LENGTH);
-
- struct list_head *lptr;
- struct bss_info *match; /* entry matching addr3 with its bssid */
- int new_entry = 0;
- int len;
- struct data_element {
- u8 type;
- u8 length;
- u8 data_head;
- } *element;
- int have_ssid = 0;
- int have_rates = 0;
- int have_channel = 0;
- int keep_going = 1;
- unsigned long flags;
-
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
- LOCK_ISTATE()
+ (struct ieee802_11_beacon_data *)mgmt->data;
+ struct bss_info *bss_ptr;
+ u8 *tlv_ptr;
+ int i;
+
if (dev->istate == CONNECTED) {
- UNLOCK_ISTATE()
/* in state CONNECTED we use the mgmt_timer to control
the beacon of the BSS */
- assert(dev->curr_bss != NULL);
- if (dev->curr_bss == NULL)
- goto rx_mgmt_beacon_end;
- if (!memcmp(dev->curr_bss->bssid, mgmt->addr3, ETH_ALEN)) {
+ assert(dev->curr_bss >= 0);
+ assert(dev->curr_bss < dev->bss_nr);
+ bss_ptr = dev->bss+dev->curr_bss;
+ if (!memcmp(bss_ptr->bssid,mgmt->addr3,ETH_ALEN)) {
mod_timer(&dev->mgmt_timer, jiffies+BEACON_TIMEOUT*HZ);
- dev->curr_bss->rssi = buf->rssi;
- dev->beacons_received++;
- goto rx_mgmt_beacon_end;
+ bss_ptr->rssi = buf->rssi;
+ return;
}
- } else
- UNLOCK_ISTATE()
+ }
/* look if we have this BSS already in the list */
- match = NULL;
-
- if (!list_empty(&dev->bss_list)) {
- list_for_each(lptr, &dev->bss_list) {
- struct bss_info *bss_ptr =
- list_entry(lptr, struct bss_info, list);
- if (!memcmp(bss_ptr->bssid, mgmt->addr3, ETH_ALEN)) {
- match = bss_ptr;
- break;
- }
- }
+ for(i=0,bss_ptr=dev->bss; i < dev->bss_nr; i++,bss_ptr++) {
+ if (!memcmp(bss_ptr->bssid,mgmt->addr3,ETH_ALEN))
+ break;
}
- if (match == NULL) {
- /* haven't found the bss in the list */
- if ((match=kmalloc(sizeof(struct bss_info), GFP_ATOMIC)) == NULL) {
- dbg(DBG_BSS_TABLE, "%s: cannot kmalloc new bss info (%zd byte)",
- dev->netdev->name, sizeof(struct bss_info));
- goto rx_mgmt_beacon_end;
- }
- memset(match,0,sizeof(*match));
- new_entry = 1;
- /* append new struct into list */
- list_add_tail(&match->list, &dev->bss_list);
+ if (i >= NR_BSS_INFO) {
+ /* table is full */
+ info("%s: scan bss table overflow",dev->netdev->name);
+ return;
}
-
- /* we either overwrite an existing entry or append a new one
- match points to the entry in both cases */
-
- match->capa = le16_to_cpu(bdata->capability_information);
-
- /* while beacon_interval is not (!) */
- match->beacon_interval = le16_to_cpu(bdata->beacon_interval);
-
- match->rssi = buf->rssi;
- match->link_qual = buf->link_quality;
- match->noise_level = buf->noise_level;
-
- memcpy(match->mac,mgmt->addr2,ETH_ALEN); /* just for info */
- memcpy(match->bssid,mgmt->addr3,ETH_ALEN);
- dbg(DBG_RX_BEACON, "%s: bssid %s", dev->netdev->name,
- mac2str(match->bssid));
-
- element = (struct data_element*)bdata->data;
-
-#define data_end(element) (&(element->data_head) + element->length)
-
- /* This routine steps through the bdata->data array to try and get
- * some useful information about the access point.
- * Currently, this implementation supports receipt of: SSID,
- * supported transfer rates and channel, in any order, with some
- * tolerance for intermittent unknown codes (although this
- * functionality may not be necessary as the useful information will
- * usually arrive in consecutively, but there have been some
- * reports of some of the useful information fields arriving in a
- * different order).
- * It does not support any more IE types although MFIE_TYPE_TIM may
- * be supported (on my AP at least).
- * The bdata->data array is about 1500 bytes long but only ~36 of those
- * bytes are useful, hence the have_ssid etc optimizations. */
-
- while (keep_going &&
- ((int)(data_end(element) - bdata->data) <= varpar_len)) {
-
- switch (element->type) {
-
- case MFIE_TYPE_SSID:
- len = min(IW_ESSID_MAX_SIZE, (int)element->length);
- if (!have_ssid && ((new_entry) ||
- !is_cloaked_ssid(&(element->data_head), len))) {
- /* we copy only if this is a new entry,
- or the incoming SSID is not a cloaked SSID. This
- will protect us from overwriting a real SSID read
- in a ProbeResponse with a cloaked one from a
- following beacon. */
-
- match->ssid_len = len;
- memcpy(match->ssid, &(element->data_head), len);
- match->ssid[len] = '\0'; /* terminate the
- string for
- printing */
- dbg(DBG_RX_BEACON, "%s: SSID - %s",
- dev->netdev->name, match->ssid);
- }
- have_ssid = 1;
- break;
-
- case MFIE_TYPE_RATES:
- if (!have_rates) {
- match->rates_len =
- min((int)sizeof(match->rates),
- (int)element->length);
- memcpy(match->rates, &(element->data_head),
- match->rates_len);
- have_rates = 1;
- dbg(DBG_RX_BEACON,
- "%s: SUPPORTED RATES %s",
- dev->netdev->name,
- hex2str(dev->obuf, &(element->data_head),
- min((sizeof(dev->obuf)-1)/2,
- (size_t)element->length), '\0'));
- }
- break;
-
- case MFIE_TYPE_DS_SET:
- if (!have_channel) {
- match->channel = element->data_head;
- have_channel = 1;
- dbg(DBG_RX_BEACON, "%s: CHANNEL - %d",
- dev->netdev->name, match->channel);
- }
- break;
-
- case MFIE_TYPE_CF_SET:
- case MFIE_TYPE_TIM:
- case MFIE_TYPE_IBSS_SET:
- default:
- {
- dbg(DBG_RX_BEACON, "%s: beacon IE id %d len %d %s",
- dev->netdev->name, element->type, element->length,
- hex2str(dev->obuf,&(element->data_head),
- min((sizeof(dev->obuf)-1)/2,
- (size_t)element->length),'\0'));
- break;
- }
- } /* switch (element->type) */
-
- /* advance to the next 'element' of data */
- element = (struct data_element*)data_end(element);
-
- /* Optimization: after all, the bdata->data array is
- * varpar_len bytes long, whereas we get all of the useful
- * information after only ~36 bytes, this saves us a lot of
- * time (and trouble as the remaining portion of the array
- * could be full of junk)
- * Comment this out if you want to see what other information
- * comes from the AP - although little of it may be useful */
- }
-
- dbg(DBG_RX_BEACON, "%s: Finished processing beacon data",
- dev->netdev->name);
-
- match->last_rx = jiffies; /* record last rx of beacon */
-
-rx_mgmt_beacon_end:
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
-} /* rx_mgmt_beacon */
+ /* we either overwrite an existing entry or append a new one
+ bss_ptr points to the entry in both cases */
+ /* capa is in little endian format (!) */
+ bss_ptr->capa = bdata->capability_information;
-/* calc the link level from a given rx_buffer */
-static void calc_level(struct at76c503 *dev, struct at76c503_rx_buffer *buf, struct iw_quality* qual)
-{ int max_rssi = 42; /* just a gues for now, might be different for other chips */
+ /* while beacon_interval is not (!) */
+ bss_ptr->beacon_interval = le16_to_cpu(bdata->beacon_interval);
- qual->level = (buf->rssi * 100 / max_rssi);
- if (qual->level > 100)
- qual->level = 100;
- qual->updated |= IW_QUAL_LEVEL_UPDATED;
-}
+ bss_ptr->rssi = buf->rssi;
+ bss_ptr->link_qual = buf->link_quality;
+ bss_ptr->noise_level = buf->noise_level;
+ memcpy(bss_ptr->mac,mgmt->addr2,ETH_ALEN); //just for info
+ memcpy(bss_ptr->bssid,mgmt->addr3,ETH_ALEN);
-/* calc the link quality from a given rx_buffer */
-static void calc_qual(struct at76c503 *dev, struct at76c503_rx_buffer *buf, struct iw_quality* qual)
-{
- if((dev->board_type == BOARDTYPE_503_INTERSIL_3861) ||
- (dev->board_type == BOARDTYPE_503_INTERSIL_3863)) {
- qual->qual=buf->link_quality;
- } else {
- qual->qual = qual->level * dev->beacons_received *
- dev->beacon_period /
- (jiffies_to_msecs(jiffies) - dev->beacons_last_qual);
-
- dev->beacons_last_qual = jiffies_to_msecs(jiffies);
- dev->beacons_received = 0;
- }
- qual->qual = (qual->qual > 100) ? 100 : qual->qual;
- qual->updated |= IW_QUAL_QUAL_UPDATED;
-}
+ tlv_ptr = bdata->data;
+ assert(*tlv_ptr == IE_ID_SSID);
+ bss_ptr->ssid_len = min(IW_ESSID_MAX_SIZE,(int)*(tlv_ptr+1));
+ memcpy(bss_ptr->ssid, tlv_ptr+2, bss_ptr->ssid_len);
+ tlv_ptr += (1+1 + *(tlv_ptr+1));
-/* calc the noise quality from a given rx_buffer */
-static void calc_noise(struct at76c503 *dev, struct at76c503_rx_buffer *buf, struct iw_quality* qual)
-{
- qual->noise = 0;
- qual->updated |= IW_QUAL_NOISE_INVALID;
-}
+ assert(*tlv_ptr == IE_ID_SUPPORTED_RATES);
+ bss_ptr->rates_len = min(MAX_RATE_LEN,(int)*(tlv_ptr+1));
+ memcpy(bss_ptr->rates, tlv_ptr+2, bss_ptr->rates_len);
+ tlv_ptr += (1+1 + *(tlv_ptr+1));
+ assert(*tlv_ptr == IE_ID_DS_PARAM_SET);
+ bss_ptr->channel = *(tlv_ptr+2);
-static void update_wstats(struct at76c503 *dev, struct at76c503_rx_buffer *buf)
-{
- struct iw_quality *qual = &dev->wstats.qual;
-
- if (buf->rssi && dev->istate == CONNECTED) {
- qual->updated = 0;
- calc_level(dev, buf, qual);
- calc_qual(dev, buf, qual);
- calc_noise(dev, buf, qual);
- } else {
- qual->qual = 0;
- qual->level = 0;
- qual->noise = 0;
- qual->updated = IW_QUAL_ALL_INVALID;
+ if (i >= dev->bss_nr) {
+ dev->bss_nr++;
}
}
static void rx_mgmt(struct at76c503 *dev, struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *mgmt =
- (struct ieee80211_hdr_3addr *)buf->packet;
- u16 subtype = le16_to_cpu(mgmt->frame_ctl) & IEEE80211_FCTL_STYPE;
-
- /* update wstats */
- LOCK_ISTATE()
- if (dev->istate != INIT && dev->istate != SCANNING) {
- UNLOCK_ISTATE()
- /* jal: this is a dirty hack needed by Tim in ad-hoc mode */
- if (dev->iw_mode == IW_MODE_ADHOC ||
- (dev->curr_bss != NULL &&
- !memcmp(mgmt->addr3, dev->curr_bss->bssid, ETH_ALEN))) {
- /* Data packets always seem to have a 0 link level, so we
- only read link quality info from management packets.
- Atmel driver actually averages the present, and previous
- values, we just present the raw value at the moment - TJS */
-
- update_wstats(dev, buf);
- }
- } else UNLOCK_ISTATE()
-
- if (at76_debug & DBG_RX_MGMT_CONTENT) {
- dbg_uc("%s rx mgmt subtype x%x %s",
- dev->netdev->name, subtype,
- hex2str(dev->obuf, (u8 *)mgmt,
- min((sizeof(dev->obuf)-1)/2,
- (size_t)le16_to_cpu(buf->wlength)), '\0'));
- }
+ struct ieee802_11_mgmt *mgmt = ( struct ieee802_11_mgmt *)buf->packet;
+ u16 subtype = mgmt->frame_ctl & IEEE802_11_FCTL_STYPE;
+
+#if 0
+ char obuf[128*2+1] __attribute__ ((unused));
+ dbg("%s rx mgmt subtype x%x %s", dev->netdev->name, subtype,
+ hex2str(obuf, (u8 *)mgmt,
+ min((sizeof(obuf)-1)/2,
+ (size_t)le16_to_cpu(buf->wlength)), '\0'));
+#endif
switch (subtype) {
- case IEEE80211_STYPE_BEACON:
- case IEEE80211_STYPE_PROBE_RESP:
+ case IEEE802_11_STYPE_BEACON:
+ case IEEE802_11_STYPE_PROBE_RESP:
rx_mgmt_beacon(dev,buf);
break;
- case IEEE80211_STYPE_ASSOC_RESP:
+ case IEEE802_11_STYPE_ASSOC_RESP:
rx_mgmt_assoc(dev,buf);
break;
- case IEEE80211_STYPE_REASSOC_RESP:
+ case IEEE802_11_STYPE_REASSOC_RESP:
rx_mgmt_reassoc(dev,buf);
break;
- case IEEE80211_STYPE_DISASSOC:
+ case IEEE802_11_STYPE_DISASSOC:
rx_mgmt_disassoc(dev,buf);
break;
- case IEEE80211_STYPE_AUTH:
+ case IEEE802_11_STYPE_AUTH:
rx_mgmt_auth(dev,buf);
break;
- case IEEE80211_STYPE_DEAUTH:
+ case IEEE802_11_STYPE_DEAUTH:
rx_mgmt_deauth(dev,buf);
break;
@@ -3731,551 +2065,76 @@ static void rx_mgmt(struct at76c503 *dev, struct at76c503_rx_buffer *buf)
return;
}
-static void dbg_dumpbuf(const char *tag, const u8 *buf, int size)
+/* shamelessly copied from orinoco.c */
+static inline int
+is_snap(struct header_struct *hdr)
{
- int i;
-
- if (!at76_debug) return;
-
- for (i=0; i<size; i++) {
- if ((i % 8) == 0) {
- if (i) printk("\n");
- printk(KERN_DEBUG __FILE__ ": %s: ", tag);
- }
- printk("%02x ", buf[i]);
- }
- printk("\n");
+ return (hdr->dsap == 0xaa) && (hdr->ssap == 0xaa) && (hdr->ctrl == 0x03);
}
-/* A short overview on Ethernet-II, 802.2, 802.3 and SNAP
- (taken from http://www.geocities.com/billalexander/ethernet.html):
-
-Ethernet Frame Formats:
-
-Ethernet (a.k.a. Ethernet II)
-
- +---------+---------+---------+----------
- | Dst | Src | Type | Data...
- +---------+---------+---------+----------
-
- <-- 6 --> <-- 6 --> <-- 2 --> <-46-1500->
-
- Type 0x80 0x00 = TCP/IP
- Type 0x06 0x00 = XNS
- Type 0x81 0x37 = Novell NetWare
-
-
-802.3
-
- +---------+---------+---------+----------
- | Dst | Src | Length | Data...
- +---------+---------+---------+----------
-
- <-- 6 --> <-- 6 --> <-- 2 --> <-46-1500->
-
-802.2 (802.3 with 802.2 header)
-
- +---------+---------+---------+-------+-------+-------+----------
- | Dst | Src | Length | DSAP | SSAP |Control| Data...
- +---------+---------+---------+-------+-------+-------+----------
-
- <- 1 -> <- 1 -> <- 1 -> <-43-1497->
-
-SNAP (802.3 with 802.2 and SNAP headers)
-
- +---------+---------+---------+-------+-------+-------+-----------+---------+-----------
- | Dst | Src | Length | 0xAA | 0xAA | 0x03 | Org Code | Type | Data...
- +---------+---------+---------+-------+-------+-------+-----------+---------+-----------
-
- <-- 3 --> <-- 2 --> <-38-1492->
-
-*/
-
-/* Convert the 802.11 header on a packet into an ethernet-style header
- * (basically, pretend we're an ethernet card receiving ethernet packets)
- *
- * This routine returns with the skbuff pointing to the actual data (just past
- * the end of the newly-created ethernet header).
- */
-static void ieee80211_to_eth(struct sk_buff *skb, int iw_mode)
+static void rx_data(struct at76c503 *dev, struct at76c503_rx_buffer *buf)
{
- struct ieee80211_hdr_3addr *i802_11_hdr;
- struct ethhdr *eth_hdr_p;
- u8 *src_addr;
- u8 *dest_addr;
- __be16 proto = 0;
- int build_ethhdr = 1;
-
- i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
-
-#ifdef DEBUG
- {
- dbg_uc("%s: ENTRY skb len %d data %s", __FUNCTION__,
- skb->len, hex2str(dev->obuf, skb->data,
- min((int)sizeof(dev->obuf)/3,64), ' '));
- }
-#endif
-
- skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
-
- src_addr = iw_mode == IW_MODE_ADHOC ? i802_11_hdr->addr2
- : i802_11_hdr->addr3;
- dest_addr = i802_11_hdr->addr1;
-
- eth_hdr_p = (struct ethhdr *)skb->data;
- if (!memcmp(eth_hdr_p->h_source, src_addr, ETH_ALEN) &&
- !memcmp(eth_hdr_p->h_dest, dest_addr, ETH_ALEN)) {
- /* An ethernet frame is encapsulated within the data portion.
- * Just use its header instead. */
- skb_pull(skb, sizeof(struct ethhdr));
- build_ethhdr = 0;
- } else if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
- /* SNAP frame - collapse it */
- skb_pull(skb, sizeof(rfc1042sig)+2);
- proto = *(__be16 *)(skb->data - 2);
- } else {
-#ifdef IEEE_STANDARD
- /* According to all standards, we should assume the data
- * portion contains 802.2 LLC information, so we should give it
- * an 802.3 header (which has the same implications) */
- proto = htons(skb->len);
-#else /* IEEE_STANDARD */
- /* Unfortunately, it appears no actual 802.11 implementations
- * follow any standards specs. They all appear to put a
- * 16-bit ethertype after the 802.11 header instead, so we take
- * that value and make it into an Ethernet-II packet. */
- /* Note that this means we can never support non-SNAP 802.2
- * frames (because we can't tell when we get one) */
-
- /* jal: This isn't true. My WRT54G happily sends SNAP.
- Difficult to speak for all APs, so I don't dare to define
- IEEE_STANDARD ... */
- proto = *(__be16 *)(skb->data);
- skb_pull(skb, 2);
-#endif /* IEEE_STANDARD */
- }
-
- eth_hdr_p = (struct ethhdr *)(skb->data-sizeof(struct ethhdr));
- set_eth_hdr(skb, eth_hdr_p);
- if (build_ethhdr) {
- /* This needs to be done in this order (eth_hdr_p->h_dest may
- * overlap src_addr) */
- memcpy(eth_hdr_p->h_source, src_addr, ETH_ALEN);
- memcpy(eth_hdr_p->h_dest, dest_addr, ETH_ALEN);
- /* make an 802.3 header (proto = length) */
- eth_hdr_p->h_proto = proto;
- }
-
- if (ntohs(eth_hdr_p->h_proto) > 1518) {
- skb->protocol = eth_hdr_p->h_proto;
- } else if (*(unsigned short *)skb->data == 0xFFFF) {
- /* Magic hack for Novell IPX-in-802.3 packets */
- skb->protocol = htons(ETH_P_802_3);
- } else {
- /* Assume it's an 802.2 packet (it should be, and we have no
- * good way to tell if it isn't) */
- skb->protocol = htons(ETH_P_802_2);
- }
-
-#ifdef DEBUG
- {
- char da[3*ETH_ALEN], sa[3*ETH_ALEN];
- dbg_uc("%s: EXIT skb da %s sa %s proto x%04x len %d data %s", __FUNCTION__,
- hex2str(da, eth_hdr(skb)->h_dest, ETH_ALEN, ':'),
- hex2str(sa, eth_hdr(skb)->h_source, ETH_ALEN, ':'),
- ntohs(skb->protocol), skb->len,
- hex2str(dev->obuf, skb->data,
- min((int)sizeof(dev->obuf)/3,64), ' '));
- }
-#endif
-
-}
-
-/* Adjust the skb to trim the hardware header and CRC, and set up skb->mac,
- * skb->protocol, etc.
- */
-static void ieee80211_fixup(struct sk_buff *skb, int iw_mode)
-{
- struct ieee80211_hdr_3addr *i802_11_hdr;
- struct ethhdr *eth_hdr_p;
- u8 *src_addr;
- u8 *dest_addr;
- __be16 proto = 0;
-
- i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
- skb_pull(skb, sizeof(struct ieee80211_hdr_3addr));
-
- src_addr = iw_mode == IW_MODE_ADHOC ? i802_11_hdr->addr2
- : i802_11_hdr->addr3;
- dest_addr = i802_11_hdr->addr1;
-
- skb->mac.raw = (unsigned char *)i802_11_hdr;
-
- eth_hdr_p = (struct ethhdr *)skb->data;
- if (!memcmp(eth_hdr_p->h_source, src_addr, ETH_ALEN) &&
- !memcmp(eth_hdr_p->h_dest, dest_addr, ETH_ALEN)) {
- /* There's an ethernet header encapsulated within the data
- * portion, count it as part of the hardware header */
- skb_pull(skb, sizeof(struct ethhdr));
- proto = eth_hdr_p->h_proto;
- } else if (!memcmp(skb->data, snapsig, sizeof(snapsig))) {
- /* SNAP frame - collapse it */
- /* RFC1042/802.1h encapsulated packet. Treat the SNAP header
- * as part of the HW header and note the protocol. */
- /* NOTE: prism2 doesn't collapse Appletalk frames (why?). */
- skb_pull(skb, sizeof(rfc1042sig) + 2);
- proto = *(__be16 *)(skb->data - 2);
- }
-
- if (ntohs(proto) > 1518) {
- skb->protocol = proto;
- } else {
-#ifdef IEEE_STANDARD
- /* According to all standards, we should assume the data
- * portion contains 802.2 LLC information */
- skb->protocol = htons(ETH_P_802_2);
-#else /* IEEE_STANDARD */
- /* Unfortunately, it appears no actual 802.11 implementations
- * follow any standards specs. They all appear to put a
- * 16-bit ethertype after the 802.11 header instead, so we'll
- * use that (and consider it part of the hardware header). */
- /* Note that this means we can never support non-SNAP 802.2
- * frames (because we can't tell when we get one) */
- skb->protocol = *(__be16 *)skb->data;
- skb_pull(skb, 2);
-#endif /* IEEE_STANDARD */
- }
-}
-
-/* check for fragmented data in dev->rx_skb. If the packet was no fragment
- or it was the last of a fragment set a skb containing the whole packet
- is returned for further processing. Otherwise we get NULL and are
- done and the packet is either stored inside the fragment buffer
- or thrown away. The check for rx_copybreak is moved here.
- Every returned skb starts with the ieee802_11 header and contains
- _no_ FCS at the end */
-static struct sk_buff *check_for_rx_frags(struct at76c503 *dev)
-{
- struct sk_buff *skb = (struct sk_buff *)dev->rx_skb;
- struct at76c503_rx_buffer *buf = (struct at76c503_rx_buffer *)skb->data;
- struct ieee80211_hdr_3addr *i802_11_hdr =
- (struct ieee80211_hdr_3addr *)buf->packet;
- /* seq_ctrl, fragment_number, sequence number of new packet */
- u16 sctl = le16_to_cpu(i802_11_hdr->seq_ctl);
- u16 fragnr = sctl & 0xf;
- u16 seqnr = sctl>>4;
- u16 frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
-
- /* length including the IEEE802.11 header, excl. the trailing FCS,
- excl. the struct at76c503_rx_buffer */
- int length = le16_to_cpu(buf->wlength) - dev->rx_data_fcs_len;
-
- /* where does the data payload start in skb->data ? */
- u8 *data = (u8 *)i802_11_hdr + sizeof(struct ieee80211_hdr_3addr);
-
- /* length of payload, excl. the trailing FCS */
- int data_len = length - (data - (u8 *)i802_11_hdr);
-
- int i;
- struct rx_data_buf *bptr, *optr;
- unsigned long oldest = ~0UL;
-
- dbg(DBG_RX_FRAGS, "%s: rx data frame_ctl %04x addr2 %s seq/frag %d/%d "
- "length %d data %d: %s ...",
- dev->netdev->name, frame_ctl,
- mac2str(i802_11_hdr->addr2),
- seqnr, fragnr, length, data_len,
- hex2str(dev->obuf, data,
- min((int)(sizeof(dev->obuf)-1)/2,32), '\0'));
-
- dbg(DBG_RX_FRAGS_SKB, "%s: incoming skb: head %p data %p "
- "tail %p end %p len %d",
- dev->netdev->name, skb->head, skb->data, skb->tail,
- skb->end, skb->len);
-
- if (data_len <= 0) {
- /* buffers contains no data */
- info("%s: rx skb without data", dev->netdev->name);
- return NULL;
- }
-
- if (fragnr == 0 && !(frame_ctl & IEEE80211_FCTL_MOREFRAGS)) {
- /* unfragmented packet received */
- if (length < rx_copybreak && (skb = dev_alloc_skb(length)) != NULL) {
- memcpy(skb_put(skb, length),
- dev->rx_skb->data + AT76C503_RX_HDRLEN, length);
- } else {
- skb_pull(skb, AT76C503_RX_HDRLEN);
- skb_trim(skb, length);
- /* Use a new skb for the next receive */
- dev->rx_skb = NULL;
- }
-
- dbg(DBG_RX_FRAGS, "%s: unfragmented", dev->netdev->name);
+ struct net_device *netdev = (struct net_device *)dev->netdev;
+ struct net_device_stats *stats = &dev->stats;
+ struct ieee802_11_hdr *i802_11_hdr = (struct ieee802_11_hdr *)buf->packet;
+ struct sk_buff *skb;
+ struct header_struct *hdr_eth = (struct header_struct *)&buf->packet[10];
+ int length, offset;
- return skb;
+ if(is_snap(hdr_eth)){
+ length = le16_to_cpu(buf->wlength) - 18 - 4;
+ offset = 18;
+ }else{
+ info("it's not a snap frame");
+ length = le16_to_cpu(buf->wlength) - 10 - 4;
+ offset = 10;
}
- /* remove the at76c503_rx_buffer header - we don't need it anymore */
- /* we need the IEEE802.11 header (for the addresses) if this packet
- is the first of a chain */
-
- assert(length > AT76C503_RX_HDRLEN);
- skb_pull(skb, AT76C503_RX_HDRLEN);
- /* remove FCS at end */
- skb_trim(skb, length);
-
- dbg(DBG_RX_FRAGS_SKB, "%s: trimmed skb: head %p data %p tail %p "
- "end %p len %d data %p data_len %d",
- dev->netdev->name, skb->head, skb->data, skb->tail,
- skb->end, skb->len, data, data_len);
-
- /* look if we've got a chain for the sender address.
- afterwards optr points to first free or the oldest entry,
- or, if i < NR_RX_DATA_BUF, bptr points to the entry for the
- sender address */
- /* determining the oldest entry doesn't cope with jiffies wrapping
- but I don't care to delete a young entry at these rare moments ... */
-
- for(i=0,bptr=dev->rx_data,optr=NULL; i < NR_RX_DATA_BUF; i++,bptr++) {
- if (bptr->skb != NULL) {
- if (!memcmp(i802_11_hdr->addr2, bptr->sender,ETH_ALEN))
- break;
- else
- if (optr == NULL) {
- optr = bptr;
- oldest = bptr->last_rx;
- } else {
- if (bptr->last_rx < oldest)
- optr = bptr;
- }
- } else {
- optr = bptr;
- oldest = 0UL;
- }
+ /* TODO: submit skb->data directly, this saves the memcpy */
+ skb = dev_alloc_skb(length+2);
+ if(skb == NULL) {
+ err("%s: could not allocate skb for rx\n", netdev->name);
+ stats->rx_dropped++;
+ goto drop;
}
-
- if (i < NR_RX_DATA_BUF) {
-
- dbg(DBG_RX_FRAGS, "%s: %d. cacheentry (seq/frag=%d/%d) "
- "matched sender addr",
- dev->netdev->name, i, bptr->seqnr, bptr->fragnr);
-
- /* bptr points to an entry for the sender address */
- if (bptr->seqnr == seqnr) {
- int left;
- /* the fragment has the current sequence number */
- if (((bptr->fragnr+1)&0xf) == fragnr) {
- bptr->last_rx = jiffies;
- /* the next following fragment number ->
- add the data at the end */
- /* is & 0xf necessary above ??? */
-
- /* for test only ??? */
- if ((left=skb_tailroom(bptr->skb)) < data_len) {
- info("%s: only %d byte free (need %d)",
- dev->netdev->name, left, data_len);
- } else
- memcpy(skb_put(bptr->skb, data_len),
- data, data_len);
- bptr->fragnr = fragnr;
- if (!(frame_ctl &
- IEEE80211_FCTL_MOREFRAGS)) {
- /* this was the last fragment - send it */
- skb = bptr->skb;
- bptr->skb = NULL; /* free the entry */
- dbg(DBG_RX_FRAGS, "%s: last frag of seq %d",
- dev->netdev->name, seqnr);
- return skb;
- } else
- return NULL;
- } else {
- /* wrong fragment number -> ignore it */
- dbg(DBG_RX_FRAGS, "%s: frag nr does not match: %d+1 != %d",
- dev->netdev->name, bptr->fragnr, fragnr);
- return NULL;
- }
- } else {
- /* got another sequence number */
- if (fragnr == 0) {
- /* it's the start of a new chain - replace the
- old one by this */
- /* bptr->sender has the correct value already */
- dbg(DBG_RX_FRAGS, "%s: start of new seq %d, "
- "removing old seq %d", dev->netdev->name,
- seqnr, bptr->seqnr);
- bptr->seqnr = seqnr;
- bptr->fragnr = 0;
- bptr->last_rx = jiffies;
- /* swap bptr->skb and dev->rx_skb */
- skb = bptr->skb;
- bptr->skb = dev->rx_skb;
- dev->rx_skb = skb;
- } else {
- /* it from the middle of a new chain ->
- delete the old entry and skip the new one */
- dbg(DBG_RX_FRAGS, "%s: middle of new seq %d (%d) "
- "removing old seq %d", dev->netdev->name,
- seqnr, fragnr, bptr->seqnr);
- dev_kfree_skb(bptr->skb);
- bptr->skb = NULL;
- }
- return NULL;
- }
- } else {
- /* if we didn't find a chain for the sender address optr
- points either to the first free or the oldest entry */
-
- if (fragnr != 0) {
- /* this is not the begin of a fragment chain ... */
- dbg(DBG_RX_FRAGS, "%s: no chain for non-first fragment (%d)",
- dev->netdev->name, fragnr);
- return NULL;
- }
- assert(optr != NULL);
- if (optr == NULL)
- return NULL;
+ skb_reserve(skb, 2);
- if (optr->skb != NULL) {
- /* swap the skb's */
- skb = optr->skb;
- optr->skb = dev->rx_skb;
- dev->rx_skb = skb;
+ memcpy(skb_put(skb, length), &(buf->packet[offset]), length);
- dbg(DBG_RX_FRAGS, "%s: free old contents: sender %s seq/frag %d/%d",
- dev->netdev->name, mac2str(optr->sender),
- optr->seqnr, optr->fragnr);
+ hdr_eth = (struct header_struct *)skb->data;
- } else {
- /* take the skb from dev->rx_skb */
- optr->skb = dev->rx_skb;
- dev->rx_skb = NULL; /* let submit_rx_urb() allocate a new skb */
-
- dbg(DBG_RX_FRAGS, "%s: use a free entry", dev->netdev->name);
- }
- memcpy(optr->sender, i802_11_hdr->addr2, ETH_ALEN);
- optr->seqnr = seqnr;
- optr->fragnr = 0;
- optr->last_rx = jiffies;
-
- return NULL;
- }
-} /* check_for_rx_frags */
-
-/* rx interrupt: we expect the complete data buffer in dev->rx_skb */
-static void rx_data(struct at76c503 *dev)
-{
- struct net_device *netdev = (struct net_device *)dev->netdev;
- struct net_device_stats *stats = &dev->stats;
- struct sk_buff *skb = dev->rx_skb;
- struct at76c503_rx_buffer *buf = (struct at76c503_rx_buffer *)skb->data;
- struct ieee80211_hdr_3addr *i802_11_hdr;
- int length = le16_to_cpu(buf->wlength);
-
- if (at76_debug & DBG_RX_DATA) {
- dbg_uc("%s received data packet:", netdev->name);
- dbg_dumpbuf(" rxhdr", skb->data, AT76C503_RX_HDRLEN);
+ if(dev->iw_mode == IW_MODE_ADHOC){
+ memcpy(hdr_eth->dest, i802_11_hdr->addr1, ETH_ALEN);
+ memcpy(hdr_eth->src, i802_11_hdr->addr2, ETH_ALEN);
+ }else if(dev->iw_mode == IW_MODE_INFRA){
+ memcpy(hdr_eth->dest, i802_11_hdr->addr1, ETH_ALEN);
+ memcpy(hdr_eth->src, i802_11_hdr->addr3, ETH_ALEN);
}
- if (at76_debug & DBG_RX_DATA_CONTENT)
- dbg_dumpbuf("packet", skb->data + AT76C503_RX_HDRLEN,
- length);
- if ((skb=check_for_rx_frags(dev)) == NULL)
- return;
-
- /* if an skb is returned, the at76c503a_rx_header and the FCS is already removed */
- i802_11_hdr = (struct ieee80211_hdr_3addr *)skb->data;
+#if 0
+ info("rx addr1: %s", mac2str(i802_11_hdr->addr1));
+ info("rx addr2: %s", mac2str(i802_11_hdr->addr2));
+ info("rx addr3: %s", mac2str(i802_11_hdr->addr3));
+#endif
skb->dev = netdev;
- skb->ip_summed = CHECKSUM_NONE; /* TODO: should check CRC */
-
- if (i802_11_hdr->addr1[0] & 1) {
- if (!memcmp(i802_11_hdr->addr1, netdev->broadcast, ETH_ALEN))
- skb->pkt_type = PACKET_BROADCAST;
- else
- skb->pkt_type = PACKET_MULTICAST;
- } else if (memcmp(i802_11_hdr->addr1, netdev->dev_addr, ETH_ALEN)) {
- skb->pkt_type=PACKET_OTHERHOST;
- }
-
- if (netdev->type == ARPHRD_ETHER) {
- ieee80211_to_eth(skb, dev->iw_mode);
- } else {
- ieee80211_fixup(skb, dev->iw_mode);
- }
-
+ skb->protocol = eth_type_trans(skb, netdev);
netdev->last_rx = jiffies;
+ skb->ip_summed = CHECKSUM_NONE;
netif_rx(skb);
stats->rx_packets++;
stats->rx_bytes += length;
+ drop:
return;
}
-static int submit_rx_urb(struct at76c503 *dev)
-{
- int ret, size;
- struct sk_buff *skb = dev->rx_skb;
-
- if (dev->read_urb == NULL) {
- err("%s: dev->read_urb is NULL", __FUNCTION__);
- return -EFAULT;
- }
-
- if (skb == NULL) {
- skb = dev_alloc_skb(sizeof(struct at76c503_rx_buffer));
- if (skb == NULL) {
- err("%s: unable to allocate rx skbuff.", dev->netdev->name);
- ret = -ENOMEM;
- goto exit;
- }
- dev->rx_skb = skb;
- } else {
- skb_push(skb, skb_headroom(skb));
- skb_trim(skb, 0);
- }
-
- size = skb_tailroom(skb);
- FILL_BULK_URB(dev->read_urb, dev->udev,
- usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
- skb_put(skb, size), size,
- (usb_complete_t)at76c503_read_bulk_callback, dev);
- ret = usb_submit_urb(dev->read_urb, GFP_ATOMIC);
- if (ret < 0) {
- if (ret == -ENODEV)
- dbg(DBG_DEVSTART, "usb_submit_urb returned -ENODEV");
- else
- err("%s: rx, usb_submit_urb failed: %d", dev->netdev->name, ret);
- }
-
-exit:
- if (ret < 0) {
- if (ret != -ENODEV) {
- /* If we can't submit the URB, the adapter becomes completely
- * useless, so try again later */
- if (--dev->nr_submit_rx_tries > 0)
- defer_kevent(dev, KEVENT_SUBMIT_RX);
- else {
- err("%s: giving up to submit rx urb after %d failures -"
- " please unload the driver and/or power cycle the device",
- dev->netdev->name, NR_SUBMIT_RX_TRIES);
- }
- }
- } else
- /* reset counter to initial value */
- dev->nr_submit_rx_tries = NR_SUBMIT_RX_TRIES;
- return ret;
-}
-
-
/* we are doing a lot of things here in an interrupt. Need
a bh handler (Watching TV with a TV card is probably
a good test: if you see flickers, we are doing too much.
Currently I do see flickers... even with our tasklet :-( )
Maybe because the bttv driver and usb-uhci use the same interrupt
*/
-/* Or maybe because our BH handler is preempting bttv's BH handler.. BHs don't
- * solve everything.. (alex) */
static void at76c503_read_bulk_callback (struct urb *urb)
{
struct at76c503 *dev = (struct at76c503 *)urb->context;
@@ -4286,211 +2145,64 @@ static void at76c503_read_bulk_callback (struct urb *urb)
return;
}
-static void rx_monitor_mode(struct at76c503 *dev)
-{
- struct net_device *netdev = (struct net_device *)dev->netdev;
- struct at76c503_rx_buffer *buf =
- (struct at76c503_rx_buffer *)dev->rx_skb->data;
- /* length including the IEEE802.11 header, excl. the trailing FCS,
- excl. the struct at76c503_rx_buffer */
- int length = le16_to_cpu(buf->wlength) - dev->rx_data_fcs_len;
- struct sk_buff *skb = dev->rx_skb;
- struct net_device_stats *stats = &dev->stats;
- struct iw_statistics *wstats = &dev->wstats;
-
- update_wstats(dev, buf);
-
- if (length < 0) {
- /* buffer contains no data */
- dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE: rx skb without data",
- dev->netdev->name);
- return;
- }
-
- if (netdev->type == ARPHRD_IEEE80211_PRISM) {
- int skblen = sizeof(p80211msg_lnxind_wlansniffrm_t) + length;
- p80211msg_lnxind_wlansniffrm_t *prism;
- u8* payload;
-
- if ((skb = dev_alloc_skb(skblen)) == NULL) {
- err("%s: MONITOR MODE: dev_alloc_skb for Prism header "
- "returned NULL", dev->netdev->name);
- return;
- }
-
- skb_put(skb, skblen);
-
- prism = (p80211msg_lnxind_wlansniffrm_t*)skb->data;
- payload = skb->data + sizeof(p80211msg_lnxind_wlansniffrm_t);
-
- prism->msgcode = DIDmsg_lnxind_wlansniffrm;
- prism->msglen = sizeof(p80211msg_lnxind_wlansniffrm_t);
- strcpy(prism->devname, netdev->name);
-
- prism->hosttime.did = DIDmsg_lnxind_wlansniffrm_hosttime;
- prism->hosttime.status = 0;
- prism->hosttime.len = 4;
- prism->hosttime.data = jiffies;
-
- prism->mactime.did = DIDmsg_lnxind_wlansniffrm_mactime;
- prism->mactime.status = 0;
- prism->mactime.len = 4;
- memcpy(&prism->mactime.data, buf->rx_time, 4);
-
- prism->channel.did = DIDmsg_lnxind_wlansniffrm_channel;
- prism->channel.status = P80211ENUM_msgitem_status_no_value;
- prism->channel.len = 4;
- /* INFO: The channel is encoded in the beacon info.
- (Kismet can figure it out, so less processing here) */
- prism->channel.data = 0;
-
- prism->rssi.did = DIDmsg_lnxind_wlansniffrm_rssi;
- prism->rssi.status = 0;
- prism->rssi.len = 4;
- prism->rssi.data = buf->rssi;
-
- prism->sq.did = DIDmsg_lnxind_wlansniffrm_sq;
- prism->sq.status = 0;
- prism->sq.len = 4;
- prism->sq.data = wstats->qual.qual;
-
- prism->signal.did = DIDmsg_lnxind_wlansniffrm_signal;
- prism->signal.status = 0;
- prism->signal.len = 4;
- prism->signal.data = wstats->qual.level;
-
- prism->noise.did = DIDmsg_lnxind_wlansniffrm_noise;
- prism->noise.status = 0;
- prism->noise.len = 4;
- prism->noise.data = wstats->qual.noise;
-
- prism->rate.did = DIDmsg_lnxind_wlansniffrm_rate;
- prism->rate.status = 0;
- prism->rate.len = 4;
- prism->rate.data = hw_rates[buf->rx_rate] & (~0x80);
-
- prism->istx.did = DIDmsg_lnxind_wlansniffrm_istx;
- prism->istx.status = 0;
- prism->istx.len = 4;
- prism->istx.data = P80211ENUM_truth_false;
-
- prism->frmlen.did = DIDmsg_lnxind_wlansniffrm_frmlen;
- prism->frmlen.status = 0;
- prism->frmlen.len = 4;
- prism->frmlen.data = length;
-
- memcpy(payload, buf->packet, length);
- } else {
- /* netdev->type != ARPHRD_IEEE80211_PRISM */
- skb_pull(skb, AT76C503_RX_HDRLEN);
- skb_trim(skb, length);
- dev->rx_skb = NULL;
- }
-
- skb->dev = netdev;
- skb->ip_summed = CHECKSUM_NONE;
- skb->mac.raw = skb->data;
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = htons(ETH_P_80211_RAW);
-
- netdev->last_rx = jiffies;
- netif_rx(skb);
- stats->rx_packets++;
- stats->rx_bytes += length;
-} /* end of rx_monitor_mode */
-
-
static void rx_tasklet(unsigned long param)
{
struct at76c503 *dev = (struct at76c503 *)param;
- struct urb *urb;
- struct net_device *netdev;
- struct at76c503_rx_buffer *buf;
- struct ieee80211_hdr_3addr *i802_11_hdr;
- u16 frame_ctl;
-
- if (!dev) return;
- urb = dev->rx_urb;
- netdev = (struct net_device *)dev->netdev;
-
- if (dev->device_unplugged) {
- dbg(DBG_DEVSTART, "device unplugged");
- if (urb)
- dbg(DBG_DEVSTART, "urb status %d", urb->status);
- return;
- }
-
-
- if(!urb || !dev->rx_skb || !netdev || !dev->rx_skb->data) return;
-
- buf = (struct at76c503_rx_buffer *)dev->rx_skb->data;
-
- if (!buf) return;
-
- i802_11_hdr = (struct ieee80211_hdr_3addr *)buf->packet;
- if (!i802_11_hdr) return;
+ struct urb *urb = dev->rx_urb;
+ struct net_device *netdev = (struct net_device *)dev->netdev;
+ struct at76c503_rx_buffer *buf = (struct at76c503_rx_buffer *)dev->bulk_in_buffer;
+ struct ieee802_11_hdr *i802_11_hdr = (struct ieee802_11_hdr *)buf->packet;
+ int ret;
+ u8 frame_type;
+// int flags;
- frame_ctl = le16_to_cpu(i802_11_hdr->frame_ctl);
+ if(!urb) return; // paranoid
if(urb->status != 0){
if ((urb->status != -ENOENT) &&
(urb->status != -ECONNRESET)) {
- dbg(DBG_URB,"%s %s: - nonzero read bulk status received: %d",
- __FUNCTION__, netdev->name, urb->status);
- goto no_more_urb;
+ dbg(__FUNCTION__ " %s: - nonzero read bulk status received: %d",
+ netdev->name, urb->status);
+ goto next_urb;
}
return;
}
- if (at76_debug & DBG_RX_ATMEL_HDR) {
- dbg_uc("%s: rx frame: rate %d rssi %d noise %d link %d %s",
- dev->netdev->name,
- buf->rx_rate, buf->rssi, buf->noise_level,
- buf->link_quality,
- hex2str(dev->obuf,(u8 *)i802_11_hdr,
- min((int)(sizeof(dev->obuf)-1)/2,48),'\0'));
- }
- LOCK_ISTATE()
- if (dev->istate == MONITORING) {
- UNLOCK_ISTATE()
- rx_monitor_mode(dev);
- goto finish;
- }
- UNLOCK_ISTATE()
+ //info("%s: rxrate %d\n",netdev->name,buf->rx_rate);
/* there is a new bssid around, accept it: */
- if(buf->newbss && dev->iw_mode == IW_MODE_ADHOC) {
- dbg(DBG_PROGRESS, "%s: rx newbss", netdev->name);
+ if(buf->newbss && dev->iw_mode == IW_MODE_ADHOC){
+ info("%s: rx newbss", netdev->name);
defer_kevent(dev, KEVENT_NEW_BSS);
}
- switch (frame_ctl & IEEE80211_FCTL_FTYPE) {
- case IEEE80211_FTYPE_DATA:
- rx_data(dev);
- break;
-
- case IEEE80211_FTYPE_MGMT:
- /* jal: TODO: find out if we can update iwspy also on
- other frames than management (might depend on the
- radio chip / firmware version !) */
-
- iwspy_update(dev, buf);
+ /* no need to care about endianness of constants - is taken care
+ of in ieee802_11.h */
+ frame_type = i802_11_hdr->frame_ctl & IEEE802_11_FCTL_FTYPE;
+ if(frame_type == IEEE802_11_FTYPE_DATA){
+// info("rx: it's a data frame");
+ rx_data(dev, buf);
+ }else if(frame_type == IEEE802_11_FTYPE_MGMT){
+// info("rx: it's a mgmt frame");
rx_mgmt(dev, buf);
- break;
+ }else if(frame_type == IEEE802_11_FTYPE_CTL)
+ info("rx: it's a ctrl frame: %2x", i802_11_hdr->frame_ctl);
+ else
+ info("rx: it's a frame from mars: %2x", i802_11_hdr->frame_ctl);
- case IEEE80211_FTYPE_CTL:
- dbg(DBG_RX_CTRL, "%s: ignored ctrl frame: %04x", dev->netdev->name,
- frame_ctl);
- break;
+ next_urb:
+ FILL_BULK_URB(dev->read_urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
+ dev->bulk_in_buffer, sizeof(struct at76c503_rx_buffer),
+ at76c503_read_bulk_callback, dev);
+ ret = usb_submit_urb(dev->read_urb);
+ if(ret < 0){
+ err("%s: rx, usb_submit_urb failed: %d", netdev->name, ret);
+ goto exit;
+ }
- default:
- info("%s: it's a frame from mars: %2x", dev->netdev->name,
- frame_ctl);
- } /* switch (frame_ctl & IEEE80211_FCTL_FTYPE) */
-finish:
- submit_rx_urb(dev);
- no_more_urb:
+ exit:
return;
}
@@ -4505,8 +2217,8 @@ static void at76c503_write_bulk_callback (struct urb *urb)
if(urb->status != 0){
if((urb->status != -ENOENT) &&
(urb->status != -ECONNRESET)) {
- dbg(DBG_URB, "%s - nonzero write bulk status received: %d",
- __FUNCTION__, urb->status);
+ dbg(__FUNCTION__ " - nonzero write bulk status received: %d",
+ urb->status);
}else
return; /* urb has been unlinked */
stats->tx_errors++;
@@ -4519,22 +2231,22 @@ static void at76c503_write_bulk_callback (struct urb *urb)
spin_unlock_irqrestore(&dev->mgmt_spinlock, flags);
if (mgmt_buf) {
- /* we don't copy the padding bytes, but add them
- to the length */
memcpy(dev->bulk_out_buffer, mgmt_buf,
le16_to_cpu(mgmt_buf->wlength) +
+ le16_to_cpu(mgmt_buf->padding) +
offsetof(struct at76c503_tx_buffer,packet));
FILL_BULK_URB(dev->write_urb, dev->udev,
usb_sndbulkpipe(dev->udev,
dev->bulk_out_endpointAddr),
dev->bulk_out_buffer,
le16_to_cpu(mgmt_buf->wlength) +
- mgmt_buf->padding + AT76C503_TX_HDRLEN,
- (usb_complete_t)at76c503_write_bulk_callback, dev);
- ret = usb_submit_urb(dev->write_urb, GFP_ATOMIC);
+ le16_to_cpu(mgmt_buf->padding) +
+ offsetof(struct at76c503_tx_buffer,packet),
+ at76c503_write_bulk_callback, dev);
+ ret = usb_submit_urb(dev->write_urb);
if (ret) {
- err("%s: %s error in tx submit urb: %d",
- dev->netdev->name, __FUNCTION__, ret);
+ err("%s:" __FUNCTION__ " error in tx submit urb: %d",
+ dev->netdev->name, ret);
}
kfree(mgmt_buf);
} else
@@ -4542,151 +2254,73 @@ static void at76c503_write_bulk_callback (struct urb *urb)
}
-#ifdef CONFIG_IPAQ_HANDHELD
-
-static struct timer_list led_timer;
-
-static void
-ipaq_clear_led (unsigned long time)
-{
- ipaq_led_off (RED_LED_2);
-}
-
-static void
-ipaq_blink_led (void)
-{
- ipaq_led_on (RED_LED_2);
-
- mod_timer (&led_timer, jiffies + (HZ / 25));
-}
-
-static void
-ipaq_init_led (void)
-{
- led_timer.function = ipaq_clear_led;
-
- init_timer (&led_timer);
-}
-
-#endif
-
-static int at76c503_tx(struct sk_buff *skb, struct net_device *netdev)
+static int
+at76c503_tx(struct sk_buff *skb, struct net_device *netdev)
{
struct at76c503 *dev = (struct at76c503 *)(netdev->priv);
struct net_device_stats *stats = &dev->stats;
- int ret = 0;
- int wlen;
+ int ret;
+ int len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
+ int wlen = len + 18;
int submit_len;
struct at76c503_tx_buffer *tx_buffer =
(struct at76c503_tx_buffer *)dev->bulk_out_buffer;
- struct ieee80211_hdr_3addr *i802_11_hdr =
- (struct ieee80211_hdr_3addr *)&(tx_buffer->packet);
- u8 *payload = tx_buffer->packet + sizeof(struct ieee80211_hdr_3addr);
-
- if (netif_queue_stopped(netdev)) {
- err("%s: %s called while netdev is stopped", netdev->name,
- __FUNCTION__);
- /* skip this packet */
- dev_kfree_skb(skb);
- return 0;
- }
-
- if (dev->write_urb->status == -EINPROGRESS) {
- err("%s: %s called while dev->write_urb is pending for tx",
- netdev->name, __FUNCTION__);
- /* skip this packet */
- dev_kfree_skb(skb);
- return 0;
- }
-
- if (skb->len < 2*ETH_ALEN) {
- err("%s: %s: skb too short (%d)", dev->netdev->name,
- __FUNCTION__, skb->len);
- dev_kfree_skb(skb);
- return 0;
- }
-
-#ifdef CONFIG_IPAQ_HANDHELD
- if (machine_is_h5400 ())
- ipaq_blink_led ();
-#endif
+ struct ieee802_11_hdr *i802_11_hdr =
+ (struct ieee802_11_hdr *)&(tx_buffer->packet);
/* we can get rid of memcpy, if we set netdev->hard_header_len
- to 8 + sizeof(struct ieee80211_hdr_3addr), because then we have
- enough space
- dbg(DBG_TX, "skb->data - skb->head = %d", skb->data - skb->head); */
-
- if (ntohs(*(__be16 *)(skb->data + 2*ETH_ALEN)) <= 1518) {
- /* this is a 802.3 packet */
- if (skb->data[2*ETH_ALEN+2] == rfc1042sig[0] &&
- skb->data[2*ETH_ALEN+2+1] == rfc1042sig[1]) {
- /* higher layer delivered SNAP header - keep it */
- memcpy(payload, skb->data + 2*ETH_ALEN+2, skb->len - 2*ETH_ALEN -2);
- wlen = sizeof(struct ieee80211_hdr_3addr) + skb->len - 2*ETH_ALEN -2;
- } else {
- err("%s: %s: no support for non-SNAP 802.2 packets "
- "(DSAP x%02x SSAP x%02x cntrl x%02x)",
- dev->netdev->name, __FUNCTION__,
- skb->data[2*ETH_ALEN+2], skb->data[2*ETH_ALEN+2+1],
- skb->data[2*ETH_ALEN+2+2]);
- dev_kfree_skb(skb);
- return 0;
- }
- } else {
- /* add RFC 1042 header in front */
- memcpy(payload, rfc1042sig, sizeof(rfc1042sig));
- memcpy(payload + sizeof(rfc1042sig),
- skb->data + 2*ETH_ALEN, skb->len - 2*ETH_ALEN);
- wlen = sizeof(struct ieee80211_hdr_3addr) + sizeof(rfc1042sig) +
- skb->len - 2*ETH_ALEN;
- }
+ to 8 + sizeof(struct ieee802_11_hdr), because then we have
+ enough space */
+ // dbg("skb->data - skb->head = %d", skb->data - skb->head);
+ /* 18 = sizeof(ieee802_11_hdr) - 2 * ETH_ALEN */
+ /* ssap and dsap stay in the data */
+ memcpy(&(tx_buffer->packet[18]), skb->data, len);
+
/* make wireless header */
- i802_11_hdr->frame_ctl =
- cpu_to_le16(IEEE80211_FTYPE_DATA |
- (dev->wep_enabled ? IEEE80211_FCTL_PROTECTED : 0) |
- (dev->iw_mode == IW_MODE_INFRA ? IEEE80211_FCTL_TODS : 0));
+ /* no need to care about endianness of constants - is taken care
+ of in ieee802_11.h */
+ i802_11_hdr->frame_ctl = IEEE802_11_FTYPE_DATA;
+
+ /* jal TODO: if the destination has sent us unencrypted packets
+ and we did not exclude them, do not encrypt the answers.
+ -> have a table of peers */
+ if (dev->wep_enabled)
+ i802_11_hdr->frame_ctl |= IEEE802_11_FCTL_WEP;
if(dev->iw_mode == IW_MODE_ADHOC){
memcpy(i802_11_hdr->addr1, skb->data, ETH_ALEN); /* destination */
- memcpy(i802_11_hdr->addr2, skb->data+ETH_ALEN, ETH_ALEN); /* source */
+ memcpy(i802_11_hdr->addr2, netdev->dev_addr, ETH_ALEN); /* source */
memcpy(i802_11_hdr->addr3, dev->bssid, ETH_ALEN);
}else if(dev->iw_mode == IW_MODE_INFRA){
+ i802_11_hdr->frame_ctl |= IEEE802_11_FCTL_TODS;
memcpy(i802_11_hdr->addr1, dev->bssid, ETH_ALEN);
- memcpy(i802_11_hdr->addr2, skb->data+ETH_ALEN, ETH_ALEN); /* source */
+ memcpy(i802_11_hdr->addr2, netdev->dev_addr, ETH_ALEN); /* source */
memcpy(i802_11_hdr->addr3, skb->data, ETH_ALEN); /* destination */
}
+ memset(i802_11_hdr->addr4, 0, ETH_ALEN);
- i802_11_hdr->duration_id = cpu_to_le16(0);
- i802_11_hdr->seq_ctl = cpu_to_le16(0);
+ i802_11_hdr->duration_id = 0;
+ i802_11_hdr->seq_ctl = 0;
- /* setup 'Atmel' header */
+ /* setup 'atmel' header */
tx_buffer->wlength = cpu_to_le16(wlen);
tx_buffer->tx_rate = dev->txrate;
- /* for broadcast destination addresses, the firmware 0.100.x
- seems to choose the highest rate set with CMD_STARTUP in
- basic_rate_set replacing this value */
-
- memset(tx_buffer->reserved, 0, 4);
- tx_buffer->padding = calc_padding(wlen);
- submit_len = wlen + AT76C503_TX_HDRLEN + tx_buffer->padding;
+ //info("txrate %d\n", dev->txrate);
+#if 0 /* does not seem to be necessary */
{
- dbg(DBG_TX_DATA_CONTENT, "%s skb->data %s", dev->netdev->name,
- hex2str(dev->obuf, skb->data,
- min((int)(sizeof(dev->obuf)-1)/2,32),'\0'));
- dbg(DBG_TX_DATA, "%s tx wlen x%x pad x%x rate %d hdr %s",
- dev->netdev->name,
- le16_to_cpu(tx_buffer->wlength),
- tx_buffer->padding, tx_buffer->tx_rate,
- hex2str(dev->obuf, (u8 *)i802_11_hdr,
- min((sizeof(dev->obuf)-1)/2,
- sizeof(struct ieee80211_hdr_3addr)),'\0'));
- dbg(DBG_TX_DATA_CONTENT, "%s payload %s", dev->netdev->name,
- hex2str(dev->obuf, payload,
- min((int)(sizeof(dev->obuf)-1)/2,48),'\0'));
+ /* strange things, as done in atmelwlandriver
+ - I do not really understand this (oku) */
+ int tmp = wlen%64;
+ tx_buffer->padding = tmp < 50 ? 50 - tmp : 114 - tmp;
}
+#endif
+ memset(tx_buffer->reserved, 0, 4);
+
+ tx_buffer->padding = 0;
+ submit_len = wlen + 8 + tx_buffer->padding;
/* send stuff */
netif_stop_queue(netdev);
@@ -4695,20 +2329,15 @@ static int at76c503_tx(struct sk_buff *skb, struct net_device *netdev)
FILL_BULK_URB(dev->write_urb, dev->udev,
usb_sndbulkpipe(dev->udev, dev->bulk_out_endpointAddr),
tx_buffer, submit_len,
- (usb_complete_t)at76c503_write_bulk_callback, dev);
- ret = usb_submit_urb(dev->write_urb, GFP_ATOMIC);
+ at76c503_write_bulk_callback, dev);
+ ret = usb_submit_urb(dev->write_urb);
if(ret){
stats->tx_errors++;
err("%s: error in tx submit urb: %d", netdev->name, ret);
- if (ret == -EINVAL)
- err("-EINVAL: urb %p urb->hcpriv %p urb->complete %p",
- dev->write_urb,
- dev->write_urb ? dev->write_urb->hcpriv : (void *)-1,
- dev->write_urb ? dev->write_urb->complete : (void *)-1);
goto err;
}
- stats->tx_bytes += skb->len;
+ stats->tx_bytes += len;
dev_kfree_skb(skb);
return 0;
@@ -4717,211 +2346,198 @@ static int at76c503_tx(struct sk_buff *skb, struct net_device *netdev)
return ret;
}
-
-static void at76c503_tx_timeout(struct net_device *netdev)
+static
+void at76c503_tx_timeout(struct net_device *netdev)
{
struct at76c503 *dev = (struct at76c503 *)(netdev->priv);
if (!dev)
return;
warn("%s: tx timeout.", netdev->name);
-#if WIRELESS_EXT < 17
dev->write_urb->transfer_flags |= USB_ASYNC_UNLINK;
-#endif
usb_unlink_urb(dev->write_urb);
dev->stats.tx_errors++;
}
-static int startup_device(struct at76c503 *dev)
+static
+int at76c503_open(struct net_device *netdev)
{
- struct at76c503_card_config *ccfg = &dev->card_config;
- int ret;
+ struct at76c503 *dev = (struct at76c503 *)(netdev->priv);
+ int ret = 0;
+ struct set_mib_buffer mib_buf;
- if (at76_debug & DBG_PARAMS) {
- char ossid[IW_ESSID_MAX_SIZE+1];
-
- /* make dev->essid printable */
- assert(dev->essid_size <= IW_ESSID_MAX_SIZE);
- memcpy(ossid, dev->essid, dev->essid_size);
- ossid[dev->essid_size] = '\0';
-
- dbg_uc("%s param: ssid %s (%s) mode %s ch %d wep %s key %d keylen %d",
- dev->netdev->name, ossid,
- hex2str(dev->obuf, dev->essid,
- min((int)(sizeof(dev->obuf)-1)/2,
- IW_ESSID_MAX_SIZE), '\0'),
- dev->iw_mode == IW_MODE_ADHOC ? "adhoc" : "infra",
- dev->channel,
- dev->wep_enabled ? "enabled" : "disabled",
- dev->wep_key_id, dev->wep_keys_len[dev->wep_key_id]);
- dbg_uc("%s param: preamble %s rts %d retry %d frag %d "
- "txrate %s auth_mode %d",
- dev->netdev->name,
- dev->preamble_type == PREAMBLE_TYPE_SHORT ? "short" : "long",
- dev->rts_threshold, dev->short_retry_limit,
- dev->frag_threshold,
- dev->txrate == TX_RATE_1MBIT ? "1MBit" :
- dev->txrate == TX_RATE_2MBIT ? "2MBit" :
- dev->txrate == TX_RATE_5_5MBIT ? "5.5MBit" :
- dev->txrate == TX_RATE_11MBIT ? "11MBit" :
- dev->txrate == TX_RATE_AUTO ? "auto" : "<invalid>",
- dev->auth_mode);
- dbg_uc("%s param: pm_mode %d pm_period %d auth_mode %s "
- "scan_times %d %d scan_mode %s international_roaming %d",
- dev->netdev->name,
- dev->pm_mode, dev->pm_period_us,
- dev->auth_mode == WLAN_AUTH_OPEN ?
- "open" : "shared_secret",
- dev->scan_min_time, dev->scan_max_time,
- dev->scan_mode == SCAN_TYPE_ACTIVE ? "active" : "passive",
- dev->international_roaming);
- }
+ if(down_interruptible(&dev->sem))
+ return -EINTR;
- memset(ccfg, 0, sizeof(struct at76c503_card_config));
- ccfg->promiscuous_mode = 0;
- ccfg->short_retry_limit = dev->short_retry_limit;
+ {
+ struct at76c503_card_config *ccfg = &dev->card_config;
+
+ memset(ccfg, 0, sizeof(struct at76c503_card_config));
+ ccfg->exclude_unencrypted = dev->wep_excl_unencr;
+ ccfg->promiscuous_mode = 0;
+ ccfg->promiscuous_mode = 1;
+ ccfg->short_retry_limit = 8;
- if (dev->wep_enabled) {
- if (dev->wep_keys_len[dev->wep_key_id] > WEP_SMALL_KEY_LEN)
+ if (dev->wep_enabled &&
+ dev->wep_keys_len[dev->wep_key_id] > WEP_SMALL_KEY_LEN)
ccfg->encryption_type = 2;
else
ccfg->encryption_type = 1;
- /* jal: always exclude unencrypted if WEP is active */
- ccfg->exclude_unencrypted = 1;
- } else {
- ccfg->exclude_unencrypted = 0;
- ccfg->encryption_type = 0;
- }
- ccfg->rts_threshold = cpu_to_le16(dev->rts_threshold);
- ccfg->fragmentation_threshold = cpu_to_le16(dev->frag_threshold);
+ ccfg->rts_threshold = dev->rts_threshold;
+ ccfg->fragmentation_threshold = dev->frag_threshold;
- memcpy(ccfg->basic_rate_set, hw_rates, 4);
- /* jal: really needed, we do a set_mib for autorate later ??? */
- ccfg->auto_rate_fallback = (dev->txrate == TX_RATE_AUTO ? 1 : 0);
- ccfg->channel = dev->channel;
- ccfg->privacy_invoked = dev->wep_enabled;
- memcpy(ccfg->current_ssid, dev->essid, IW_ESSID_MAX_SIZE);
- ccfg->ssid_len = dev->essid_size;
+ memcpy(ccfg->basic_rate_set, hw_rates, 4);
+ /* jal: really needed, we do a set_mib for autorate later ??? */
+ ccfg->auto_rate_fallback = (dev->txrate == 4 ? 1 : 0);
+ ccfg->channel = dev->channel;
+ ccfg->privacy_invoked = dev->wep_enabled;
+ memcpy(ccfg->current_ssid, dev->essid, IW_ESSID_MAX_SIZE);
+ ccfg->ssid_len = dev->essid_size;
- ccfg->wep_default_key_id = dev->wep_key_id;
- memcpy(ccfg->wep_default_key_value, dev->wep_keys, 4 * WEP_KEY_LEN);
+ ccfg->wep_default_key_id = dev->wep_key_id;
+ memcpy(ccfg->wep_default_key_value, dev->wep_keys, 4 * WEP_KEY_SIZE);
- ccfg->short_preamble = dev->preamble_type;
- ccfg->beacon_period = cpu_to_le16(dev->beacon_period);
+ ccfg->short_preamble = dev->preamble_type;
+ ccfg->beacon_period = 100;
+ }
ret = set_card_command(dev->udev, CMD_STARTUP, (unsigned char *)&dev->card_config,
sizeof(struct at76c503_card_config));
if(ret < 0){
- err("%s: set_card_command failed: %d", dev->netdev->name, ret);
- return ret;
+ err("%s: set_card_command failed: %d", netdev->name, ret);
+ goto err;
}
wait_completion(dev, CMD_STARTUP);
- /* remove BSSID from previous run */
- memset(dev->bssid, 0, ETH_ALEN);
-
- if (set_radio(dev, 1) == 1)
- wait_completion(dev, CMD_RADIO);
+ set_radio(dev, 1);
+ wait_completion(dev, CMD_RADIO);
- if ((ret=set_preamble(dev, dev->preamble_type)) < 0)
- return ret;
- if ((ret=set_frag(dev, dev->frag_threshold)) < 0)
- return ret;
+ set_preamble(dev, dev->preamble_type);
+ set_frag(dev, dev->frag_threshold);
+ set_rts(dev, dev->rts_threshold);
+ set_autorate_fallback(dev, dev->txrate == 4 ? 1 : 0);
- if ((ret=set_rts(dev, dev->rts_threshold)) < 0)
- return ret;
-
- if ((ret=set_autorate_fallback(dev, dev->txrate == TX_RATE_AUTO ? 1 : 0)) < 0)
- return ret;
+ FILL_BULK_URB(dev->read_urb, dev->udev,
+ usb_rcvbulkpipe(dev->udev, dev->bulk_in_endpointAddr),
+ dev->bulk_in_buffer, sizeof(struct at76c503_rx_buffer),
+ at76c503_read_bulk_callback, dev);
- if ((ret=set_pm_mode(dev, dev->pm_mode)) < 0)
- return ret;
-
- if ((ret=set_iroaming(dev, dev->international_roaming)) < 0)
- return ret;
+ ret = usb_submit_urb(dev->read_urb);
+ if(ret < 0){
+ err("%s: open: usb_submit_urb failed: %d", netdev->name, ret);
+ goto err;
+ }
- if (at76_debug & DBG_MIB)
- {
- dump_mib_mac(dev);
- dump_mib_mac_addr(dev);
- dump_mib_mac_mgmt(dev);
- dump_mib_mac_wep(dev);
- dump_mib_mdomain(dev);
- dump_mib_phy(dev);
- dump_mib_local(dev);
+ if (dev->iw_mode == IW_MODE_INFRA) {
+ NEW_STATE(dev,SCANNING);
+ defer_kevent(dev,KEVENT_SCANJOIN);
+ netif_carrier_off(dev->netdev); /* disable running netdev watchdog */
+ netif_stop_queue(dev->netdev); /* stop tx data packets */
+
+ goto good_end;
}
- return 0;
-}
+ /* here we go in adhoc mode only */
+ ret = start_scan(dev);
+ if(ret < 0){
+ err("%s: start_scan failed: %d", netdev->name, ret);
+ goto err;
+ }
-static int at76c503_open(struct net_device *netdev)
-{
- struct at76c503 *dev = (struct at76c503 *)(netdev->priv);
- int ret = 0;
+ wait_completion(dev, CMD_SCAN);
- dbg(DBG_PROC_ENTRY, "at76c503_open entry");
+// dump_bss_table(dev);
- if(down_interruptible(&dev->sem))
- return -EINTR;
+ if ((dev->curr_bss = find_matching_bss(dev,0)) >= 0) {
+ ret = join_bss(dev, dev->curr_bss);
+ if(ret < 0){
+ err("%s: join_bss failed: %d",
+ netdev->name, ret);
+ } else {
+ ret = wait_completion(dev, CMD_JOIN);
+ if (ret != CMD_STATUS_COMPLETE) {
+ /* it may time out -> dbg, not err */
+ dbg("%s join failed to complete,%d",
+ netdev->name, ret);
+ } else {
+ dbg("%s: join succeeded", netdev->name);
+ netif_start_queue(netdev);
- /* if netdev->dev_addr != dev->mac_addr we must
- set the mac address in the device ! */
- if (memcmp(netdev->dev_addr, dev->mac_addr, ETH_ALEN)) {
- if (set_mac_address(dev,netdev->dev_addr) >= 0)
- dbg(DBG_PROGRESS, "%s: set new MAC addr %s",
- netdev->name, mac2str(netdev->dev_addr));
- }
+ ret = get_current_bssid(dev);
+ if(ret < 0) goto err;
+
+ ret = get_current_channel(dev);
+ if(ret < 0) goto err;
-#ifdef DEBUG
- dump_mib_mac_addr(dev);
-#endif
+ goto good_end;
+ }
+ }
+ }else
+ dbg("%s: cannot find matching IBSS - start own",
+ dev->netdev->name);
- dev->site_survey_state=SITE_SURVEY_IDLE;
- dev->last_survey = jiffies;
- dev->nr_submit_rx_tries = NR_SUBMIT_RX_TRIES; /* init counter */
+ /* we either didn't find a matching BSS or
+ repeately failed to join it */
+ ret = start_ibss(dev);
+ if(ret < 0){
+ err("%s: start_ibss failed: %d", netdev->name, ret);
+ goto err;
+ }
- if((ret=submit_rx_urb(dev)) < 0){
- err("%s: open: submit_rx_urb failed: %d", netdev->name, ret);
+ ret = wait_completion(dev, CMD_START_IBSS);
+ if (ret != CMD_STATUS_COMPLETE) {
+ err("%s start_ibss failed to complete,%d",
+ netdev->name, ret);
goto err;
}
- dev->open_count++;
+ ret = get_current_bssid(dev);
+ if(ret < 0) goto err;
- defer_kevent(dev, KEVENT_RESTART);
+ ret = get_current_channel(dev);
+ if(ret < 0) goto err;
- dbg(DBG_PROC_ENTRY, "at76c503_open end");
+ // usb_debug_data(__FUNCTION__, (unsigned char *)phy, sizeof(struct mib_phy));
+
+
+ /* not sure what this is good for */
+ memset(&mib_buf, 0, sizeof(struct set_mib_buffer));
+ mib_buf.type = MIB_MAC_MGMT;
+ mib_buf.size = 1;
+ mib_buf.index = IBSS_CHANGE_OK_OFFSET;
+ ret = set_mib(dev->udev, &mib_buf);
+ if(ret < 0){
+ err("%s: set_mib (ibss change ok) failed: %d", netdev->name, ret);
+ goto err;
+ }
+
+ netif_start_queue(netdev);
+
+ good_end:
+ dbg("at76c503_open end");
err:
up(&dev->sem);
return ret < 0 ? ret : 0;
}
-static int at76c503_stop(struct net_device *netdev)
+static
+int at76c503_stop(struct net_device *netdev)
{
struct at76c503 *dev = (struct at76c503 *)(netdev->priv);
unsigned long flags;
- dbg(DBG_DEVSTART, "%s: ENTER", __FUNCTION__);
-
- if (down_interruptible(&dev->sem))
- return -EINTR;
+ down(&dev->sem);
netif_stop_queue(netdev);
- NEW_STATE(dev,INIT);
+ set_radio(dev, 0);
- if (!(dev->device_unplugged)) {
- /* we are called by "ifconfig wlanX down", not because the
- device isn't avail. anymore */
- set_radio(dev, 0);
-
- /* we unlink the read urb, because the _open()
- submits it again. _delete_device() takes care of the
- read_urb otherwise. */
- usb_kill_urb(dev->read_urb);
- }
+ usb_unlink_urb(dev->read_urb);
+ usb_unlink_urb(dev->write_urb);
+ usb_unlink_urb(dev->ctrl_urb);
del_timer_sync(&dev->mgmt_timer);
@@ -4932,38 +2548,29 @@ static int at76c503_stop(struct net_device *netdev)
}
spin_unlock_irqrestore(&dev->mgmt_spinlock,flags);
- /* free the bss_list */
- free_bss_list(dev);
-
- assert(dev->open_count > 0);
- dev->open_count--;
-
up(&dev->sem);
- dbg(DBG_DEVSTART, "%s: EXIT", __FUNCTION__);
-
return 0;
}
-static struct net_device_stats *at76c503_get_stats(struct net_device *netdev)
+static
+struct net_device_stats *at76c503_get_stats(struct net_device *netdev)
{
struct at76c503 *dev = (struct at76c503 *)netdev->priv;
-
+
return &dev->stats;
}
-static struct iw_statistics *at76c503_get_wireless_stats(struct net_device *netdev)
+static
+struct iw_statistics *at76c503_get_wireless_stats(struct net_device *netdev)
{
struct at76c503 *dev = (struct at76c503 *)netdev->priv;
-
- dbg(DBG_IOCTL, "RETURN qual %d level %d noise %d updated %d",
- dev->wstats.qual.qual, dev->wstats.qual.level,
- dev->wstats.qual.noise, dev->wstats.qual.updated);
-
+
return &dev->wstats;
}
-static void at76c503_set_multicast(struct net_device *netdev)
+static
+void at76c503_set_multicast(struct net_device *netdev)
{
struct at76c503 *dev = (struct at76c503 *)netdev->priv;
int promisc;
@@ -4976,1604 +2583,396 @@ static void at76c503_set_multicast(struct net_device *netdev)
}
}
-/* we only store the new mac address in netdev struct,
- it got set when the netdev gets opened. */
-static int at76c503_set_mac_address(struct net_device *netdev, void *addr)
+static
+int at76c503_set_mac_address(struct net_device *netdev, void *addr)
{
+ struct at76c503 *dev = (struct at76c503 *)netdev->priv;
struct sockaddr *mac = addr;
- memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
- return 1;
-}
-
-/* == PROC iwspy_update ==
- check if we spy on the sender address of buf and update statistics */
-static void iwspy_update(struct at76c503 *dev, struct at76c503_rx_buffer *buf)
-{
- struct ieee80211_hdr_3addr *hdr = (struct ieee80211_hdr_3addr *)buf->packet;
- struct iw_quality qual;
-
- /* We can only set the level here */
- qual.updated = IW_QUAL_QUAL_INVALID | IW_QUAL_NOISE_INVALID;
- qual.level = 0;
- qual.noise = 0;
- calc_level(dev, buf, &qual);
-
- spin_lock_bh(&(dev->spy_spinlock));
-
- if (dev->spy_data.spy_number > 0) {
- wireless_spy_update(dev->netdev, hdr->addr2, &qual);
- }
- spin_unlock_bh(&(dev->spy_spinlock));
-} /* iwspy_update */
-
-
-/*******************************************************************************
- * structure that describes the private ioctls/iw handlers of this driver
- */
-static const struct iw_priv_args at76c503_priv_args[] = {
- { PRIV_IOCTL_SET_SHORT_PREAMBLE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "short_preamble" }, /* 0 - long, 1 -short */
-
- { PRIV_IOCTL_SET_DEBUG,
- /* we must pass the new debug mask as a string,
- * 'cause iwpriv cannot parse hex numbers
- * starting with 0x :-( */
- IW_PRIV_TYPE_CHAR | 10, 0,
- "set_debug"}, /* set debug value */
-
- { PRIV_IOCTL_SET_POWERSAVE_MODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "powersave_mode"}, /* 1 - active, 2 - power save,
- 3 - smart power save */
- { PRIV_IOCTL_SET_SCAN_TIMES,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0,
- "scan_times"}, /* min_channel_time,
- max_channel_time */
- { PRIV_IOCTL_SET_SCAN_MODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "scan_mode"}, /* 0 - active, 1 - passive scan */
-
- { PRIV_IOCTL_SET_INTL_ROAMING,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0,
- "intl_roaming"},
-
- /* needed for Kismet, orinoco mode */
- { PRIV_IOCTL_SET_MONITOR_MODE,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 2, 0,
- "monitor"}, /* param1: monitor mode: 0 (off), 1 (on,Prism header),
- 2 (on, no Prism header)
- param2: channel (to start scan at) */
-};
-
-
-/*******************************************************************************
- * at76c503 implementations of iw_handler functions:
- */
-static int at76c503_iw_handler_commit(struct net_device *netdev,
- struct iw_request_info *info,
- void *null,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- unsigned long flags;
-
- dbg(DBG_IOCTL, "%s %s: restarting the device", netdev->name,
- __FUNCTION__);
-
- /* stop any pending tx bulk urb
- TODO */
-
- /* jal: TODO: protect access to dev->istate by a spinlock
- (ISR's on other processors may read/write it) */
- LOCK_ISTATE()
- if (dev->istate != INIT) {
- UNLOCK_ISTATE()
- NEW_STATE(dev,INIT);
- /* stop pending management stuff */
- del_timer_sync(&dev->mgmt_timer);
-
- spin_lock_irqsave(&dev->mgmt_spinlock,flags);
- if (dev->next_mgmt_bulk) {
- kfree(dev->next_mgmt_bulk);
- dev->next_mgmt_bulk = NULL;
- }
- spin_unlock_irqrestore(&dev->mgmt_spinlock,flags);
-
- netif_carrier_off(dev->netdev);
- netif_stop_queue(dev->netdev);
- } else UNLOCK_ISTATE()
-
- /* do the restart after two seconds to catch
- * following ioctl's (from more params of iwconfig)
- * in _one_ restart */
- mod_timer(&dev->restart_timer, jiffies+2*HZ);
-
- return 0;
-}
-
-static int at76c503_iw_handler_get_name(struct net_device *netdev,
- struct iw_request_info *info,
- char *name,
- char *extra)
-{
- strcpy(name, "IEEE 802.11b");
-
- dbg(DBG_IOCTL, "%s: SIOCGIWNAME - name %s", netdev->name, name);
-
- return 0;
-}
-
-static int at76c503_iw_handler_set_freq(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_freq *freq,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int chan = -1;
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - freq.m %d freq.e %d", netdev->name,
- freq->m, freq->e);
-
- /* modelled on orinoco.c */
- if ((freq->e == 0) && (freq->m <= 1000))
- {
- /* Setting by channel number */
- chan = freq->m;
- }
- else
- {
- /* Setting by frequency - search the table */
- int mult = 1;
- int i;
-
- for (i = 0; i < (6 - freq->e); i++) {
- mult *= 10;
- }
-
- for (i = 0; i < NUM_CHANNELS; i++) {
- if (freq->m == (channel_frequency[i] * mult))
- chan = i + 1;
- }
- }
-
- if (chan < 1 || !dev->domain ) {
- /* non-positive channels are invalid
- * we need a domain info to set the channel
- * either that or an invalid frequency was
- * provided by the user */
- ret = -EINVAL;
- } else if (!dev->international_roaming) {
- if (!(dev->domain->channel_map & (1 << (chan-1)))) {
- info("%s: channel %d not allowed for domain %s "
- "(and international_roaming is OFF)",
- dev->netdev->name, chan, dev->domain->name);
- ret = -EINVAL;
- }
- }
-
- if (ret == -EIWCOMMIT) {
- dev->channel = chan;
- dbg(DBG_IOCTL, "%s: SIOCSIWFREQ - ch %d", netdev->name, chan);
- }
-
- return ret;
-}
+ int ret;
-static int at76c503_iw_handler_get_freq(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_freq *freq,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- freq->m = dev->channel;
- freq->e = 0;
-
- if (dev->channel)
- {
- dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - freq %ld x 10e%d", netdev->name,
- channel_frequency[dev->channel - 1], 6);
- }
- dbg(DBG_IOCTL, "%s: SIOCGIWFREQ - ch %d", netdev->name, dev->channel);
-
- return 0;
-}
+ if (down_interruptible(&dev->sem))
+ return -EINTR;
-static int at76c503_iw_handler_set_mode(struct net_device *netdev,
- struct iw_request_info *info,
- __u32 *mode,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWMODE - %d", netdev->name, *mode);
-
- if ((*mode != IW_MODE_ADHOC) && (*mode != IW_MODE_INFRA) &&
- (*mode != IW_MODE_MONITOR)) {
- ret = -EINVAL;
- } else {
- dev->iw_mode = *mode;
+ ret = set_mac_address(dev, mac->sa_data);
+ if(ret >= 0){
+ memcpy(netdev->dev_addr, mac->sa_data, ETH_ALEN);
}
- return ret;
-}
-
-static int at76c503_iw_handler_get_mode(struct net_device *netdev,
- struct iw_request_info *info,
- __u32 *mode,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- *mode = dev->iw_mode;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWMODE - %d", netdev->name, *mode);
-
- return 0;
-}
-static int at76c503_iw_handler_get_range(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- /* inspired by atmel.c */
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- struct iw_range *range = (struct iw_range*)extra;
- int i;
-
- data->length = sizeof(struct iw_range);
- memset(range, 0, sizeof(struct iw_range));
-
-
- /* TODO: range->throughput = xxxxxx; */
-
- range->min_nwid = 0x0000;
- range->max_nwid = 0x0000;
-
- /* this driver doesn't maintain sensitivity information */
- range->sensitivity = 0;
-
- range->max_qual.qual = 100;
- range->max_qual.level = 100;
- range->max_qual.noise = 0;
- range->max_qual.updated = IW_QUAL_NOISE_INVALID;
-
- range->avg_qual.qual = 50;
- range->avg_qual.level = 50;
- range->avg_qual.noise = 0;
- range->avg_qual.updated = IW_QUAL_NOISE_INVALID;
-
- range->bitrate[0] = 1000000;
- range->bitrate[1] = 2000000;
- range->bitrate[2] = 5500000;
- range->bitrate[3] = 11000000;
- range->num_bitrates = 4;
-
-
- range->min_rts = 0;
- range->max_rts = MAX_RTS_THRESHOLD;
-
- range->min_frag = MIN_FRAG_THRESHOLD;
- range->max_frag = MAX_FRAG_THRESHOLD;
-
-
- /* TODO: find out what values we can use to describe PM capabilities */
- range->pmp_flags = IW_POWER_ON;
- range->pmt_flags = IW_POWER_ON;
- range->pm_capa = 0;
-
-
- range->encoding_size[0] = WEP_SMALL_KEY_LEN;
- range->encoding_size[1] = WEP_LARGE_KEY_LEN;
- range->num_encoding_sizes = 2;
- range->max_encoding_tokens = WEP_KEYS;
- /* TODO: do we need this? what is a valid value if we don't support?
- range->encoding_login_index = -1; */
-
- /* both WL-240U and Linksys WUSB11 v2.6 specify 15 dBm as output power
- - take this for all (ignore antenna gains) */
- range->txpower[0] = 15;
- range->num_txpower = 1;
- range->txpower_capa = IW_TXPOW_DBM;
-
- range->we_version_source = WIRELESS_EXT_SUPPORTED;
- range->we_version_compiled = WIRELESS_EXT;
-
- /* same as the values used in atmel.c */
- range->retry_capa = IW_RETRY_LIMIT ;
- range->retry_flags = IW_RETRY_LIMIT;
- range->r_time_flags = 0;
- range->min_retry = 1;
- range->max_retry = 255;
-
-
- range->num_channels = NUM_CHANNELS;
- range->num_frequency = 0;
-
- for (i = 0;
- i < 32; /* number of bits in reg_domain.channel_map */
- i++)
- {
- /* test if channel map bit is raised */
- if (dev->domain->channel_map & (0x1 << i))
- {
- range->num_frequency += 1;
-
- range->freq[i].i = i + 1;
- range->freq[i].m = channel_frequency[i] * 100000;
- range->freq[i].e = 1; /* channel frequency*100000 * 10^1 */
- }
- }
-
- dbg(DBG_IOCTL, "%s: SIOCGIWRANGE", netdev->name);
-
- return 0;
-}
-
-static int at76c503_iw_handler_set_spy(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = 0;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWSPY - number of addresses %d",
- netdev->name, data->length);
-
- spin_lock_bh(&(dev->spy_spinlock));
- ret = iw_handler_set_spy(dev->netdev, info, (union iwreq_data *)data,
- extra);
- spin_unlock_bh(&(dev->spy_spinlock));
-
- return ret;
-}
-
-static int at76c503_iw_handler_get_spy(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
-
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = 0;
-
- spin_lock_bh(&(dev->spy_spinlock));
- ret = iw_handler_get_spy(dev->netdev, info,
- (union iwreq_data *)data, extra);
- spin_unlock_bh(&(dev->spy_spinlock));
-
- dbg(DBG_IOCTL, "%s: SIOCGIWSPY - number of addresses %d",
- netdev->name, data->length);
-
- return ret;
-}
-
-static int at76c503_iw_handler_set_thrspy(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWTHRSPY - number of addresses %d)",
- netdev->name, data->length);
-
- spin_lock_bh(&(dev->spy_spinlock));
- ret = iw_handler_set_thrspy(netdev, info, (union iwreq_data *)data,
- extra);
- spin_unlock_bh(&(dev->spy_spinlock));
-
- return ret;
-}
+ up(&dev->sem);
-static int at76c503_iw_handler_get_thrspy(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret;
-
- spin_lock_bh(&(dev->spy_spinlock));
- ret = iw_handler_get_thrspy(netdev, info, (union iwreq_data *)data,
- extra);
- spin_unlock_bh(&(dev->spy_spinlock));
-
- dbg(DBG_IOCTL, "%s: SIOCGIWTHRSPY - number of addresses %d)",
- netdev->name, data->length);
-
return ret;
}
-static int at76c503_iw_handler_set_wap(struct net_device *netdev,
- struct iw_request_info *info,
- struct sockaddr *ap_addr,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWAP - wap/bssid %s", netdev->name,
- mac2str(ap_addr->sa_data));
-
- /* if the incoming address == ff:ff:ff:ff:ff:ff, the user has
- chosen any or auto AP preference */
- if (!memcmp(ap_addr->sa_data, bc_addr, ETH_ALEN)
- || !memcmp(ap_addr->sa_data, off_addr, ETH_ALEN)) {
- dev->wanted_bssid_valid = 0;
- } else {
- /* user wants to set a preferred AP address */
- dev->wanted_bssid_valid = 1;
- memcpy(dev->wanted_bssid, ap_addr->sa_data, ETH_ALEN);
- }
-
- return -EIWCOMMIT;
-}
-
-static int at76c503_iw_handler_get_wap(struct net_device *netdev,
- struct iw_request_info *info,
- struct sockaddr *ap_addr,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- ap_addr->sa_family = ARPHRD_ETHER;
- memcpy(ap_addr->sa_data, dev->bssid, ETH_ALEN);
-
- dbg(DBG_IOCTL, "%s: SIOCGIWAP - wap/bssid %s", netdev->name,
- mac2str(ap_addr->sa_data));
-
- return 0;
-}
-
-
-static int at76c503_iw_handler_set_scan(struct net_device *netdev,
- struct iw_request_info *info,
- union iwreq_data *wrqu,
- char *extra)
+static
+int at76c503_ioctl(struct net_device *netdev, struct ifreq *rq, int cmd)
{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- unsigned long flags;
+ struct at76c503 *dev = netdev->priv;
+ struct iwreq *wrq = (struct iwreq *)rq;
int ret = 0;
-#if WIRELESS_EXT > 19
- struct iw_scan_req *req = NULL;
-#endif
-
- dbg(DBG_IOCTL, "%s: SIOCSIWSCAN", netdev->name);
-
- if (!netif_running(netdev))
- return -ENETDOWN;
+ // int changed = 0;
+
+ if (! netif_device_present(netdev))
+ return -ENODEV;
- /* jal: we don't allow "iwlist wlanX scan" while we are
- in monitor mode */
- if (dev->iw_mode == IW_MODE_MONITOR)
- return -EBUSY;
+ if (down_interruptible(&dev->sem))
+ return -EINTR;
- /* Timeout old surveys. */
- if ((jiffies - dev->last_survey) > (20 * HZ))
- dev->site_survey_state = SITE_SURVEY_IDLE;
- dev->last_survey = jiffies;
+ switch (cmd) {
+ case SIOCGIWNAME:
+ dbg("%s: SIOCGIWNAME", netdev->name);
+ strcpy(wrq->u.name, "IEEE 802.11-DS");
+ break;
+
+ case SIOCGIWAP:
+ dbg("%s: SIOCGIWAP", netdev->name);
+ wrq->u.ap_addr.sa_family = ARPHRD_ETHER;
- /* Initiate a scan command */
- if (dev->site_survey_state == SITE_SURVEY_IN_PROGRESS)
- return -EBUSY;
+ memcpy(wrq->u.ap_addr.sa_data, dev->bssid, ETH_ALEN);
- dev->site_survey_state = SITE_SURVEY_IN_PROGRESS;
+ break;
- /* stop pending management stuff */
- del_timer_sync(&(dev->mgmt_timer));
-
- spin_lock_irqsave(&(dev->mgmt_spinlock), flags);
- if (dev->next_mgmt_bulk) {
- kfree(dev->next_mgmt_bulk);
- dev->next_mgmt_bulk = NULL;
- }
- spin_unlock_irqrestore(&(dev->mgmt_spinlock), flags);
-
- if (netif_running(dev->netdev)) {
- /* pause network activity */
- netif_carrier_off(dev->netdev);
- netif_stop_queue(dev->netdev);
- }
- /* Try to do passive or active scan if WE asks as. */
-#if WIRELESS_EXT > 19
- if (wrqu->data.length
- && wrqu->data.length == sizeof(struct iw_scan_req)) {
- req = (struct iw_scan_req *)extra;
-
- if (req->scan_type == IW_SCAN_TYPE_PASSIVE)
- dev->scan_mode = SCAN_TYPE_PASSIVE;
- else if (req->scan_type == IW_SCAN_TYPE_ACTIVE)
- dev->scan_mode = SCAN_TYPE_ACTIVE;
-
- /* Sanity check values? */
- LOCK_ISTATE()
- if (req->min_channel_time > 0) {
- if (dev->istate == MONITORING)
- dev->monitor_scan_min_time = req->min_channel_time;
- else
- dev->scan_min_time = req->min_channel_time;
- }
- if (req->max_channel_time > 0) {
- if (dev->istate == MONITORING)
- dev->monitor_scan_max_time = req->max_channel_time;
- else
- dev->scan_max_time = req->max_channel_time;
- }
- UNLOCK_ISTATE()
- }
+ case SIOCSIWRTS:
+ dbg("%s: SIOCSIWRTS", netdev->name);
+ {
+ int rthr = wrq->u.rts.value;
+#if 0
+ printk(KERN_DEBUG "%s: ioctl SIOCSIWRTS, value %d, disabled %d\n",
+ dev->name, wrq->u.rts.value, wrq->u.rts.disabled);
#endif
-
- /* change to scanning state */
- NEW_STATE(dev, SCANNING);
- defer_kevent(dev, KEVENT_SCAN);
-
- return ret;
-}
-
-static int at76c503_iw_handler_get_scan(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- unsigned long flags;
- struct list_head *lptr, *nptr;
- struct bss_info *curr_bss;
- struct iw_event *iwe = kmalloc(sizeof(struct iw_event), GFP_KERNEL);
- char *curr_val, *curr_pos = extra;
- int i;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWSCAN", netdev->name);
-
- if (!iwe)
- return -ENOMEM;
-
- if (dev->site_survey_state != SITE_SURVEY_COMPLETED)
- /* scan not yet finished */
- return -EAGAIN;
-
- spin_lock_irqsave(&(dev->bss_list_spinlock), flags);
-
- list_for_each_safe(lptr, nptr, &(dev->bss_list)) {
- curr_bss = list_entry(lptr, struct bss_info, list);
-
- iwe->cmd = SIOCGIWAP;
- iwe->u.ap_addr.sa_family = ARPHRD_ETHER;
- memcpy(iwe->u.ap_addr.sa_data, curr_bss->bssid, 6);
- curr_pos = iwe_stream_add_event(curr_pos,
- extra + IW_SCAN_MAX_DATA, iwe, IW_EV_ADDR_LEN);
-
- iwe->u.data.length = curr_bss->ssid_len;
- iwe->cmd = SIOCGIWESSID;
- iwe->u.data.flags = 1;
-
- curr_pos = iwe_stream_add_point(curr_pos,
- extra + IW_SCAN_MAX_DATA, iwe, curr_bss->ssid);
-
- iwe->cmd = SIOCGIWMODE;
- iwe->u.mode = (curr_bss->capa & WLAN_CAPABILITY_IBSS) ?
- IW_MODE_ADHOC :
- (curr_bss->capa & WLAN_CAPABILITY_ESS) ?
- IW_MODE_MASTER :
- IW_MODE_AUTO;
- /* IW_MODE_AUTO = 0 which I thought is
- * the most logical value to return in this case */
- curr_pos = iwe_stream_add_event(curr_pos,
- extra + IW_SCAN_MAX_DATA, iwe, IW_EV_UINT_LEN);
-
- iwe->cmd = SIOCGIWFREQ;
- iwe->u.freq.m = curr_bss->channel;
- iwe->u.freq.e = 0;
- curr_pos = iwe_stream_add_event(curr_pos,
- extra + IW_SCAN_MAX_DATA, iwe, IW_EV_FREQ_LEN);
-
- iwe->cmd = SIOCGIWENCODE;
- if (curr_bss->capa & WLAN_CAPABILITY_PRIVACY) {
- iwe->u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- } else {
- iwe->u.data.flags = IW_ENCODE_DISABLED;
- }
- iwe->u.data.length = 0;
- curr_pos = iwe_stream_add_point(curr_pos,
- extra + IW_SCAN_MAX_DATA, iwe, NULL);
-
- /* Add quality statistics */
- iwe->cmd = IWEVQUAL;
- iwe->u.qual.noise=0;
- iwe->u.qual.updated=IW_QUAL_NOISE_INVALID | IW_QUAL_LEVEL_UPDATED;
- iwe->u.qual.level = (curr_bss->rssi * 100 / 42);
- if (iwe->u.qual.level > 100)
- iwe->u.qual.level = 100;
- if((dev->board_type == BOARDTYPE_503_INTERSIL_3861) ||
- (dev->board_type == BOARDTYPE_503_INTERSIL_3863)) {
- iwe->u.qual.qual=curr_bss->link_qual;
- } else {
- iwe->u.qual.qual=0;
- iwe->u.qual.updated |= IW_QUAL_QUAL_INVALID;
- }
- /* Add new value to event */
- curr_pos = iwe_stream_add_event(curr_pos,
- extra + IW_SCAN_MAX_DATA, iwe, IW_EV_QUAL_LEN);
-
- /* Rate : stuffing multiple values in a single event require a bit
- * more of magic - Jean II */
- curr_val = curr_pos + IW_EV_LCP_LEN;
-
- iwe->cmd = SIOCGIWRATE;
- /* Those two flags are ignored... */
- iwe->u.bitrate.fixed = iwe->u.bitrate.disabled = 0;
- /* Max 8 values */
- for(i=0; i < curr_bss->rates_len; i++) {
- /* Bit rate given in 500 kb/s units (+ 0x80) */
- iwe->u.bitrate.value =
- ((curr_bss->rates[i] & 0x7f) * 500000);
- /* Add new value to event */
- curr_val = iwe_stream_add_value(curr_pos, curr_val,
- extra + IW_SCAN_MAX_DATA,
- iwe, IW_EV_PARAM_LEN);
+ if(wrq->u.rts.disabled)
+ rthr = MAX_RTS_THRESHOLD;
+ if((rthr < 0) || (rthr > MAX_RTS_THRESHOLD)) {
+ ret = -EINVAL;
+ goto error;
+ }
+ dev->rts_threshold = rthr;
}
+ break;
- /* Check if we added any event */
- if ((curr_val - curr_pos) > IW_EV_LCP_LEN)
- curr_pos = curr_val;
-
-
- /* more information may be sent back using IWECUSTOM */
-
- }
-
- spin_unlock_irqrestore(&(dev->bss_list_spinlock), flags);
-
- data->length = (curr_pos - extra);
- data->flags = 0;
-
- kfree(iwe);
- return 0;
-}
+ // Get the current RTS threshold
+ case SIOCGIWRTS:
+ dbg("%s: SIOCGIWRTS", netdev->name);
+#if 0
+ printk(KERN_DEBUG "%s: ioctl SIOCGIWRTS\n", dev->name);
+#endif
+ wrq->u.rts.value = dev->rts_threshold;
+ wrq->u.rts.disabled = (wrq->u.rts.value == MAX_RTS_THRESHOLD);
+ wrq->u.rts.fixed = 1;
+ break;
+ // Set the desired fragmentation threshold
-static int at76c503_iw_handler_set_essid(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWESSID - %s", netdev->name, extra);
-
- if (data->flags)
- {
- memcpy(dev->essid, extra, data->length);
- dev->essid_size = data->length;
-#if WIRELESS_EXT < 21
- /* For historic reasons, the SSID length used to include one
- * extra character, C string nul termination, even though SSID is
- * really an octet string that should not be presented as a C
- * string. WE-21 changes this to explicitly require the length
- * _not_ to include nul termination, but for WE < 21, decrement
- * the length count here to remove the nul termination. */
- dev->essid_size = max(dev->essid_size - 1, 0);
+ case SIOCSIWFRAG:
+ dbg("%s: SIOCSIWFRAG", netdev->name);
+ {
+ int fthr = wrq->u.frag.value;
+#if 0
+ printk(KERN_DEBUG "%s: ioctl SIOCSIWFRAG, value %d, disabled %d\n",
+ dev->name, wrq->u.frag.value, wrq->u.frag.disabled);
#endif
- }
- else
- {
- /* Use any SSID */
- dev->essid_size = 0;
- }
-
- return -EIWCOMMIT;
-}
-
-static int at76c503_iw_handler_get_essid(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- if (dev->essid_size) {
- /* not the ANY ssid in dev->essid */
- data->flags = 1;
- data->length = dev->essid_size;
- memcpy(extra, dev->essid, data->length);
- extra[data->length] = '\0';
- data->length += 1;
- } else {
- /* the ANY ssid was specified */
- LOCK_ISTATE()
- if (dev->istate == CONNECTED &&
- dev->curr_bss != NULL) {
- UNLOCK_ISTATE()
- /* report the SSID we have found */
- data->flags = 1;
- data->length = dev->curr_bss->ssid_len;
- memcpy(extra, dev->curr_bss->ssid, data->length);
- extra[dev->curr_bss->ssid_len] = '\0';
- data->length += 1;
- } else {
- UNLOCK_ISTATE()
- /* report ANY back */
- data->flags=0;
- data->length=0;
+ if(wrq->u.frag.disabled)
+ fthr = MAX_FRAG_THRESHOLD;
+ if((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD)){
+ ret = -EINVAL;
+ goto error;
+ }else{
+ dev->frag_threshold = fthr & ~0x1; // get an even value
+ }
}
- }
-
- dbg(DBG_IOCTL, "%s: SIOCGIWESSID - %s", netdev->name, extra);
-
- return 0;
-}
-
-static int at76c503_iw_handler_set_nickname(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWNICKN - %s", netdev->name, extra);
-
- /* iwconfig gives length including 0 byte like in the case of essid */
- memcpy(dev->nickn, extra, data->length);
-
- return 0;
-}
-
-static int at76c503_iw_handler_get_nickname(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *data,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- data->length = strlen(dev->nickn);
- memcpy(extra, dev->nickn, data->length);
- extra[data->length] = '\0';
- data->length += 1;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWNICKN - %s", netdev->name, extra);
-
- return 0;
-}
-
-static int at76c503_iw_handler_set_rate(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *bitrate,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWRATE - %d", netdev->name,
- bitrate->value);
-
- switch (bitrate->value)
- {
- case -1: dev->txrate = TX_RATE_AUTO; break; /* auto rate */
- case 1000000: dev->txrate = TX_RATE_1MBIT; break;
- case 2000000: dev->txrate = TX_RATE_2MBIT; break;
- case 5500000: dev->txrate = TX_RATE_5_5MBIT; break;
- case 11000000: dev->txrate = TX_RATE_11MBIT; break;
- default: ret = -EINVAL;
- }
-
- return ret;
-}
+ break;
-static int at76c503_iw_handler_get_rate(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *bitrate,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = 0;
-
- switch (dev->txrate)
- {
- /* return max rate if RATE_AUTO */
- case TX_RATE_AUTO: bitrate->value = 11000000; break;
- case TX_RATE_1MBIT: bitrate->value = 1000000; break;
- case TX_RATE_2MBIT: bitrate->value = 2000000; break;
- case TX_RATE_5_5MBIT: bitrate->value = 5500000; break;
- case TX_RATE_11MBIT: bitrate->value = 11000000; break;
- default: ret = -EINVAL;
- }
-
- bitrate->fixed = (dev->txrate != TX_RATE_AUTO);
- bitrate->disabled = 0;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWRATE - %d", netdev->name,
- bitrate->value);
-
- return ret;
-}
+ // Get the current fragmentation threshold
+ case SIOCGIWFRAG:
+ dbg("%s: SIOCGIWFRAG", netdev->name);
-static int at76c503_iw_handler_set_rts(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *rts,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = -EIWCOMMIT;
- int rthr = rts->value;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWRTS - value %d disabled %s",
- netdev->name, rts->value,
- (rts->disabled) ? "true" : "false");
-
- if (rts->disabled)
- rthr = MAX_RTS_THRESHOLD;
-
- if ((rthr < 0) || (rthr > MAX_RTS_THRESHOLD)) {
- ret = -EINVAL;
- } else {
- dev->rts_threshold = rthr;
- }
-
- return ret;
-}
+ wrq->u.frag.value = dev->frag_threshold;
+ wrq->u.frag.disabled = (wrq->u.frag.value >= MAX_FRAG_THRESHOLD);
+ wrq->u.frag.fixed = 1;
+ break;
-static int at76c503_iw_handler_get_rts(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *rts,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- rts->value = dev->rts_threshold;
- rts->disabled = (rts->value >= MAX_RTS_THRESHOLD);
- rts->fixed = 1;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWRTS - value %d disabled %s",
- netdev->name, rts->value,
- (rts->disabled) ? "true" : "false");
-
- return 0;
-}
+ case SIOCGIWFREQ:
+ dbg("%s: SIOCGIWFREQ", netdev->name);
+ wrq->u.freq.m = dev->channel;
+ wrq->u.freq.e = 0;
+ wrq->u.freq.i = 0;
+ break;
-static int at76c503_iw_handler_set_frag(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *frag,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = -EIWCOMMIT;
- int fthr = frag->value;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWFRAG - value %d, disabled %s",
- netdev->name, frag->value,
- (frag->disabled) ? "true" : "false");
-
- if(frag->disabled)
- fthr = MAX_FRAG_THRESHOLD;
-
- if ((fthr < MIN_FRAG_THRESHOLD) || (fthr > MAX_FRAG_THRESHOLD)) {
- ret = -EINVAL;
- } else {
- dev->frag_threshold = fthr & ~0x1; /* get an even value */
- }
-
- return ret;
-}
+ case SIOCSIWFREQ:
+ dbg("%s: SIOCGIWFREQ", netdev->name);
+ /* copied from orinoco.c */
+ {
+ struct iw_freq *frq = &wrq->u.freq;
+ int chan = -1;
+
+ /* We can only use this in Ad-Hoc demo mode to set the operating
+ * frequency, or in IBSS mode to set the frequency where the IBSS
+ * will be created - Jean II */
+ /* dunno if this also applies for this device (oku) */
+ if(dev->iw_mode != IW_MODE_ADHOC){
+ ret = -EOPNOTSUPP;
+ goto error;
+ }
-static int at76c503_iw_handler_get_frag(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *frag,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- frag->value = dev->frag_threshold;
- frag->disabled = (frag->value >= MAX_FRAG_THRESHOLD);
- frag->fixed = 1;
+ if((frq->e == 0) && (frq->m <= 1000)){
+ /* Setting by channel number */
+ chan = frq->m;
+ }else{
+ /* Setting by frequency - search the table */
+ int mult = 1;
+ int i;
- dbg(DBG_IOCTL, "%s: SIOCGIWFRAG - value %d, disabled %s",
- netdev->name, frag->value,
- (frag->disabled) ? "true" : "false");
+ for(i = 0; i < (6 - frq->e); i++)
+ mult *= 10;
- return 0;
-}
+ for(i = 0; i < NUM_CHANNELS; i++)
+ if(frq->m == (channel_frequency[i] * mult))
+ chan = i+1;
+ }
+
+ /* TODO: we should also check if the channel is
+ supported by the device (oku) */
+ if ((chan < 1) || (chan > NUM_CHANNELS)){
+ ret = -EINVAL;
+ goto error;
+ }
-static int at76c503_iw_handler_get_txpow(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *power,
- char *extra)
-{
- power->value = 15;
- power->fixed = 1; /* No power control */
- power->disabled = 0;
- power->flags = IW_TXPOW_DBM;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWTXPOW - txpow %d dBm", netdev->name,
- power->value);
-
- return 0;
-}
+ dev->channel = chan;
+ }
+ break;
-/* jal: short retry is handled by the firmware (at least 0.90.x),
- while long retry is not (?) */
-static int at76c503_iw_handler_set_retry(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *retry,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWRETRY disabled %d flags x%x val %d",
- netdev->name, retry->disabled, retry->flags, retry->value);
-
- if(!retry->disabled && (retry->flags & IW_RETRY_LIMIT)) {
- if ((retry->flags & IW_RETRY_MIN) ||
- !(retry->flags & IW_RETRY_MAX)) {
- dev->short_retry_limit = retry->value;
- } else
- ret = -EINVAL;
- } else {
- ret = -EINVAL;
- }
-
- return ret;
-}
+ case SIOCGIWMODE:
+ dbg("%s: SIOCGIWMODE", netdev->name);
+ wrq->u.mode = dev->iw_mode;
+ break;
-/* adapted (ripped) from atmel.c */
-static int at76c503_iw_handler_get_retry(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *retry,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWRETRY", netdev->name);
-
- retry->disabled = 0; /* Can't be disabled */
-
+ case SIOCSIWMODE:
+ dbg("%s: SIOCSIWMODE %d", netdev->name, wrq->u.mode);
+ dev->iw_mode = wrq->u.mode;
+ break;
- retry->flags = IW_RETRY_LIMIT;
- retry->value = dev->short_retry_limit;
-
- return 0;
-}
+ case SIOCGIWESSID:
+ dbg("%s: SIOCGIWESSID", netdev->name);
+ {
+ char essidbuf[IW_ESSID_MAX_SIZE];
+ struct iw_point *erq = &wrq->u.essid;
-static int at76c503_iw_handler_set_encode(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *encoding,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
- int len = encoding->length;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - enc.flags %08x "
- "pointer %p len %d", netdev->name, encoding->flags,
- encoding->pointer, encoding->length);
- dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - old wepstate: enabled %s key_id %d "
- "auth_mode %s",
- netdev->name, (dev->wep_enabled) ? "true" : "false",
- dev->wep_key_id,
- (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ?
- "restricted" : "open");
-
- /* take the old default key if index is invalid */
- if ((index < 0) || (index >= WEP_KEYS))
- index = dev->wep_key_id;
-
- if (len > 0)
- {
- if (len > WEP_LARGE_KEY_LEN)
- len = WEP_LARGE_KEY_LEN;
-
- memset(dev->wep_keys[index], 0, WEP_KEY_LEN);
- memcpy(dev->wep_keys[index], extra, len);
- dev->wep_keys_len[index] = (len <= WEP_SMALL_KEY_LEN) ?
- WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
- dev->wep_enabled = 1;
- }
-
- dev->wep_key_id = index;
- dev->wep_enabled = ((encoding->flags & IW_ENCODE_DISABLED) == 0);
-
- if (encoding->flags & IW_ENCODE_RESTRICTED)
- dev->auth_mode = WLAN_AUTH_SHARED_KEY;
- if (encoding->flags & IW_ENCODE_OPEN)
- dev->auth_mode = WLAN_AUTH_OPEN;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWENCODE - new wepstate: enabled %s key_id %d "
- "key_len %d auth_mode %s",
- netdev->name, (dev->wep_enabled) ? "true" : "false",
- dev->wep_key_id + 1, dev->wep_keys_len[dev->wep_key_id],
- (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ?
- "restricted" : "open");
-
- return -EIWCOMMIT;
-}
+ memcpy(essidbuf, dev->essid, sizeof(essidbuf));
+ erq->flags = 1;
+ erq->length = strlen(essidbuf);
-static int at76c503_iw_handler_get_encode(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_point *encoding,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int index = (encoding->flags & IW_ENCODE_INDEX) - 1;
-
- if ((index < 0) || (index >= WEP_KEYS))
- index = dev->wep_key_id;
-
- encoding->flags =
- (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ?
- IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
-
- if (!dev->wep_enabled)
- encoding->flags |= IW_ENCODE_DISABLED;
-
- if (encoding->pointer)
- {
- encoding->length = dev->wep_keys_len[index];
-
- memcpy(extra, dev->wep_keys[index], dev->wep_keys_len[index]);
-
- encoding->flags |= (index + 1);
- }
-
- dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - enc.flags %08x "
- "pointer %p len %d", netdev->name, encoding->flags,
- encoding->pointer, encoding->length);
- dbg(DBG_IOCTL, "%s: SIOCGIWENCODE - wepstate: enabled %s key_id %d "
- "key_len %d auth_mode %s",
- netdev->name, (dev->wep_enabled) ? "true" : "false",
- dev->wep_key_id + 1, dev->wep_keys_len[dev->wep_key_id],
- (dev->auth_mode == WLAN_AUTH_SHARED_KEY) ?
- "restricted" : "open");
-
- return 0;
-}
+ if(erq->pointer){
+ if(copy_to_user(erq->pointer, essidbuf, erq->length)){
+ ret = -EFAULT;
+ goto error;
+ }
+ }
-static int at76c503_iw_handler_set_power(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *power,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- dbg(DBG_IOCTL, "%s: SIOCSIWPOWER - disabled %s flags x%x value x%x",
- netdev->name, (power->disabled) ? "true" : "false",
- power->flags, power->value);
-
- if (power->disabled)
- {
- dev->pm_mode = PM_ACTIVE;
- }
- else
- {
- /* we set the listen_interval based on the period given
- no idea how to handle the timeout of iwconfig ??? */
- if (power->flags & IW_POWER_PERIOD)
- {
- dev->pm_period_us = power->value;
}
-
- dev->pm_mode = PM_SAVE; /* use iw_priv to select SMART_SAVE */
- }
-
- return -EIWCOMMIT;
-}
-
-static int at76c503_iw_handler_get_power(struct net_device *netdev,
- struct iw_request_info *info,
- struct iw_param *power,
- char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
-
- power->disabled = dev->pm_mode == PM_ACTIVE;
-
- if ((power->flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT)
- {
- power->flags = IW_POWER_TIMEOUT;
- power->value = 0;
- }
- else
- {
- unsigned long flags;
- u16 beacon_int; /* of the current bss */
-
- power->flags = IW_POWER_PERIOD;
+ break;
- spin_lock_irqsave(&dev->bss_list_spinlock, flags);
- beacon_int = dev->curr_bss != NULL ?
- dev->curr_bss->beacon_interval : 0;
- spin_unlock_irqrestore(&dev->bss_list_spinlock, flags);
-
- if (beacon_int != 0)
- {
- power->value =
- (beacon_int * dev->pm_period_beacon) << 10;
- }
- else
+ case SIOCSIWESSID:
+ dbg("%s: SIOCSIWESSID", netdev->name);
{
- power->value = dev->pm_period_us;
- }
- }
-
- power->flags |= IW_POWER_ALL_R;
-
- dbg(DBG_IOCTL, "%s: SIOCGIWPOWER - disabled %s flags x%x value x%x",
- netdev->name, (power->disabled) ? "true" : "false",
- power->flags, power->value);
-
- return 0;
-}
-
-
-/*******************************************************************************
- * Private IOCTLS
- */
-static int at76c503_iw_handler_PRIV_IOCTL_SET_SHORT_PREAMBLE
- (struct net_device *netdev, struct iw_request_info *info,
- char *name, char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int val = *((int *)name);
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_SHORT_PREAMBLE, %d",
- netdev->name, val);
-
- if (val < 0 || val > 2) {
- /* allow value of 2 - in the win98 driver it stands
- for "auto preamble" ...? */
- ret = -EINVAL;
- } else {
- dev->preamble_type = val;
- }
-
- return ret;
-}
+ char essidbuf[IW_ESSID_MAX_SIZE];
+ struct iw_point *erq = &wrq->u.essid;
-static int at76c503_iw_handler_PRIV_IOCTL_SET_DEBUG
- (struct net_device *netdev, struct iw_request_info *info,
- struct iw_point *data, char *extra)
-{
- char *ptr;
- u32 val;
-
- if (data->length > 0) {
- val = simple_strtol(extra, &ptr, 0);
-
- if (ptr == extra) {
- val = DBG_DEFAULTS;
- }
-
- dbg_uc("%s: PRIV_IOCTL_SET_DEBUG input %d: %s -> x%x",
- netdev->name, data->length, extra, val);
- } else {
- val = DBG_DEFAULTS;
- }
-
- dbg_uc("%s: PRIV_IOCTL_SET_DEBUG, old 0x%x new 0x%x",
- netdev->name, at76_debug, val);
-
- /* jal: some more output to pin down lockups */
- dbg_uc("%s: netif running %d queue_stopped %d carrier_ok %d",
- netdev->name,
- netif_running(netdev),
- netif_queue_stopped(netdev),
- netif_carrier_ok(netdev));
-
- at76_debug = val;
-
- return 0;
-}
+ memset(&essidbuf, 0, sizeof(essidbuf));
-static int at76c503_iw_handler_PRIV_IOCTL_SET_POWERSAVE_MODE
- (struct net_device *netdev, struct iw_request_info *info,
- char *name, char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int val = *((int *)name);
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_POWERSAVE_MODE, %d (%s)",
- netdev->name, val,
- val == PM_ACTIVE ? "active" : val == PM_SAVE ? "save" :
- val == PM_SMART_SAVE ? "smart save" : "<invalid>");
- if (val < PM_ACTIVE || val > PM_SMART_SAVE) {
- ret = -EINVAL;
- } else {
- dev->pm_mode = val;
- }
+ if (erq->flags) {
+ if (erq->length > IW_ESSID_MAX_SIZE){
+ ret = -E2BIG;
+ goto error;
+ }
- return ret;
-}
-
-static int at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_TIMES
- (struct net_device *netdev, struct iw_request_info *info,
- char *name, char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int mint = *((int *)name);
- int maxt = *((int *)name + 1);
- int ret = -EIWCOMMIT;
+ if (copy_from_user(essidbuf, erq->pointer, erq->length)){
+ ret = -EFAULT;
+ goto error;
+ }
- dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_SCAN_TIMES - min %d max %d",
- netdev->name, mint, maxt);
- if (mint <= 0 || maxt <= 0 || mint > maxt) {
- ret = -EINVAL;
- } else {
- LOCK_ISTATE()
- if (dev->istate == MONITORING) {
- dev->monitor_scan_min_time = mint;
- dev->monitor_scan_max_time = maxt;
- ret = 0;
- } else {
- dev->scan_min_time = mint;
- dev->scan_max_time = maxt;
+ /* iwconfig gives len including 0 byte -
+ 3 hours debugging... grrrr (oku) */
+ dev->essid_size = erq->length - 1;
+ memcpy(dev->essid, essidbuf, IW_ESSID_MAX_SIZE);
+ }
}
- UNLOCK_ISTATE()
- }
-
- return ret;
-}
-
-static int at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_MODE
- (struct net_device *netdev, struct iw_request_info *info,
- char *name, char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int val = *((int *)name);
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_SCAN_MODE - mode %s",
- netdev->name, (val = SCAN_TYPE_ACTIVE) ? "active" :
- (val = SCAN_TYPE_PASSIVE) ? "passive" : "<invalid>");
-
- if (val != SCAN_TYPE_ACTIVE && val != SCAN_TYPE_PASSIVE) {
- ret = -EINVAL;
- } else {
- dev->scan_mode = val;
- }
-
- return ret;
-}
-
-static int set_iroaming(struct at76c503 *dev, int onoff)
-{
- int ret = 0;
-
- memset(&dev->mib_buf, 0, sizeof(struct set_mib_buffer));
- dev->mib_buf.type = MIB_MAC_MGMT;
- dev->mib_buf.size = 1;
- dev->mib_buf.index = IROAMING_OFFSET;
- dev->mib_buf.data[0] = (dev->international_roaming ? 1 : 0);
- ret = set_mib(dev, &dev->mib_buf);
- if(ret < 0){
- err("%s: set_mib (intl_roaming_enable) failed: %d", dev->netdev->name, ret);
- }
+ break;
- return ret;
-}
+ case SIOCGIWRATE:
+ wrq->u.bitrate.value = dev->txrate == 0 ? 1000000 :
+ dev->txrate == 1 ? 2000000 : dev->txrate == 2 ? 5500000 :
+ dev->txrate == 3 ? 11000000 : 11000000;
+ wrq->u.bitrate.fixed = (dev->txrate != 4);
+ wrq->u.bitrate.disabled = 0;
+ break;
-static int at76c503_iw_handler_PRIV_IOCTL_SET_INTL_ROAMING
- (struct net_device *netdev, struct iw_request_info *info,
- char *name, char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int val = *((int *)name);
- int ret = -EIWCOMMIT;
-
- dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_INTL_ROAMING - mode %s",
- netdev->name, (val == IR_OFF) ? "off" :
- (val == IR_ON) ? "on" : "<invalid>");
-
- if (val != IR_OFF && val != IR_ON) {
- ret = -EINVAL;
- } else {
- if (dev->international_roaming != val) {
- dev->international_roaming = val;
- set_iroaming(dev, val);
+ case SIOCSIWRATE:
+ dbg("%s: SIOCSIWRATE %d", netdev->name, wrq->u.bitrate.value);
+ switch (wrq->u.bitrate.value){
+ case -1: dev->txrate = 4; break; /* auto rate */
+ case 1000000: dev->txrate = 0; break;
+ case 2000000: dev->txrate = 1; break;
+ case 5500000: dev->txrate = 2; break;
+ case 11000000: dev->txrate = 3; break;
+ default:
+ ret = -EINVAL;
}
- }
+ break;
- return ret;
-}
+ case SIOCSIWENCODE:
+ dbg("%s: SIOCSIWENCODE", netdev->name);
+#if 1
+ printk(KERN_DEBUG "%s: ioctl SIOCSIWENCODE enc.flags %08x "
+ "pointer %p len %d\n",
+ dev->netdev->name, wrq->u.encoding.flags,
+ wrq->u.encoding.pointer, wrq->u.encoding.length);
+ printk(KERN_DEBUG "%s: old wepstate: enabled %d key_id %d "
+ "excl_unencr %d\n",
+ dev->netdev->name, dev->wep_enabled, dev->wep_key_id,
+ dev->wep_excl_unencr);
+#endif
+ {
+ int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+ /* take the old default key if index is invalid */
+ if((index < 0) || (index >= NR_WEP_KEYS))
+ index = dev->wep_key_id;
+ if(wrq->u.encoding.pointer){
+ int len = wrq->u.encoding.length;
+
+ if(len > WEP_LARGE_KEY_LEN){
+ len = WEP_LARGE_KEY_LEN;
+ }
-/* == PROC set_monitor_mode ==
- sets dev->netdev->type */
-static void set_monitor_mode(struct at76c503 *dev, int use_prism)
-{
- if (dev->iw_mode == IW_MODE_MONITOR) {
- if (use_prism) {
- dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE ON: "
- "Prism headers ARE used", dev->netdev->name);
- dev->netdev->type = ARPHRD_IEEE80211_PRISM;
- } else {
- dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE ON: "
- "Prism headers NOT used", dev->netdev->name);
- dev->netdev->type = ARPHRD_IEEE80211;
+ memset(dev->wep_keys[index], 0, WEP_KEY_SIZE);
+ if(copy_from_user(dev->wep_keys[index],
+ wrq->u.encoding.pointer, len)) {
+ dev->wep_keys_len[index] = 0;
+ ret = -EFAULT;
+ }else{
+ dev->wep_keys_len[index] =
+ len <= WEP_SMALL_KEY_LEN ?
+ WEP_SMALL_KEY_LEN : WEP_LARGE_KEY_LEN;
+#if 0
+ printk(KERN_DEBUG "%s: new key index %d, len %d: ",
+ dev->netdev->name, index, dev->wep_keys_len[index]);
+#endif
+ dev->wep_enabled = 1;
+ }
+ }
+
+ dev->wep_key_id = index;
+ dev->wep_enabled = ((wrq->u.encoding.flags & IW_ENCODE_DISABLED) == 0);
+ if (wrq->u.encoding.flags & IW_ENCODE_RESTRICTED)
+ dev->wep_excl_unencr = 1;
+ if (wrq->u.encoding.flags & IW_ENCODE_OPEN)
+ dev->wep_excl_unencr = 0;
+#if 1
+ printk(KERN_DEBUG "%s: new wepstate: enabled %d key_id %d key_len %d "
+ "excl_unencr %d\n",
+ dev->netdev->name, dev->wep_enabled, dev->wep_key_id,
+ dev->wep_keys_len[dev->wep_key_id],
+ dev->wep_excl_unencr);
+#endif
}
- } else {
- dbg(DBG_MONITOR_MODE, "%s: MONITOR MODE OFF",
- dev->netdev->name);
- dev->netdev->type = ARPHRD_ETHER;
- }
-} /* set_monitor_mode */
-
-static int at76c503_iw_handler_PRIV_IOCTL_SET_MONITOR_MODE
- (struct net_device *netdev, struct iw_request_info *info,
- char *name, char *extra)
-{
- struct at76c503 *dev = (struct at76c503*)netdev->priv;
- int *params = ((int *)name);
- int mode = params[0];
- int channel = params[1];
- int ret = 0;
-
- dbg(DBG_IOCTL, "%s: PRIV_IOCTL_SET_MONITOR_MODE - mode %d ch %d",
- netdev->name, mode, channel);
-
- if (mode != MM_OFF && mode != MM_ON && mode != MM_ON_NO_PRISM)
- ret = -EINVAL;
- else {
- if (mode != MM_OFF) {
- if ((channel >= 1) &&
- (channel <= (sizeof(channel_frequency) /
- sizeof(channel_frequency[0]))))
- /* INFO: This doesn't actually affect the scan */
- dev->channel = channel;
-
- dev->monitor_prism_header = (mode == MM_ON);
+ break;
- if (dev->iw_mode != IW_MODE_MONITOR) {
- ret = -EIWCOMMIT;
- dev->iw_mode = IW_MODE_MONITOR;
- }
- } else {
- /* mode == MM_OFF */
- if (dev->iw_mode == IW_MODE_MONITOR) {
- ret = -EIWCOMMIT;
- dev->iw_mode = IW_MODE_INFRA;
+ // Get the WEP keys and mode
+ case SIOCGIWENCODE:
+ dbg("%s: SIOCGIWENCODE", netdev->name);
+ {
+ int index = (wrq->u.encoding.flags & IW_ENCODE_INDEX) - 1;
+ if ((index < 0) || (index >= NR_WEP_KEYS))
+ index = dev->wep_key_id;
+
+ wrq->u.encoding.flags =
+ (dev->wep_excl_unencr) ? IW_ENCODE_RESTRICTED : IW_ENCODE_OPEN;
+ if(!dev->wep_enabled)
+ wrq->u.encoding.flags |= IW_ENCODE_DISABLED;
+ if(wrq->u.encoding.pointer){
+ wrq->u.encoding.length = dev->wep_keys_len[index];
+ if (copy_to_user(wrq->u.encoding.pointer,
+ dev->wep_keys[index],
+ dev->wep_keys_len[index]))
+ ret = -EFAULT;
+ wrq->u.encoding.flags |= (index + 1);
}
}
- set_monitor_mode(dev, dev->monitor_prism_header);
+ break;
+
+ default:
+ dbg("%s: not supported (%ux)", netdev->name, cmd);
+ ret = -EOPNOTSUPP;
}
+ error:
+ up(&dev->sem);
return ret;
}
-/*******************************************************************************
- * structure that advertises the iw handlers of this driver
- */
-static const iw_handler at76c503_handlers[] =
-{
- [SIOCSIWCOMMIT-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_commit,
- [SIOCGIWNAME -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_name,
- [SIOCSIWFREQ -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_freq,
- [SIOCGIWFREQ -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_freq,
- [SIOCSIWMODE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_mode,
- [SIOCGIWMODE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_mode,
- [SIOCGIWRANGE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_range,
- [SIOCSIWSPY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_spy,
- [SIOCGIWSPY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_spy,
- [SIOCSIWTHRSPY-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_thrspy,
- [SIOCGIWTHRSPY-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_thrspy,
- [SIOCSIWAP -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_wap,
- [SIOCGIWAP -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_wap,
- [SIOCSIWSCAN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_scan,
- [SIOCGIWSCAN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_scan,
- [SIOCSIWESSID -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_essid,
- [SIOCGIWESSID -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_essid,
- [SIOCSIWNICKN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_nickname,
- [SIOCGIWNICKN -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_nickname,
- [SIOCSIWRATE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_rate,
- [SIOCGIWRATE -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_rate,
- [SIOCSIWRTS -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_rts,
- [SIOCGIWRTS -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_rts,
- [SIOCSIWFRAG -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_frag,
- [SIOCGIWFRAG -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_frag,
- [SIOCGIWTXPOW -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_txpow,
- [SIOCSIWRETRY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_retry,
- [SIOCGIWRETRY -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_retry,
- [SIOCSIWENCODE-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_encode,
- [SIOCGIWENCODE-SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_encode,
- [SIOCSIWPOWER -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_set_power,
- [SIOCGIWPOWER -SIOCIWFIRST] = (iw_handler) at76c503_iw_handler_get_power,
-};
-
-/*******************************************************************************
- * structure that advertises the private iw handlers of this driver
- */
-static const iw_handler at76c503_priv_handlers[] =
-{
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_SHORT_PREAMBLE,
- (iw_handler) NULL,
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_DEBUG,
- (iw_handler) NULL,
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_POWERSAVE_MODE,
- (iw_handler) NULL,
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_TIMES,
- (iw_handler) NULL,
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_SCAN_MODE,
- (iw_handler) NULL,
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_INTL_ROAMING,
- (iw_handler) NULL,
- (iw_handler) at76c503_iw_handler_PRIV_IOCTL_SET_MONITOR_MODE,
- (iw_handler) NULL,
-};
-
-static const struct iw_handler_def at76c503_handler_def =
-{
- .num_standard = sizeof(at76c503_handlers)/sizeof(iw_handler),
- .num_private = sizeof(at76c503_priv_handlers)/sizeof(iw_handler),
- .num_private_args = sizeof(at76c503_priv_args)/
- sizeof(struct iw_priv_args),
- .standard = (iw_handler *) at76c503_handlers,
- .private = (iw_handler *) at76c503_priv_handlers,
- .private_args = (struct iw_priv_args *) at76c503_priv_args,
-#if WIRELESS_EXT > 16
- .get_wireless_stats = at76c503_get_wireless_stats,
-#endif
-#if WIRELESS_EXT == 15 || WIRELESS_EXT == 16
- .spy_offset = offsetof(struct at76c503, spy_data),
-#endif
-};
-
-
-static void at76c503_ethtool_get_drvinfo(struct net_device *netdev,
- struct ethtool_drvinfo *info)
-{
- struct at76c503 *dev = (struct at76c503 *)netdev->priv;
-
- strncpy(info->driver, DRIVER_NAME, sizeof(info->driver) - 1);
-
- strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
- info->version[sizeof(info->version)-1] = '\0';
-
- snprintf(info->bus_info, sizeof(info->bus_info) - 1, "usb%d:%d",
- dev->udev->bus->busnum, dev->udev->devnum);
-
- snprintf(info->fw_version, sizeof(info->fw_version) - 1,
- "%d.%d.%d-%d",
- dev->fw_version.major, dev->fw_version.minor,
- dev->fw_version.patch, dev->fw_version.build);
-}
-
-static u32 at76c503_ethtool_get_link(struct net_device *netdev)
-{
- struct at76c503 *dev = netdev->priv;
- return dev->istate == CONNECTED;
-}
-
-static struct ethtool_ops at76c503_ethtool_ops = {
- .get_drvinfo = at76c503_ethtool_get_drvinfo,
- .get_link = at76c503_ethtool_get_link,
-};
-
-
-static void at76c503_delete_device(struct at76c503 *dev)
+static inline void at76c503_delete(struct at76c503 *dev)
{
- int i;
-
- if (!dev)
- return;
-
- /* signal to _stop() that the device is gone */
- dev->device_unplugged = 1;
-
- dbg(DBG_PROC_ENTRY, "%s: ENTER",__FUNCTION__);
+ if(dev){
+ if(dev->bulk_in_buffer != NULL)
+ kfree(dev->bulk_in_buffer);
+ if(dev->bulk_out_buffer != NULL)
+ kfree(dev->bulk_out_buffer);
+ if(dev->ctrl_buffer != NULL)
+ kfree(dev->ctrl_buffer);
- if (dev->netdev_registered) {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 17)
- if (down_trylock(&rtnl_sem) != 0) {
-#else
- if (rtnl_trylock() == 0) {
-#endif
- info("%s: rtnl_sem already down'ed", __FUNCTION__);
- } else {
- /* synchronously calls at76c503_stop() */
- unregister_netdevice(dev->netdev);
- rtnl_unlock();
- }
- }
-
- PUT_DEV(dev->udev);
-
- /* assuming we used keventd, it must quiesce too */
- flush_scheduled_work ();
-
- if(dev->bulk_out_buffer != NULL)
- kfree(dev->bulk_out_buffer);
-
- kfree(dev->ctrl_buffer);
-
- if(dev->write_urb != NULL) {
- usb_kill_urb(dev->write_urb);
- usb_free_urb(dev->write_urb);
- }
- if(dev->read_urb != NULL) {
- usb_kill_urb(dev->read_urb);
- usb_free_urb(dev->read_urb);
- }
- if(dev->ctrl_buffer != NULL) {
- usb_kill_urb(dev->ctrl_urb);
- usb_free_urb(dev->ctrl_urb);
- }
-
- dbg(DBG_PROC_ENTRY,"%s: unlinked urbs",__FUNCTION__);
-
- if(dev->rx_skb != NULL)
- kfree_skb(dev->rx_skb);
-
- free_bss_list(dev);
- del_timer_sync(&dev->bss_list_timer);
-
- LOCK_ISTATE()
- if (dev->istate == CONNECTED) {
- UNLOCK_ISTATE()
- iwevent_bss_disconnect(dev->netdev);
- } else UNLOCK_ISTATE()
-
- for(i=0; i < NR_RX_DATA_BUF; i++)
- if (dev->rx_data[i].skb != NULL) {
- dev_kfree_skb(dev->rx_data[i].skb);
- dev->rx_data[i].skb = NULL;
- }
- dbg(DBG_PROC_ENTRY, "%s: before freeing dev/netdev", __FUNCTION__);
- free_netdev(dev->netdev); /* dev is in net_dev */
-#ifdef CONFIG_IPAQ_HANDHELD
- if (machine_is_h5400()) {
- ipaq_led_off (RED_LED);
- ipaq_led_off (RED_LED_2);
+ if(dev->write_urb != NULL)
+ usb_free_urb(dev->write_urb);
+ if(dev->read_urb != NULL)
+ usb_free_urb(dev->read_urb);
+ if(dev->ctrl_buffer != NULL)
+ usb_free_urb(dev->ctrl_urb);
+
+ kfree (dev->netdev); /* dev is in net_dev */
}
-#endif
- dbg(DBG_PROC_ENTRY, "%s: EXIT", __FUNCTION__);
}
static int at76c503_alloc_urbs(struct at76c503 *dev)
{
struct usb_interface *interface = dev->interface;
+ struct usb_interface_descriptor *iface_desc = &interface->altsetting[0];
struct usb_endpoint_descriptor *endpoint;
struct usb_device *udev = dev->udev;
int i, buffer_size;
- dbg(DBG_PROC_ENTRY, "%s: ENTER", __FUNCTION__);
-
- dbg(DBG_URB, "%s: NumEndpoints %d ", __FUNCTION__, NUM_EP(interface));
-
- for(i = 0; i < NUM_EP(interface); i++) {
- endpoint = &EP(interface,i);
-
- dbg(DBG_URB, "%s: %d. endpoint: addr x%x attr x%x",
- __FUNCTION__,
- i,
- endpoint->bEndpointAddress,
- endpoint->bmAttributes);
+ for(i = 0; i < iface_desc->bNumEndpoints; i++) {
+ endpoint = &iface_desc->endpoint[i];
if ((endpoint->bEndpointAddress & 0x80) &&
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found a bulk in endpoint */
- dev->read_urb = usb_alloc_urb(0, GFP_KERNEL);
+ dev->read_urb = usb_alloc_urb(0);
if (!dev->read_urb) {
err("No free urbs available");
return -1;
}
+ buffer_size = sizeof(struct at76c503_rx_buffer);
+ dev->bulk_in_size = buffer_size;
dev->bulk_in_endpointAddr = endpoint->bEndpointAddress;
+ dev->bulk_in_buffer = kmalloc (buffer_size, GFP_KERNEL);
+ if (!dev->bulk_in_buffer) {
+ err("Couldn't allocate bulk_in_buffer");
+ return -1;
+ }
+ FILL_BULK_URB(dev->read_urb, udev,
+ usb_rcvbulkpipe(udev,
+ endpoint->bEndpointAddress),
+ dev->bulk_in_buffer, buffer_size,
+ at76c503_read_bulk_callback, dev);
}
if (((endpoint->bEndpointAddress & 0x80) == 0x00) &&
((endpoint->bmAttributes & 3) == 0x02)) {
/* we found a bulk out endpoint */
- dev->write_urb = usb_alloc_urb(0, GFP_KERNEL);
+ dev->write_urb = usb_alloc_urb(0);
if (!dev->write_urb) {
err("no free urbs available");
return -1;
}
- buffer_size = sizeof(struct at76c503_tx_buffer) +
- MAX_PADDING_SIZE;
+ buffer_size = sizeof(struct at76c503_tx_buffer);
dev->bulk_out_size = buffer_size;
dev->bulk_out_endpointAddr = endpoint->bEndpointAddress;
dev->bulk_out_buffer = kmalloc (buffer_size, GFP_KERNEL);
@@ -6585,11 +2984,11 @@ static int at76c503_alloc_urbs(struct at76c503 *dev)
usb_sndbulkpipe(udev,
endpoint->bEndpointAddress),
dev->bulk_out_buffer, buffer_size,
- (usb_complete_t)at76c503_write_bulk_callback, dev);
+ at76c503_write_bulk_callback, dev);
}
}
- dev->ctrl_urb = usb_alloc_urb(0, GFP_KERNEL);
+ dev->ctrl_urb = usb_alloc_urb(0);
if (!dev->ctrl_urb) {
err("no free urbs available");
return -1;
@@ -6600,114 +2999,82 @@ static int at76c503_alloc_urbs(struct at76c503 *dev)
return -1;
}
- dbg(DBG_PROC_ENTRY, "%s: EXIT", __FUNCTION__);
-
return 0;
}
-static struct at76c503 *alloc_new_device(struct usb_device *udev,
- int board_type,
- const char *netdev_name)
+static void *at76c503_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
{
struct net_device *netdev;
struct at76c503 *dev = NULL;
- int i;
+ struct usb_interface *interface;
+ int ret;
- /* allocate memory for our device state and initialize it */
+ /* allocate memory for our device state and intialize it */
netdev = alloc_etherdev(sizeof(struct at76c503));
if (netdev == NULL) {
err("out of memory");
- return NULL;
+ goto error;
}
dev = (struct at76c503 *)netdev->priv;
- memset(dev, 0, sizeof(*dev));
-
dev->udev = udev;
dev->netdev = netdev;
init_MUTEX (&dev->sem);
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 20)
- INIT_WORK (&dev->kevent, (void (*)(void *))kevent, &dev->kevent);
-#else
- INIT_WORK (&dev->kevent, kevent);
-#endif
-
- dev->open_count = 0;
-
- init_timer(&dev->restart_timer);
- dev->restart_timer.data = (unsigned long)dev;
- dev->restart_timer.function = restart_timeout;
+ INIT_TQUEUE (&dev->kevent, kevent, dev);
init_timer(&dev->mgmt_timer);
dev->mgmt_timer.data = (unsigned long)dev;
dev->mgmt_timer.function = mgmt_timeout;
-
- init_timer(&dev->fw_dl_timer);
- dev->fw_dl_timer.data = (unsigned long)dev;
- dev->fw_dl_timer.function = fw_dl_timeout;
-
-
- spin_lock_init(&dev->mgmt_spinlock);
- spin_lock_init(&dev->istate_spinlock);
+ dev->mgmt_spinlock = SPIN_LOCK_UNLOCKED;
dev->next_mgmt_bulk = NULL;
- dev->istate = INTFW_DOWNLOAD;
-
- /* initialize empty BSS list */
- dev->curr_bss = dev->new_bss = NULL;
- INIT_LIST_HEAD(&dev->bss_list);
- spin_lock_init(&dev->bss_list_spinlock);
-
- init_timer(&dev->bss_list_timer);
- dev->bss_list_timer.data = (unsigned long)dev;
- dev->bss_list_timer.function = bss_list_timeout;
-
- spin_lock_init(&dev->spy_spinlock);
-
- /* mark all rx data entries as unused */
- for(i=0; i < NR_RX_DATA_BUF; i++)
- dev->rx_data[i].skb = NULL;
+ dev->istate = INIT;
+ dev->curr_bss = dev->new_bss = -1;
dev->tasklet.func = rx_tasklet;
dev->tasklet.data = (unsigned long)dev;
- dev->board_type = board_type;
-
- dev->pm_mode = pm_mode;
- dev->pm_period_us = pm_period;
-
- dev_alloc_name(netdev, netdev_name);
-
- return dev;
-} /* alloc_new_device */
-
-/* == PROC init_new_device ==
- firmware got downloaded, we can continue with init */
-/* We may have to move the register_netdev into alloc_new_device,
- because hotplug may try to configure the netdev _before_
- (or parallel to) the download of firmware */
-static int init_new_device(struct at76c503 *dev)
-{
- struct net_device *netdev = dev->netdev;
- int ret;
+ if((ret = usb_get_configuration(udev)) != 0) {
+ err("get configuration failed: %d", ret);
+ goto error;
+ }
+
+ if ((ret = usb_set_configuration(udev, 1)) != 0) {
+ err("set configuration to 1 failed: %d", ret);
+ goto error;
+ }
/* set up the endpoint information */
/* check out the endpoints */
+ interface = &udev->actconfig->interface[0];
+ dev->interface = interface;
- dev->interface = dev->udev->actconfig->interface[0];
-
- dbg(DBG_DEVSTART, "USB interface: %d endpoints",
- NUM_EP(dev->interface));
-
+ ret = get_op_mode(dev);
+ if(ret < 0){
+ err("getting op mode failed: is the firmware loaded?");
+ goto error;
+ }
-#ifdef CONFIG_IPAQ_HANDHELD
- if (machine_is_h5400 ())
- ipaq_init_led ();
-#endif
+ if(dev->op_mode == 0){
+ err("firmware is not loaded");
+ goto error;
+ }
if(at76c503_alloc_urbs(dev) < 0)
goto error;
+ /* download external firmware */
+ /* checking for presence of ext. fw by eg. checking the version does not work:
+ if it's not present, just the get_mib command will fubar the device,
+ so that not even usb_clear_halt() helps.
+ But it does not seem to hurt if we reload the ext. fw again. (oku)
+ */
+ ret = download_external_fw(dev->udev, ExternalRFMD, sizeof(ExternalRFMD));
+ if(ret < 0){
+ err("downloading external firmware failed: %d", ret);
+ goto error;
+ }
+
/* get firmware version */
ret = get_mib(dev->udev, MIB_FW_VERSION, (u8*)&dev->fw_version, sizeof(dev->fw_version));
if((ret < 0) || ((dev->fw_version.major == 0) &&
@@ -6718,686 +3085,117 @@ static int init_new_device(struct at76c503 *dev)
err("this probably means that the ext. fw was not loaded correctly");
goto error;
}
-
- /* fw 0.84 doesn't send FCS with rx data */
- if (dev->fw_version.major == 0 && dev->fw_version.minor <= 84)
- dev->rx_data_fcs_len = 0;
- else
- dev->rx_data_fcs_len = 4;
-
- info("firmware version %d.%d.%d #%d (fcs_len %d)",
+ info("firmware version %d.%d.%d #%d",
dev->fw_version.major, dev->fw_version.minor,
- dev->fw_version.patch, dev->fw_version.build,
- dev->rx_data_fcs_len);
+ dev->fw_version.patch, dev->fw_version.build);
/* MAC address */
- ret = get_hw_config(dev);
+ ret = get_hw_cfg(dev->udev, (unsigned char *)&dev->hwcfg.rfmd, sizeof(struct hwcfg_rfmd));
if(ret < 0){
- err("could not get MAC address");
+ err("could not get MAC: get_hw_cfg() failed, ret = %d", ret);
goto error;
}
+ memcpy(netdev->dev_addr, &(dev->hwcfg.rfmd.mac_addr), ETH_ALEN);
+ info("using MAC %s", mac2str(netdev->dev_addr));
- dev->domain = getRegDomain(dev->regulatory_domain);
- /* init. netdev->dev_addr */
- memcpy(netdev->dev_addr, dev->mac_addr, ETH_ALEN);
- info("device's MAC %s, regulatory domain %s (id %d)",
- mac2str(dev->mac_addr), dev->domain->name,
- dev->regulatory_domain);
+ set_mac_address(dev, netdev->dev_addr); /* may have been changed, write back original */
/* initializing */
- dev->international_roaming = international_roaming;
dev->channel = DEF_CHANNEL;
- dev->iw_mode = default_iw_mode;
- dev->monitor_prism_header = 1;
+ dev->iw_mode = IW_MODE_ADHOC;
memset(dev->essid, 0, IW_ESSID_MAX_SIZE);
- memset(dev->nickn, 0, sizeof(dev->nickn));
+ memcpy(dev->essid, DEF_ESSID, DEF_ESSID_LEN);
+ dev->essid_size = DEF_ESSID_LEN;
dev->rts_threshold = DEF_RTS_THRESHOLD;
dev->frag_threshold = DEF_FRAG_THRESHOLD;
- dev->short_retry_limit = DEF_SHORT_RETRY_LIMIT;
- /* dev->long_retr_limit = DEF_LONG_RETRY_LIMIT; */
dev->txrate = TX_RATE_AUTO;
- dev->preamble_type = preamble_type;
- dev->beacon_period = 100;
- dev->beacons_last_qual=jiffies_to_msecs(jiffies);
- dev->auth_mode = auth_mode ? WLAN_AUTH_SHARED_KEY :
- WLAN_AUTH_OPEN;
- dev->scan_min_time = scan_min_time;
- dev->scan_max_time = scan_max_time;
- dev->scan_mode = scan_mode;
- dev->monitor_scan_min_time = monitor_scan_min_time;
- dev->monitor_scan_max_time = monitor_scan_max_time;
+ dev->preamble_type = PREAMBLE_TYPE_LONG;
netdev->flags &= ~IFF_MULTICAST; /* not yet or never */
netdev->open = at76c503_open;
netdev->stop = at76c503_stop;
netdev->get_stats = at76c503_get_stats;
- netdev->ethtool_ops = &at76c503_ethtool_ops;
-
-#if WIRELESS_EXT > 16
- /* Add pointers to enable iwspy support. */
- dev->wireless_data.spy_data = &dev->spy_data;
- netdev->wireless_data = &dev->wireless_data;
-#else /* WIRELESS_EXT > 16 */
netdev->get_wireless_stats = at76c503_get_wireless_stats;
-#endif /* WIRELESS_EXT > 16 */
-
netdev->hard_start_xmit = at76c503_tx;
netdev->tx_timeout = at76c503_tx_timeout;
- netdev->watchdog_timeo = 2 * HZ;
- netdev->wireless_handlers =
- (struct iw_handler_def*)&at76c503_handler_def;
+ netdev->do_ioctl = at76c503_ioctl;
netdev->set_multicast_list = at76c503_set_multicast;
netdev->set_mac_address = at76c503_set_mac_address;
-
- /* putting this inside rtnl_lock() - rtnl_unlock() hangs modprobe ...? */
- ret = register_netdev(dev->netdev);
- if (ret) {
- err("unable to register netdevice %s (status %d)!",
- dev->netdev->name, ret);
- return -1;
- }
- info("registered %s", dev->netdev->name);
- dev->netdev_registered = 1;
-
- /* we let this timer run the whole time this driver instance lives */
- mod_timer(&dev->bss_list_timer, jiffies+BSS_LIST_TIMEOUT);
-
- return 0;
-
- error:
- at76c503_delete_device(dev);
- return -1;
-
-} /* init_new_device */
-
-
-/* == PROC at76c503_get_fw_info ==
- disassembles the firmware image into version, str,
- internal and external fw part. returns 0 on success, < 0 on error */
-static int at76c503_get_fw_info(u8 *fw_data, int fw_size,
- u32 *board, u32 *version, char **str,
- u8 **int_fw, int *int_fw_size,
- u8 **ext_fw, int *ext_fw_size)
-{
-/* fw structure (all numbers are little_endian)
- offset length description
- 0 4 crc 32 (seed ~0, no post, all gaps are zeros, header included)
- 4 4 board type (see at76c503.h)
- 8 4 version (major<<24|middle<<16|minor<<8|build)
- c 4 offset of printable string (id) area from begin of image
- (must be \0 terminated !)
- 10 4 offset of internal fw part area
- 14 4 length of internal fw part
- 18 4 offset of external fw part area (may be first byte _behind_
- image in case we have no external part)
- 1c 4 length of external fw part
+ strcpy(netdev->name, eth_name);
+ // netdev->hard_header_len = 8 + sizeof(struct ieee802_11_hdr);
+ /*
+// netdev->hard_header = at76c503_header;
*/
+ SET_MODULE_OWNER(netdev);
- __le32 val;
-
- if (fw_size < 0x21) {
- err("fw too short (x%x)",fw_size);
- return -EFAULT;
- }
-
- /* crc currently not checked */
-
- memcpy(&val,fw_data+4,4);
- *board = le32_to_cpu(val);
-
- memcpy(&val,fw_data+8,4);
- *version = le32_to_cpu(val);
-
- memcpy(&val,fw_data+0xc,4);
- *str = fw_data + le32_to_cpu(val);
-
- memcpy(&val,fw_data+0x10,4);
- *int_fw = fw_data + le32_to_cpu(val);
- memcpy(&val,fw_data+0x14,4);
- *int_fw_size = le32_to_cpu(val);
-
- memcpy(&val,fw_data+0x18,4);
- *ext_fw = fw_data + le32_to_cpu(val);
- memcpy(&val,fw_data+0x1c,4);
- *ext_fw_size = le32_to_cpu(val);
-
- return 0;
-}
-
-/* == PROC at76c503_do_probe == */
-static int at76c503_do_probe(struct module *mod, struct usb_device *udev,
- u8 *fw_data, int fw_size, u32 board_type,
- const char *netdev_name)
-{
- struct usb_interface *intf = udev->actconfig->interface[0];
- int ret;
- struct at76c503 *dev = NULL;
- int op_mode;
- char *id_str;
- u32 version;
-
- GET_DEV(udev);
-
- if ((dev=alloc_new_device(udev, (u8)board_type, netdev_name)) == NULL) {
- ret = -ENOMEM;
- goto error;
- }
-
- op_mode = get_op_mode(udev);
-
- usb_set_intfdata(intf, dev);
- dev->interface = intf;
-
- dbg(DBG_DEVSTART, "opmode %d", op_mode);
-
- /* we get OPMODE_NONE with 2.4.23, SMC2662W-AR ???
- we get 204 with 2.4.23, Fiberline FL-WL240u (505A+RFMD2958) ??? */
-
- if (op_mode == OPMODE_HW_CONFIG_MODE) {
- err("cannot handle a device in HW_CONFIG_MODE (opmode %d)", op_mode);
- ret = -ENODEV;
- goto error;
- }
-
- if (op_mode != OPMODE_NORMAL_NIC_WITH_FLASH &&
- op_mode != OPMODE_NORMAL_NIC_WITHOUT_FLASH) {
-
- dbg(DBG_DEVSTART, "need to download firmware");
-
- /* disassem. the firmware */
- if ((ret=at76c503_get_fw_info(fw_data, fw_size, &dev->board_type,
- &version, &id_str,
- &dev->intfw, &dev->intfw_size,
- &dev->extfw, &dev->extfw_size))) {
- goto error;
- }
-
- dbg(DBG_DEVSTART, "firmware board %u version %u.%u.%u#%u "
- "(int %x:%tx, ext %x:%tx)",
- dev->board_type, version>>24,(version>>16)&0xff,
- (version>>8)&0xff, version&0xff,
- dev->intfw_size, dev->intfw-fw_data,
- dev->extfw_size, dev->extfw-fw_data);
- if (*id_str)
- dbg(DBG_DEVSTART, "firmware id %s",id_str);
-
- if (dev->board_type != board_type) {
- err("inconsistent board types %u != %u",
- board_type, dev->board_type);
- at76c503_delete_device(dev);
- goto error;
- }
+ register_netdev(netdev);
- /* download internal firmware part */
- dbg(DBG_DEVSTART, "downloading internal firmware");
- NEW_STATE(dev,INTFW_DOWNLOAD);
- defer_kevent(dev,KEVENT_INTERNAL_FW);
-
- } else {
- /* internal firmware already inside the device */
- /* get firmware version to test if external firmware is loaded */
- /* This works only for newer firmware, e.g. the Intersil 0.90.x
- says "control timeout on ep0in" and subsequent get_op_mode() fail
- too :-( */
- int force_fw_dwl = 0;
-
- /* disassem. the firmware */
- if ((ret=at76c503_get_fw_info(fw_data, fw_size, &dev->board_type,
- &version, &id_str,
- &dev->intfw, &dev->intfw_size,
- &dev->extfw, &dev->extfw_size))) {
- goto error;
- }
-
- /* if version >= 0.100.x.y or device with built-in flash we can query the device
- * for the fw version */
- if (version >= ((0<<24)|(100<<16)) || (op_mode == OPMODE_NORMAL_NIC_WITH_FLASH)) {
- ret = get_mib(udev, MIB_FW_VERSION, (u8*)&dev->fw_version,
- sizeof(dev->fw_version));
- } else {
- /* force fw download only if the device has no flash inside */
- force_fw_dwl = 1;
- }
+ info("using net device %s", netdev->name);
- if ((force_fw_dwl) || (ret < 0) || ((dev->fw_version.major == 0) &&
- (dev->fw_version.minor == 0) &&
- (dev->fw_version.patch == 0) &&
- (dev->fw_version.build == 0))) {
- if (force_fw_dwl)
- dbg(DBG_DEVSTART, "forced download of external firmware part");
- else
- dbg(DBG_DEVSTART, "cannot get firmware (ret %d) or all zeros "
- "- download external firmware", ret);
- dbg(DBG_DEVSTART, "firmware board %u version %u.%u.%u#%u "
- "(int %x:%tx, ext %x:%tx)",
- dev->board_type, version>>24,(version>>16)&0xff,
- (version>>8)&0xff, version&0xff,
- dev->intfw_size, dev->intfw-fw_data,
- dev->extfw_size, dev->extfw-fw_data);
- if (*id_str)
- dbg(DBG_DEVSTART, "firmware id %s",id_str);
-
- if (dev->board_type != board_type) {
- err("inconsistent board types %u != %u",
- board_type, dev->board_type);
- at76c503_delete_device(dev);
- goto error;
- }
+ goto exit;
- NEW_STATE(dev,EXTFW_DOWNLOAD);
- defer_kevent(dev,KEVENT_EXTERNAL_FW);
- } else {
- NEW_STATE(dev,INIT);
- if (init_new_device(dev) < 0) {
- ret = -ENODEV;
- goto error;
- }
- }
- }
-
- SET_NETDEV_DEV(dev->netdev, &intf->dev);
- return 0;
+ error:
+ at76c503_delete(dev);
+ dev = NULL;
-error:
- PUT_DEV(udev);
- return ret;
+ exit:
+ return dev;
}
-/* Firmware names - this must be in sync with boardtype definitions */
-static struct fwentry {
- const char *const fwname;
- const struct firmware *fw;
-} firmwares[] = {
- { "" },
- { "atmel_at76c503-i3861.bin" },
- { "atmel_at76c503-i3863.bin" },
- { "atmel_at76c503-rfmd.bin" },
- { "atmel_at76c503-rfmd-acc.bin" },
- { "atmel_at76c505-rfmd.bin" },
- { "atmel_at76c505-rfmd2958.bin" },
- { "atmel_at76c505a-rfmd2958.bin" },
- { "atmel_at76c505amx-rfmd.bin" }
-};
-
-/* USB Device IDs supported by this driver */
-
-/* at76c503-i3861 */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_503I 0x7603 /* Generic AT76C503/3861 device */
-
-#define VENDOR_ID_LINKSYS_OLD 0x066b
-#define PRODUCT_ID_LINKSYS_WUSB11_V21 0x2211 /* Linksys WUSB11 v2.1/v2.6 */
-
-#define VENDOR_ID_NETGEAR 0x0864
-#define PRODUCT_ID_NETGEAR_MA101A 0x4100 /* Netgear MA 101 Rev. A */
-
-#define VENDOR_ID_TEKRAM 0x0b3b
-#define PRODUCT_ID_TEKRAM_U300C 0x1612 /* Tekram U-300C / Allnet ALL0193 */
-
-#define VENDOR_ID_HP 0x03f0
-#define PRODUCT_ID_HP_HN210W 0x011c /* HP HN210W PKW-J7801A */
-
-#define VENDOR_ID_M4Y750 0x0cde /* Unknown Vendor ID! */
-#define PRODUCT_ID_M4Y750 0x0001 /* Sitecom/Z-Com/Zyxel M4Y-750 */
-
-#define VENDOR_ID_DYNALINK 0x069a
-#define PRODUCT_ID_DYNALINK_WLL013_I 0x0320 /* Dynalink/Askey WLL013 (intersil) */
-
-#define VENDOR_ID_SMC_OLD 0x0d5c
-#define PRODUCT_ID_SMC2662W_V1 0xa001 /* EZ connect 11Mpbs
-Wireless USB Adapter SMC2662W (v1) */
-
-#define VENDOR_ID_BENQ 0x04a5 /* BenQ (Acer) */
-#define PRODUCT_ID_BENQ_AWL_300 0x9000 /* AWL-300 */
-
-/* this adapter contains flash */
-#define VENDOR_ID_ADDTRON 0x05dd /* Addtron */
-#define PRODUCT_ID_ADDTRON_AWU120 0xff31 /* AWU-120 */
-/* also Compex WLU11 */
-
-#define VENDOR_ID_INTEL 0x8086 /* Intel */
-#define PRODUCT_ID_INTEL_AP310 0x0200 /* AP310 AnyPoint II USB */
-
-#define VENDOR_ID_CONCEPTRONIC 0x0d8e
-#define PRODUCT_ID_CONCEPTRONIC_C11U 0x7100 /* also Dynalink L11U */
-
-#define VENDOR_ID_ARESCOM 0xd8e
-#define PRODUCT_ID_WL_210 0x7110 /* Arescom WL-210,
- FCC id 07J-GL2411USB */
-#define VENDOR_ID_IO_DATA 0x04bb
-#define PRODUCT_ID_IO_DATA_WN_B11_USB 0x0919 /* IO-DATA WN-B11/USB */
-
-#define VENDOR_ID_BT 0x069a
-#define PRODUCT_ID_BT_VOYAGER_1010 0x0821 /* BT Voyager 1010 */
-
-
-/* at76c503-i3863 */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_503_I3863 0x7604 /* Generic AT76C503/3863 device */
-
-#define VENDOR_ID_SAMSUNG 0x055d
-#define PRODUCT_ID_SAMSUNG_SWL2100U 0xa000 /* Samsung SWL-2100U */
-
-
-/* at76c503-rfmd */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_503R 0x7605 /* Generic AT76C503/RFMD device */
-#define PRODUCT_ID_W_BUDDIE_WN210 0x4102 /* AirVast W-Buddie WN210 */
-
-#define VENDOR_ID_DYNALINK 0x069a
-#define PRODUCT_ID_DYNALINK_WLL013_R 0x0321 /* Dynalink/Askey WLL013 (rfmd) */
-
-#define VENDOR_ID_LINKSYS 0x077b
-#define PRODUCT_ID_LINKSYS_WUSB11_V26 0x2219 /* Linksys WUSB11 v2.6 */
-#define PRODUCT_ID_NE_NWU11B 0x2227 /* Network Everywhere NWU11B */
-
-#define VENDOR_ID_NETGEAR 0x0864
-#define PRODUCT_ID_NETGEAR_MA101B 0x4102 /* Netgear MA 101 Rev. B */
-
-#define VENDOR_ID_ACTIONTEC 0x1668
-#define PRODUCT_ID_ACTIONTEC_802UAT1 0x7605 /* Actiontec 802UAT1, HWU01150-01UK */
-
-#define VENDOR_ID_DLINK 0x2001 /* D-Link */
-#define PRODUCT_ID_DLINK_DWL120 0x3200 /* DWL-120 rev. E */
-
-#define VENDOR_ID_DICK_SMITH_ELECTR 0x1371 /* Dick Smith Electronics */
-#define PRODUCT_ID_DSE_XH1153 0x5743 /* XH1153 802.11b USB adapter */
- /* also: CNet CNUSB611 (D) */
-#define PRODUCT_ID_WL_200U 0x0002 /* WL-200U */
-
-#define VENDOR_ID_BENQ 0x04a5 /* BenQ (Acer) */
-#define PRODUCT_ID_BENQ_AWL_400 0x9001 /* BenQ AWL-400 USB stick */
-
-#define VENDOR_ID_3COM 0x506
-#define PRODUCT_ID_3COM_3CRSHEW696 0xa01 /* 3COM 3CRSHEW696 */
-
-#define VENDOR_ID_SIEMENS 0x681
-#define PRODUCT_ID_SIEMENS_SANTIS_WLL013 0x1b /* Siemens Santis ADSL WLAN
- USB adapter WLL 013 */
-
-#define VENDOR_ID_BELKIN_2 0x50d
-#define PRODUCT_ID_BELKIN_F5D6050_V2 0x50 /* Belkin F5D6050, version 2 */
-
-#define VENDOR_ID_BLITZ 0x07b8
-#define PRODUCT_ID_BLITZ_NETWAVE_BWU613 0xb000 /* iBlitzz, BWU613 (not *B or *SB !) */
-
-#define VENDOR_ID_GIGABYTE 0x1044
-#define PRODUCT_ID_GIGABYTE_GN_WLBM101 0x8003 /* Gigabyte GN-WLBM101 */
-
-#define VENDOR_ID_PLANEX 0x2019
-#define PRODUCT_ID_PLANEX_GW_US11S 0x3220 /* Planex GW-US11S */
-
-#define VENDOR_ID_COMPAQ 0x049f
-#define PRODUCT_ID_IPAQ_INT_WLAN 0x0032 /* internal WLAN adapter in h5[4,5]xx series iPAQs */
-
-
-/* at76c503-rfmd-acc */
-#define VENDOR_ID_BELKIN 0x0d5c
-#define PRODUCT_ID_BELKIN_F5D6050 0xa002 /* Belkin F5D6050 / SMC 2662W v2 / SMC 2662W-AR */
-
-#define VENDOR_ID_SMC 0x083a
-#define PRODUCT_ID_SMC_2664W 0x3501
-
-
-/* at76c505-rfmd */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_505R 0x7606 /* Generic AT76C505/RFMD device */
-
-
-/* at76c505-rfmd2958 */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_505R2958 0x7613 /* Generic AT76C505/RFMD device
- also OvisLink WL-1130USB */
-
-#define VENDOR_ID_CNET 0x1371
-#define PRODUCT_ID_CNET_CNUSB611G 0x0013 /* CNet CNUSB 611G */
-#define PRODUCT_ID_FL_WL240U 0x0014 /* Fiberline WL-240U with the
- CNet vendor id */
-
-#define VENDOR_ID_LINKSYS_1915 0x1915
-#define PRODUCT_ID_LINKSYS_WUSB11V28 0x2233 /* Linksys WUSB11 v2.8 */
-
-#define VENDOR_ID_XTERASYS 0x12fd
-#define PRODUCT_ID_XTERASYS_XN_2122B 0x1001 /* Xterasys XN-2122B, also
- IBlitzz BWU613B / BWU613SB */
-
-#define VENDOR_ID_COREGA 0x07aa
-#define PRODUCT_ID_COREGA_USB_STICK_11_KK 0x7613 /* Corega WLAN USB Stick 11 (K.K.) */
-
-#define VENDOR_ID_MSI 0x0db0
-#define PRODUCT_ID_MSI_MS6978_WLAN_BOX_PC2PC 0x1020
-
-
-/* at76c505a-rfmd2958 */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_505A 0x7614 /* Generic AT76C505A device */
-#define PRODUCT_ID_ATMEL_505AS 0x7617 /* Generic AT76C505AS device */
-
-#define VENDOR_ID_GIGASET 0x1690
-#define PRODUCT_ID_GIGASET_11 0x0701
-
-
-/* at76c505amx-rfmd */
-#define VENDOR_ID_ATMEL 0x03eb
-#define PRODUCT_ID_ATMEL_505AMX 0x7615 /* Generic AT76C505AMX device */
-
-
-static struct usb_device_id dev_table[] = {
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503I ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_LINKSYS_OLD, PRODUCT_ID_LINKSYS_WUSB11_V21),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_NETGEAR, PRODUCT_ID_NETGEAR_MA101A ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_TEKRAM, PRODUCT_ID_TEKRAM_U300C ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_HP, PRODUCT_ID_HP_HN210W ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_M4Y750, PRODUCT_ID_M4Y750 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_DYNALINK, PRODUCT_ID_DYNALINK_WLL013_I ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_SMC_OLD, PRODUCT_ID_SMC2662W_V1 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_BENQ, PRODUCT_ID_BENQ_AWL_300 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_ADDTRON, PRODUCT_ID_ADDTRON_AWU120 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_INTEL, PRODUCT_ID_INTEL_AP310 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_CONCEPTRONIC,PRODUCT_ID_CONCEPTRONIC_C11U),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_ARESCOM, PRODUCT_ID_WL_210),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_IO_DATA, PRODUCT_ID_IO_DATA_WN_B11_USB),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
- { USB_DEVICE(VENDOR_ID_BT, PRODUCT_ID_BT_VOYAGER_1010 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3861 },
-
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503_I3863 ),
- .driver_info = BOARDTYPE_503_INTERSIL_3863 },
- { USB_DEVICE(VENDOR_ID_SAMSUNG, PRODUCT_ID_SAMSUNG_SWL2100U),
- .driver_info = BOARDTYPE_503_INTERSIL_3863 },
-
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_503R ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_DYNALINK, PRODUCT_ID_DYNALINK_WLL013_R ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_LINKSYS, PRODUCT_ID_LINKSYS_WUSB11_V26),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_LINKSYS, PRODUCT_ID_NE_NWU11B ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_NETGEAR, PRODUCT_ID_NETGEAR_MA101B ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_DLINK, PRODUCT_ID_DLINK_DWL120 ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_ACTIONTEC,PRODUCT_ID_ACTIONTEC_802UAT1 ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_W_BUDDIE_WN210 ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_DICK_SMITH_ELECTR, PRODUCT_ID_DSE_XH1153),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_DICK_SMITH_ELECTR, PRODUCT_ID_WL_200U),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_BENQ, PRODUCT_ID_BENQ_AWL_400),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_3COM, PRODUCT_ID_3COM_3CRSHEW696),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_SIEMENS, PRODUCT_ID_SIEMENS_SANTIS_WLL013),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_BELKIN_2, PRODUCT_ID_BELKIN_F5D6050_V2 ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_BLITZ, PRODUCT_ID_BLITZ_NETWAVE_BWU613 ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_GIGABYTE, PRODUCT_ID_GIGABYTE_GN_WLBM101 ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_PLANEX, PRODUCT_ID_PLANEX_GW_US11S ),
- .driver_info = BOARDTYPE_503_RFMD },
- { USB_DEVICE(VENDOR_ID_COMPAQ, PRODUCT_ID_IPAQ_INT_WLAN),
- .driver_info = BOARDTYPE_503_RFMD },
-
- { USB_DEVICE(VENDOR_ID_SMC, PRODUCT_ID_SMC_2664W),
- .driver_info = BOARDTYPE_503_RFMD_ACC },
- { USB_DEVICE(VENDOR_ID_BELKIN, PRODUCT_ID_BELKIN_F5D6050 ),
- .driver_info = BOARDTYPE_503_RFMD_ACC },
-
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505R ),
- .driver_info = BOARDTYPE_505_RFMD },
-
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505R2958 ),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_CNET, PRODUCT_ID_FL_WL240U ),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_CNET, PRODUCT_ID_CNET_CNUSB611G ),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_LINKSYS_1915, PRODUCT_ID_LINKSYS_WUSB11V28 ),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_XTERASYS, PRODUCT_ID_XTERASYS_XN_2122B ),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_COREGA, PRODUCT_ID_COREGA_USB_STICK_11_KK ),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_MSI, PRODUCT_ID_MSI_MS6978_WLAN_BOX_PC2PC),
- .driver_info = BOARDTYPE_505_RFMD_2958 },
-
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505A ),
- .driver_info = BOARDTYPE_505A_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505AS ),
- .driver_info = BOARDTYPE_505A_RFMD_2958 },
- { USB_DEVICE(VENDOR_ID_GIGASET, PRODUCT_ID_GIGASET_11 ),
- .driver_info = BOARDTYPE_505A_RFMD_2958 },
-
- { USB_DEVICE(VENDOR_ID_ATMEL, PRODUCT_ID_ATMEL_505AMX ),
- .driver_info = BOARDTYPE_505AMX_RFMD },
-
- { }
-};
-
-MODULE_DEVICE_TABLE (usb, dev_table);
-
-
-static int at76c50x_probe(struct usb_interface *interface,
- const struct usb_device_id *id)
+/**
+ * at76c503_disconnect
+ *
+ * Called by the usb core when the device is removed from the system.
+ */
+static void at76c503_disconnect(struct usb_device *udev, void *ptr)
{
- int retval;
-
- struct usb_device *udev;
- int boardtype = (int)id->driver_info;
- const char *const fw_name = firmwares[boardtype].fwname;
- const struct firmware *fw = firmwares[boardtype].fw;
- udev = interface_to_usbdev(interface);
-
- if (fw == NULL) {
- dbg(DBG_FW, "downloading firmware %s", fw_name);
- retval = request_firmware(&fw, fw_name, &udev->dev);
- if (retval == 0) {
- dbg(DBG_FW, "got it.");
- } else {
- err("firmware %s not found.", fw_name);
- err("You may need to download the firmware from "
- "https://developer.berlios.de/projects/at76c503a/");
- return retval;
- }
- } else
- dbg(DBG_FW, "re-using previously loaded fw");
-
- retval = at76c503_do_probe(THIS_MODULE, udev,
- fw->data, fw->size,
- boardtype, netdev_name);
- return retval;
-}
+ struct at76c503 *dev;
-static void at76c50x_disconnect(struct usb_interface *interface)
-{
- struct at76c503 *ptr;
+ dbg("udev=%p, ptr=%p", udev, ptr);
- ptr = usb_get_intfdata (interface);
- usb_set_intfdata(interface, NULL);
+ dev = (struct at76c503 *)ptr;
+
+ unregister_netdev(dev->netdev);
+ at76c503_delete(dev);
- info("%s disconnecting", ((struct at76c503 *)ptr)->netdev->name);
- at76c503_delete_device(ptr);
- info(DRIVER_NAME " disconnected");
+ info("at76c503 now disconnected");
}
-/* structure for registering this driver with the USB subsystem */
-static struct usb_driver module_usb = {
-#if LINUX_VERSION_CODE < KERNEL_VERSION(2,6,16)
- .owner = THIS_MODULE,
-#endif
- .name = DRIVER_NAME,
- .probe = at76c50x_probe,
- .disconnect = at76c50x_disconnect,
- .id_table = dev_table,
-};
-
-
-static int __init mod_init(void)
+/**
+ * at76c503_usb_init
+ */
+static int __init at76c503_init(void)
{
int result;
- info(DRIVER_DESC " " DRIVER_VERSION " loading");
-
-#ifdef CONFIG_IPAQ_HANDHELD
- if (machine_is_h5400()) {
- /* turn WLAN power on */
- /* both needed? */
- SET_H5400_ASIC_GPIO (GPB, RF_POWER_ON, 1);
- SET_H5400_ASIC_GPIO (GPB, WLAN_POWER_ON, 1);
- }
-#endif
+ info(DRIVER_DESC " " DRIVER_VERSION);
+ usbdfu_register(&at76c503_driver, InternalRFMD, sizeof(InternalRFMD));
/* register this driver with the USB subsystem */
- result = usb_register(&module_usb);
+ result = usb_register(&at76c503_driver);
+ info("driver registered");
if (result < 0) {
- err("usb_register failed (status %d)", result);
+ err("usb_register failed for the "__FILE__" driver. Error number %d",
+ result);
return -1;
}
-
return 0;
}
-static void __exit mod_exit(void)
+/**
+ * at76c503_usb_exit
+ */
+static void __exit at76c503_exit(void)
{
- int i;
-
- info(DRIVER_DESC " " DRIVER_VERSION " unloading");
- usb_deregister(&module_usb);
- for (i = 0; i < ARRAY_SIZE(firmwares); i++) {
- if (firmwares[i].fw)
- release_firmware(firmwares[i].fw);
- }
-
-#ifdef CONFIG_IPAQ_HANDHELD
- if (machine_is_h5400()) {
- /* turn WLAN power off */
- SET_H5400_ASIC_GPIO (GPB, RF_POWER_ON, 0);
- SET_H5400_ASIC_GPIO (GPB, WLAN_POWER_ON, 0);
- }
-#endif
+ info(DRIVER_DESC " " DRIVER_VERSION "exit");
+ /* deregister this driver with the USB subsystem */
+ usbdfu_deregister(&at76c503_driver);
+ usb_deregister(&at76c503_driver);
}
-module_init(mod_init);
-module_exit(mod_exit);
+module_init (at76c503_init);
+module_exit (at76c503_exit);
MODULE_AUTHOR(DRIVER_AUTHOR);
MODULE_DESCRIPTION(DRIVER_DESC);
diff --git a/at76c503.h b/at76c503.h
index 0d36bbb..1149761 100644
--- a/at76c503.h
+++ b/at76c503.h
@@ -1,53 +1,16 @@
/* -*- linux-c -*- */
/*
- * Copyright (c) 2002 - 2003 Oliver Kurth
- * (c) 2003 - 2004 Jörg Albert <joerg.albert@gmx.de>
+ * USB at76c503 driver
+ *
+ * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx>
*
* This program is free software; you can redistribute it and/or
* modify it under the terms of the GNU General Public License as
* published by the Free Software Foundation; either version 2 of
* the License, or (at your option) any later version.
*
- * This driver was based on information from the Sourceforge driver
- * released and maintained by Atmel:
- *
- * http://sourceforge.net/projects/atmelwlandriver/
- *
- * Although the code was completely re-written,
- * it would have been impossible without Atmel's decision to
- * release an Open Source driver (unfortunately the firmware was
- * kept binary only). Thanks for that decision to Atmel!
- *
- * For the latest version of this driver, mailinglists
- * and other info, please check
- * http://at76c503a.berlios.de/
*/
-#ifndef _AT76C503_H
-#define _AT76C503_H
-
-#include <net/ieee80211.h>
-
-/* current driver version */
-#define DRIVER_VERSION "0.14dev"
-
-
-/* our private ioctl's */
-/* set preamble length*/
-#define PRIV_IOCTL_SET_SHORT_PREAMBLE (SIOCIWFIRSTPRIV + 0x0)
-/* set debug parameter */
-#define PRIV_IOCTL_SET_DEBUG (SIOCIWFIRSTPRIV + 0x2)
-/* set power save mode (incl. the Atmel proprietary smart save mode */
-#define PRIV_IOCTL_SET_POWERSAVE_MODE (SIOCIWFIRSTPRIV + 0x4)
-/* set min and max channel times for scan */
-#define PRIV_IOCTL_SET_SCAN_TIMES (SIOCIWFIRSTPRIV + 0x6)
-/* set scan mode */
-#define PRIV_IOCTL_SET_SCAN_MODE (SIOCIWFIRSTPRIV + 0x8)
-/* set international roaming */
-#define PRIV_IOCTL_SET_INTL_ROAMING (SIOCIWFIRSTPRIV + 0x10)
-/* set monitor mode */
-#define PRIV_IOCTL_SET_MONITOR_MODE (SIOCIWFIRSTPRIV + 0x12)
-
#define DEVICE_VENDOR_REQUEST_OUT 0x40
#define DEVICE_VENDOR_REQUEST_IN 0xc0
#define INTERFACE_VENDOR_REQUEST_OUT 0x41
@@ -65,13 +28,6 @@
#define CMD_STATUS_HOST_FAILURE 0xff
#define CMD_STATUS_SCAN_FAILED 0xf0
-/* answers to get op mode */
-#define OPMODE_NONE 0x00
-#define OPMODE_NORMAL_NIC_WITH_FLASH 0x01
-#define OPMODE_HW_CONFIG_MODE 0x02
-#define OPMODE_DFU_MODE_WITH_FLASH 0x03
-#define OPMODE_NORMAL_NIC_WITHOUT_FLASH 0x04
-
#define CMD_SET_MIB 0x01
#define CMD_GET_MIB 0x02
#define CMD_SCAN 0x03
@@ -79,7 +35,6 @@
#define CMD_START_IBSS 0x05
#define CMD_RADIO 0x06
#define CMD_STARTUP 0x0B
-#define CMD_GETOPMODE 0x33
#define MIB_LOCAL 0x01
#define MIB_MAC_ADD 0x02
@@ -104,21 +59,6 @@
#define TX_RATE_11MBIT 3
#define TX_RATE_AUTO 4
-/* power management modes */
-#define PM_ACTIVE 1
-#define PM_SAVE 2
-#define PM_SMART_SAVE 3
-
-/* international roaming state */
-#define IR_OFF 0
-#define IR_ON 1
-
-/* monitor mode - param of private ioctl */
-#define MM_OFF 0
-#define MM_ON 1
-#define MM_ON_NO_PRISM 2
-
-
/* offsets into the MIBs we use to configure the device */
#define TX_AUTORATE_FALLBACK_OFFSET offsetof(struct mib_local,txautorate_fallback)
#define FRAGMENTATION_OFFSET offsetof(struct mib_mac,frag_threshold)
@@ -127,24 +67,8 @@
/* valid only for rfmd and 505 !*/
#define IBSS_CHANGE_OK_OFFSET offsetof(struct mib_mac_mgmt, ibss_change)
-#define IROAMING_IMPL_OFFSET offsetof(struct mib_mac_mgmt, multi_domain_capability_implemented)
#define IROAMING_OFFSET \
offsetof(struct mib_mac_mgmt, multi_domain_capability_enabled)
-/* the AssocID */
-#define STATION_ID_OFFSET offsetof(struct mib_mac_mgmt, station_id)
-#define POWER_MGMT_MODE_OFFSET offsetof(struct mib_mac_mgmt, power_mgmt_mode)
-#define LISTEN_INTERVAL_OFFSET offsetof(struct mib_mac, listen_interval)
-
-#define PRIVACY_OPT_IMPL offsetof(struct mib_mac_mgmt, privacy_option_implemented)
-
-#define BOARDTYPE_503_INTERSIL_3861 1
-#define BOARDTYPE_503_INTERSIL_3863 2
-#define BOARDTYPE_503_RFMD 3
-#define BOARDTYPE_503_RFMD_ACC 4
-#define BOARDTYPE_505_RFMD 5
-#define BOARDTYPE_505_RFMD_2958 6
-#define BOARDTYPE_505A_RFMD_2958 7
-#define BOARDTYPE_505AMX_RFMD 8
struct hwcfg_r505 {
u8 cr39_values[14];
@@ -170,15 +94,17 @@ struct hwcfg_rfmd {
u8 reserved1[3];
} __attribute__ ((packed));
-struct hwcfg_intersil {
+struct hwcfg_other {
u8 mac_addr[ETH_ALEN];
- u8 cr31_values[14];
- u8 cr58_values[14];
- u8 pidvid[4];
- u8 regulatory_domain;
+ u8 cr31[14];
+ u8 cr58[14];
+ u8 vidpid[4];
+ u8 reg_domain;
u8 reserved[1];
} __attribute__ ((packed));
+#define WEP_KEY_SIZE 13
+#define NR_WEP_KEYS 4
#define WEP_SMALL_KEY_LEN (40/8)
#define WEP_LARGE_KEY_LEN (104/8)
@@ -187,31 +113,30 @@ struct at76c503_card_config{
u8 promiscuous_mode;
u8 short_retry_limit;
u8 encryption_type;
- __le16 rts_threshold;
- __le16 fragmentation_threshold; // 256..2346
+ u16 rts_threshold;
+ u16 fragmentation_threshold; // 256..2346
u8 basic_rate_set[4];
u8 auto_rate_fallback; //0,1
u8 channel;
u8 privacy_invoked;
u8 wep_default_key_id; // 0..3
u8 current_ssid[32];
- u8 wep_default_key_value[4][WEP_KEY_LEN];
+ u8 wep_default_key_value[4][WEP_KEY_SIZE];
u8 ssid_len;
u8 short_preamble;
- __le16 beacon_period;
+ u16 beacon_period;
} __attribute__ ((packed));
struct at76c503_command{
u8 cmd;
u8 reserved;
- __le16 size;
+ u16 size;
} __attribute__ ((packed));
-/* the length of the Atmel firmware specific rx header before IEEE 802.11 starts */
-#define AT76C503_RX_HDRLEN offsetof(struct at76c503_rx_buffer, packet)
+#define MAX_PACKET 1536
struct at76c503_rx_buffer {
- __le16 wlength;
+ u16 wlength;
u8 rx_rate;
u8 newbss;
u8 fragmentation;
@@ -219,18 +144,15 @@ struct at76c503_rx_buffer {
u8 link_quality;
u8 noise_level;
u8 rx_time[4];
- u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
+ u8 packet[MAX_PACKET];
} __attribute__ ((packed));
-/* the length of the Atmel firmware specific tx header before IEEE 802.11 starts */
-#define AT76C503_TX_HDRLEN offsetof(struct at76c503_tx_buffer, packet)
-
struct at76c503_tx_buffer {
- __le16 wlength;
+ u16 wlength;
u8 tx_rate;
u8 padding;
u8 reserved[4];
- u8 packet[IEEE80211_FRAME_LEN + IEEE80211_FCS_LEN];
+ u8 packet[MAX_PACKET];
} __attribute__ ((packed));
/* defines for scan_type below */
@@ -242,9 +164,9 @@ struct at76c503_start_scan {
u8 essid[32];
u8 scan_type;
u8 channel;
- __le16 probe_delay;
- __le16 min_channel_time;
- __le16 max_channel_time;
+ u16 probe_delay;
+ u16 min_channel_time;
+ u16 max_channel_time;
u8 essid_size;
u8 international_scan;
} __attribute__ ((packed));
@@ -263,7 +185,7 @@ struct at76c503_join {
u8 essid[32];
u8 bss_type;
u8 channel;
- __le16 timeout;
+ u16 timeout;
u8 essid_size;
u8 reserved;
} __attribute__ ((packed));
@@ -296,20 +218,20 @@ struct mib_mac_addr {
} __attribute__ ((packed));
struct mib_mac {
- __le32 max_tx_msdu_lifetime;
- __le32 max_rx_lifetime;
- __le16 frag_threshold;
- __le16 rts_threshold;
- __le16 cwmin;
- __le16 cwmax;
+ u32 max_tx_msdu_lifetime;
+ u32 max_rx_lifetime;
+ u16 frag_threshold;
+ u16 rts_threshold;
+ u16 cwmin;
+ u16 cwmax;
u8 short_retry_time;
u8 long_retry_time;
u8 scan_type; /* active or passive */
u8 scan_channel;
- __le16 probe_delay; /* delay before sending a ProbeReq in active scan, RO */
- __le16 min_channel_time;
- __le16 max_channel_time;
- __le16 listen_interval;
+ u16 probe_delay; /* delay before sending a ProbeReq in active scan, RO */
+ u16 min_channel_time;
+ u16 max_channel_time;
+ u16 listen_interval;
u8 desired_ssid[32];
u8 desired_bssid[ETH_ALEN];
u8 desired_bsstype; /* ad-hoc or infrastructure */
@@ -317,11 +239,11 @@ struct mib_mac {
} __attribute__ ((packed));
struct mib_mac_mgmt {
- __le16 beacon_period;
- __le16 CFP_max_duration;
- __le16 medium_occupancy_limit;
- __le16 station_id; /* assoc id */
- __le16 ATIM_window;
+ u16 beacon_period;
+ u16 CFP_max_duration;
+ u16 medium_occupancy_limit;
+ u16 station_id;
+ u16 ATIM_window;
u8 CFP_mode;
u8 privacy_option_implemented;
u8 DTIM_period;
@@ -344,21 +266,21 @@ struct mib_mac_wep {
u8 wep_default_key_id;
u8 wep_key_mapping_len;
u8 exclude_unencrypted;
- __le32 wep_icv_error_count;
- __le32 wep_excluded_count;
- u8 wep_default_keyvalue[WEP_KEYS][WEP_KEY_LEN];
+ u32 wep_icv_error_count;
+ u32 wep_excluded_count;
+ u8 wep_default_keyvalue[NR_WEP_KEYS][WEP_KEY_SIZE];
u8 encryption_level; /* 1 for 40bit, 2 for 104bit encryption */
} __attribute__ ((packed));
struct mib_phy {
- __le32 ed_threshold;
+ u32 ed_threshold;
- __le16 slot_time;
- __le16 sifs_time;
- __le16 preamble_length;
- __le16 plcp_header_length;
- __le16 mpdu_max_length;
- __le16 cca_mode_supported;
+ u16 slot_time;
+ u16 sifs_time;
+ u16 preamble_length;
+ u16 plcp_header_length;
+ u16 mpdu_max_length;
+ u16 cca_mode_supported;
u8 operation_rate_set[4];
u8 channel_id;
@@ -379,347 +301,4 @@ struct mib_mdomain {
u8 channel_list[14]; /* 0 for invalid channels */
} __attribute__ ((packed));
-/* states in infrastructure mode */
-enum infra_state {
- INIT,
- SCANNING,
- AUTHENTICATING,
- ASSOCIATING,
- REASSOCIATING,
- DISASSOCIATING,
- JOINING,
- CONNECTED,
- STARTIBSS,
- INTFW_DOWNLOAD,
- EXTFW_DOWNLOAD,
- WAIT_FOR_DISCONNECT,
- MONITORING,
-};
-
-/* a description of a regulatory domain and the allowed channels */
-struct reg_domain {
- u16 code;
- char const *name;
- u32 channel_map; /* if bit N is set, channel (N+1) is allowed */
-};
-
-/* how long do we keep a (I)BSS in the bss_list in jiffies
- this should be long enough for the user to retrieve the table
- (by iwlist ?) after the device started, because all entries from
- other channels than the one the device locks on get removed, too */
-#define BSS_LIST_TIMEOUT (120*HZ)
-
-/* struct to store BSS info found during scan */
-#define BSS_LIST_MAX_RATE_LEN 32 /* 32 rates should be enough ... */
-
-struct bss_info{
- struct list_head list;
-
- u8 mac[ETH_ALEN]; /* real mac address, differs
- for ad-hoc from bssid */
- u8 bssid[ETH_ALEN]; /* bssid */
- u8 ssid[IW_ESSID_MAX_SIZE+1]; /* ssid, +1 for trailing \0
- to make it printable */
- u8 ssid_len; /* length of ssid above */
- u8 channel;
- u16 capa; /* the capabilities of the BSS (in original endianess -
- we only check IEEE802_11 bits in it) */
- u16 beacon_interval; /* the beacon interval in units of TU (1.024 ms)
- (in CPU endianess - we must calc. values from it) */
- u8 rates[BSS_LIST_MAX_RATE_LEN]; /* supported rates (list of bytes:
- (basic_rate ? 0x80 : 0) + rate/(500 Kbit/s); e.g.
- x82,x84,x8b,x96 for basic rates 1,2,5.5,11 MBit/s) */
- u8 rates_len;
-
- /* quality of received beacon */
- u8 rssi;
- u8 link_qual;
- u8 noise_level;
-
- unsigned long last_rx; /* time (jiffies) of last beacon received */
- u16 assoc_id; /* if this is dev->curr_bss this is the assoc id we got
- in a successful AssocResponse */
-};
-
-/* a rx data buffer to collect rx fragments */
-struct rx_data_buf {
- u8 sender[ETH_ALEN]; /* sender address */
- u16 seqnr; /* sequence number */
- u16 fragnr; /* last fragment received */
- unsigned long last_rx; /* jiffies of last rx */
- struct sk_buff *skb; /* == NULL if entry is free */
-};
-
-#define NR_RX_DATA_BUF 8
-
-/* how often do we try to submit a rx urb until giving up */
-#define NR_SUBMIT_RX_TRIES 8
-
-struct at76c503 {
- struct usb_device *udev; /* USB device pointer */
- struct net_device *netdev; /* net device pointer */
- struct net_device_stats stats;
- struct iw_statistics wstats;
- struct usb_interface *interface; /* the interface for this device */
-
-// unsigned char num_ports; /* the number of ports this device has */
-// char num_interrupt_in; /* number of interrupt in endpoints we have */
-// char num_bulk_in; /* number of bulk in endpoints we have */
-// char num_bulk_out; /* number of bulk out endpoints we have */
-
- struct sk_buff * rx_skb; /* skbuff for receiving packets */
- __u8 bulk_in_endpointAddr; /* the address of the bulk in endpoint */
-
- unsigned char * bulk_out_buffer; /* the buffer to send data */
- int bulk_out_size; /* the size of the send buffer */
- struct urb * write_urb; /* the urb used to send data */
- struct urb * read_urb;
- __u8 bulk_out_endpointAddr; /* the address of the bulk out endpoint */
-
-// struct work_struct tqueue; /* task queue for line discipline waking up */
- int open_count; /* number of times this port has been opened */
- struct semaphore sem; /* locks this structure */
-
-
- unsigned long kevent_flags;
- struct work_struct kevent;
- int nr_submit_rx_tries; /* number of tries to submit an rx urb left */
- struct tasklet_struct tasklet;
- struct urb *rx_urb; /* tmp urb pointer for rx_tasklet */
-
- unsigned char *ctrl_buffer;
- struct urb *ctrl_urb;
-
- u8 op_mode;
-
- /* the WEP stuff */
- int wep_enabled; /* 1 if WEP is enabled */
- int wep_key_id; /* key id to be used */
- u8 wep_keys[WEP_KEYS][WEP_KEY_LEN]; /* the four WEP keys,
- 5 or 13 bytes are used */
- u8 wep_keys_len[WEP_KEYS]; /* the length of the above keys */
-
- int channel;
- int iw_mode;
- int curr_ap;
- u8 bssid[ETH_ALEN];
- u8 essid[IW_ESSID_MAX_SIZE];
- char nickn[IW_ESSID_MAX_SIZE+1]; /* nickname, only used in the iwconfig i/f */
- int essid_size;
- int radio_on;
- int promisc;
-
- int preamble_type; /* 0 - long preamble, 1 - short preamble */
- int auth_mode; /* authentication type: 0 open, 1 shared key */
- int txrate; /* 0,1,2,3 = 1,2,5.5,11 MBit, 4 is auto-fallback */
- int frag_threshold; /* threshold for fragmentation of tx packets */
- int rts_threshold; /* threshold for RTS mechanism */
- int short_retry_limit;
- //int long_retry_limit;
-
- int scan_min_time; /* scan min channel time */
- int scan_max_time; /* scan max channel time */
- int scan_mode; /* SCAN_TYPE_ACTIVE, SCAN_TYPE_PASSIVE */
- int scan_runs; /* counts how many scans are started */
-
- /* the list we got from scanning */
- spinlock_t bss_list_spinlock; /* protects bss_list operations and setting
- curr_bss and new_bss */
- struct list_head bss_list; /* the list of bss we received beacons from */
- struct timer_list bss_list_timer; /* a timer removing old entries from
- the bss_list. It must acquire bss_list_spinlock
- before and must not remove curr_bss nor
- new_bss ! */
- struct bss_info *curr_bss; /* if istate == AUTH, ASSOC, REASSOC, JOIN or CONN
- dev->bss[curr_bss] is the currently selected BSS
- we operate on */
- struct bss_info *new_bss; /* if istate == REASSOC dev->new_bss
- is the new bss we want to reassoc to */
-
- u8 wanted_bssid[ETH_ALEN];
- int wanted_bssid_valid; /* != 0 if wanted_bssid is to be used */
-
- /* some data for infrastructure mode only */
- spinlock_t mgmt_spinlock; /* this spinlock protects access to
- next_mgmt_bulk */
- spinlock_t istate_spinlock; /* this spinlock protects access to
- istate */
-
-
- struct at76c503_tx_buffer *next_mgmt_bulk; /* pending management msg to
- send via bulk out */
- enum infra_state istate;
- enum {
- SITE_SURVEY_IDLE,
- SITE_SURVEY_IN_PROGRESS,
- SITE_SURVEY_COMPLETED
- } site_survey_state;
- time_t last_survey;
-
- struct timer_list restart_timer; /* the timer we use to delay the restart a bit */
-
- struct timer_list mgmt_timer; /* the timer we use to repeat auth_req etc. */
- int retries; /* counts backwards while re-trying to send auth/assoc_req's */
- u16 assoc_id; /* the assoc_id for states JOINING, REASSOCIATING, CONNECTED */
- u8 pm_mode ; /* power management mode: ACTIVE, SAVE, SMART_SAVE */
- u32 pm_period_us; /* power manag. period (in us ?) - set by iwconfig */
- u32 pm_period_beacon; /* power manag. period (in beacon intervals
- of the curr_bss) */
- u32 board_type; /* BOARDTYPE_* defined above*/
-
- struct reg_domain const *domain; /* the description of the regulatory domain */
-
- /* iwspy support */
- spinlock_t spy_spinlock;
- struct iw_spy_data spy_data;
-
-#if WIRELESS_EXT > 16
- struct iw_public_data wireless_data;
-#endif /* WIRELESS_EXT > 16 */
-
- /* These fields contain HW config provided by the device (not all of
- * these fields are used by all board types) */
- u8 mac_addr[ETH_ALEN];
- u8 bb_cr[14];
- u8 pidvid[4];
- u8 regulatory_domain;
- u8 cr15_values[14];
- u8 cr20_values[14];
- u8 cr21_values[14];
- u8 cr31_values[14];
- u8 cr39_values[14];
- u8 cr58_values[14];
- u8 low_power_values[14];
- u8 normal_power_values[14];
- struct at76c503_card_config card_config;
- struct mib_fw_version fw_version;
-
- int rx_data_fcs_len; /* length of the trailing FCS
- (0 for fw <= 0.84.x, 4 otherwise) */
-
- /* store rx fragments until complete */
- struct rx_data_buf rx_data[NR_RX_DATA_BUF];
-
- /* firmware downloading stuff */
- struct timer_list fw_dl_timer; /* timer used to wait after REMAP
- until device is reset */
- int extfw_size;
- int intfw_size;
- /* these point into a buffer managed by at76c503-xxx.o, no need to dealloc */
- u8 *extfw; /* points to external firmware part, extfw_size bytes long */
- u8 *intfw; /* points to internal firmware part, intfw_size bytes long */
- unsigned int device_unplugged:1;
- unsigned int netdev_registered:1;
- char obuf[2*256+1]; /* global debug output buffer to reduce stack usage */
- char obuf_s[3*32]; /* small global debug output buffer to reduce stack usage */
- struct set_mib_buffer mib_buf; /* global buffer for set_mib calls */
-
- /* new whiz-bang feature flags */
- int international_roaming;
- int monitor_prism_header; /* if iw_mode == IW_MODE_MONITOR,
- use Prism header */
- int monitor_scan_min_time;
- int monitor_scan_max_time;
-
- int beacon_period; /* period of mgmt beacons */
- int beacons_received;
- unsigned long beacons_last_qual; /* last time we reset beacons_received = 0 */
-};
-
-/* Quasi-monitor mode defs (copied from <kernel>/drivers/net/wireless/orinoco.h) */
-
-/* message data item for INT, BOUNDEDINT, ENUMINT */
-typedef struct p80211item_uint32
-{
- uint32_t did __attribute__ ((packed));
- uint16_t status __attribute__ ((packed));
- uint16_t len __attribute__ ((packed));
- uint32_t data __attribute__ ((packed));
-} __attribute__ ((packed)) p80211item_uint32_t;
-
-typedef struct p80211msg
-{
- uint32_t msgcode __attribute__ ((packed));
- uint32_t msglen __attribute__ ((packed));
- uint8_t devname[IFNAMSIZ];
-} __attribute__ ((packed)) p80211msg_t;
-
-#define P80211ENUM_msgitem_status_data_ok 0
-#define P80211ENUM_msgitem_status_no_value 1
-#define P80211ENUM_truth_false 0
-#define P80211ENUM_truth_true 1
-
-#define DIDmsg_lnxind_wlansniffrm 0x0041
-#define DIDmsg_lnxind_wlansniffrm_hosttime 0x1041
-#define DIDmsg_lnxind_wlansniffrm_mactime 0x2041
-#define DIDmsg_lnxind_wlansniffrm_channel 0x3041
-#define DIDmsg_lnxind_wlansniffrm_rssi 0x4041
-#define DIDmsg_lnxind_wlansniffrm_sq 0x5041
-#define DIDmsg_lnxind_wlansniffrm_signal 0x6041
-#define DIDmsg_lnxind_wlansniffrm_noise 0x7041
-#define DIDmsg_lnxind_wlansniffrm_rate 0x8041
-#define DIDmsg_lnxind_wlansniffrm_istx 0x9041
-#define DIDmsg_lnxind_wlansniffrm_frmlen 0xA041
-
-typedef struct p80211msg_lnxind_wlansniffrm
-{
- uint32_t msgcode;
- uint32_t msglen;
- uint8_t devname[IFNAMSIZ];
- p80211item_uint32_t hosttime;
- p80211item_uint32_t mactime;
- p80211item_uint32_t channel;
- p80211item_uint32_t rssi;
- p80211item_uint32_t sq;
- p80211item_uint32_t signal;
- p80211item_uint32_t noise;
- p80211item_uint32_t rate;
- p80211item_uint32_t istx;
- p80211item_uint32_t frmlen;
-} __attribute__ ((packed)) p80211msg_lnxind_wlansniffrm_t;
-
-/* at76_debug bits */
-#define DBG_PROGRESS 0x00000001 /* progress of scan-join-(auth-assoc)-connected */
-#define DBG_BSS_TABLE 0x00000002 /* show the bss table after scans */
-#define DBG_IOCTL 0x00000004 /* ioctl calls / settings */
-#define DBG_KEVENT 0x00000008 /* kevents */
-#define DBG_TX_DATA 0x00000010 /* tx header */
-#define DBG_TX_DATA_CONTENT 0x00000020 /* tx content */
-#define DBG_TX_MGMT 0x00000040
-#define DBG_RX_DATA 0x00000080 /* rx data header */
-#define DBG_RX_DATA_CONTENT 0x00000100 /* rx data content */
-#define DBG_RX_MGMT 0x00000200 /* rx mgmt header except beacon and probe responses */
-#define DBG_RX_BEACON 0x00000400 /* rx beacon */
-#define DBG_RX_CTRL 0x00000800 /* rx control */
-#define DBG_RX_MGMT_CONTENT 0x00001000 /* rx mgmt content */
-#define DBG_RX_FRAGS 0x00002000 /* rx data fragment handling */
-#define DBG_DEVSTART 0x00004000 /* fw download, device start */
-#define DBG_URB 0x00008000 /* rx urb status, ... */
-#define DBG_RX_ATMEL_HDR 0x00010000 /* the Atmel specific header of each rx packet */
-#define DBG_PROC_ENTRY 0x00020000 /* procedure entries and exits */
-#define DBG_PM 0x00040000 /* power management settings */
-#define DBG_BSS_MATCH 0x00080000 /* show why a certain bss did not match */
-#define DBG_PARAMS 0x00100000 /* show the configured parameters */
-#define DBG_WAIT_COMPLETE 0x00200000 /* show the wait_completion progress */
-#define DBG_RX_FRAGS_SKB 0x00400000 /* show skb header for incoming rx fragments */
-#define DBG_BSS_TABLE_RM 0x00800000 /* inform on removal of old bss table entries */
-#define DBG_MONITOR_MODE 0x01000000 /* debugs from monitor mode */
-#define DBG_MIB 0x02000000 /* dump all MIBs in startup_device */
-#define DBG_MGMT_TIMER 0x04000000 /* dump mgmt_timer ops */
-#define DBG_WE_EVENTS 0x08000000 /* dump wireless events */
-#define DBG_FW 0x10000000 /* firmware download */
-#define DBG_DFU 0x20000000 /* device firmware upgrade */
-
-#define DBG_DEFAULTS 0
-extern int at76_debug;
-
-/* Use our own dbg macro */
-#undef dbg
-#define dbg(bits, format, arg...) \
- do { \
- if (at76_debug & (bits)) \
- printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg);\
- } while (0)
-
-#endif /* _AT76C503_H */
diff --git a/at76c503fw.c b/at76c503fw.c
new file mode 100644
index 0000000..e784dff
--- /dev/null
+++ b/at76c503fw.c
@@ -0,0 +1,362 @@
+/*
+ * USB at76c503 firmware loader
+ *
+ * Copyright (c) 2002 - 2003 Oliver Kurth <oku@masqmail.cx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the 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 code is _very_ hackish, I know that. It was written with trial
+ and error, and will be made obsolete, when the download will be
+ done in the module (oku) */
+
+/*
+ * See here for the DFU specifications:
+ * http://www.usb.org/developers/devclass_docs/usbdfu10.pdf
+ */
+
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+
+#include <usb.h>
+
+typedef unsigned char UCHAR;
+#include "internalr.h"
+#include "externalr.h"
+
+#define DEVICE_VENDOR_REQUEST_OUT 0x40
+#define DEVICE_VENDOR_REQUEST_IN 0xc0
+#define INTERFACE_VENDOR_REQUEST_OUT 0x41
+#define INTERFACE_VENDOR_REQUEST_IN 0xc1
+#define CLASS_REQUEST_OUT 0x21
+#define CLASS_REQUEST_IN 0xa1
+
+/* Define these values to match your device */
+#define USB_BELKIN_VENDOR_ID 0x0d5c
+#define USB_BELKIN_PRODUCT_ID 0xa002
+
+#define TIMEOUT 1000 /* ms */
+
+struct hwcfg_rfmd {
+ unsigned char CR20Values[14];
+ unsigned char CR21Values[14];
+ unsigned char BB_CR[14];
+ unsigned char PIDVID[4];
+ unsigned char mac_addr[6];
+ unsigned char mRegulatoryDomain;
+ unsigned char LowPowerValues[14];
+ unsigned char NormalPowerVlues[14];
+ unsigned char Reserved1[3];
+};
+
+static inline
+int set_remap(struct usb_dev_handle *devh)
+{
+ return usb_control_msg(devh,
+ INTERFACE_VENDOR_REQUEST_OUT, 0x0a,
+ 0, 0,
+ NULL, 0, TIMEOUT);
+}
+
+static inline
+int get_op_mode(struct usb_dev_handle *devh, unsigned char *mode)
+{
+ return usb_control_msg(devh,
+ INTERFACE_VENDOR_REQUEST_IN, 0x33,
+ 0x01, 0,
+ mode, 1, TIMEOUT);
+}
+
+static inline
+int get_dfu_state(struct usb_dev_handle *devh, unsigned char *state)
+{
+ return usb_control_msg(devh,
+ CLASS_REQUEST_IN, 0x05,
+ 0, 0,
+ state, 1, TIMEOUT);
+}
+
+static inline
+int get_dfu_status(struct usb_dev_handle *devh, unsigned char *state)
+{
+ return usb_control_msg(devh,
+ CLASS_REQUEST_IN, 0x03,
+ 0, 0,
+ state, 6, TIMEOUT);
+}
+
+static inline
+int set_dfu_block_int(struct usb_dev_handle *devh,
+ int i, unsigned char *buf, int bsize)
+{
+ return usb_control_msg(devh,
+ CLASS_REQUEST_OUT, 0x01,
+ i, 0,
+ buf, bsize, TIMEOUT);
+}
+
+static inline
+int set_dfu_block_ext(struct usb_dev_handle *devh,
+ int i, unsigned char *buf, int bsize)
+{
+ return usb_control_msg(devh,
+ DEVICE_VENDOR_REQUEST_OUT, 0x0e,
+ 0x0802, i,
+ buf, bsize, TIMEOUT);
+}
+
+static inline
+int get_hw_cfg(struct usb_dev_handle *devh,
+ unsigned char *buf, int buf_size)
+{
+ return usb_control_msg(devh,
+ INTERFACE_VENDOR_REQUEST_IN, 0x33,
+ ((0x0a << 8) | 0x02), 0,
+ buf, buf_size, TIMEOUT);
+}
+
+
+static int fw_download_int(struct usb_dev_handle *devh,
+ unsigned char *realbuf, int size)
+{
+ int i = 0;
+ unsigned char *dfu_status = malloc (6);
+ unsigned char *dfu_state = malloc(1);
+ unsigned char *buf = malloc (size);
+
+ if(!buf)
+ return -ENOMEM;
+
+ memcpy(buf, realbuf, size);
+
+ // while(size > 0){
+ while(1){
+ int bsize = size > 1024 ? 1024 : size;
+ int ret;
+
+ do{
+ if((ret = get_dfu_state(devh, dfu_state)) < 0){
+ err("get_dfu 1 failed: %d", ret);
+ return ret;
+ }
+
+ if((*dfu_state != 5) && (*dfu_state != 6) && (*dfu_state != 3) && (*dfu_state != 2)){
+ /* TODO: fix this */
+ err("cannot handle dfu_state = %d", *dfu_state);
+ return -EIO;
+ }
+ printf("dfu_state 1 = %d", *dfu_state);
+
+ /*
+ if(*dfu_state == 6){
+ }
+ */
+
+ if((*dfu_state == 3 || *dfu_state == 6)){
+ if((ret = get_dfu_status(devh, dfu_status)) < 0){
+ err("get_dfu 2 failed: %d", ret);
+ return ret;
+ }
+ *dfu_state = dfu_status[4]; /* what an ugly hardware... */
+
+ if(*dfu_state == 7){
+ return 0;
+ }
+
+ if((*dfu_state != 5) && (*dfu_state != 6) && (*dfu_state != 3) &&
+ (*dfu_state != 2) && (*dfu_state != 7)){
+ /* TODO: fix this */
+ err("cannot handle dfu_state(2) = %d", *dfu_state);
+ return -EIO;
+ }
+ }
+ // }while((dfu_state != 2) && (dfu_state != 5) && (dfu_state != 6));
+ }while((*dfu_state != 2) && (*dfu_state != 5));
+
+ printf("fw_int, size = %d, bsize = %d, i = %d, buf = %p\n", size, bsize, i, buf);
+ if((ret = set_dfu_block_int(devh, i, buf, bsize)) < 0){
+ err("fw_int failed: %d, i = %d", ret, i);
+ return ret;
+ }
+ buf += bsize;
+ size -= bsize;
+ i++;
+ }
+ free(dfu_status);
+ free(dfu_state);
+ free(buf);
+ return 0;
+}
+
+static int fw_download_ext(struct usb_dev_handle *devh, unsigned char *buf, int size)
+{
+ int i = 0, ret;
+ unsigned char dev_mode;
+ unsigned char *tmpbuf = malloc(1024);
+
+ if((ret = get_op_mode(devh, &dev_mode)) < 0){
+ fprintf(stderr, "get_op_mode failed, ret = %d", ret);
+ }
+
+ if(dev_mode != 4){
+ err("dev_mode = %d != 4, that's bad", dev_mode);
+ }
+
+ while(size > 0){
+ int bsize = size > 1024 ? 1024 : size;
+ int ret;
+
+ memcpy(tmpbuf, buf, bsize);
+ printf("fw_ext, size = %d, bsize = %d, i = %d, buf = %p\n", size, bsize, i, buf);
+ if((ret = set_dfu_block_ext(devh, i, tmpbuf, bsize)) < 0){
+ err("fw_ext failed: %d, i = %d", ret, i);
+ return ret;
+ }
+ buf += bsize;
+ size -= bsize;
+ i++;
+ }
+ if((ret = set_dfu_block_ext(devh, i, tmpbuf, 0)) < 0){
+ err("fw_ext failed: %d, i = %d", ret, i);
+ return ret;
+ }
+ free(tmpbuf);
+ return 0;
+}
+
+int main(int argc, char *argv[])
+{
+ struct usb_bus *bus;
+ struct usb_device *dev;
+ int do_int = 0, do_ext = 0, c;
+
+ usb_init();
+ usb_set_debug(0);
+
+ while(1){
+ c = getopt(argc, argv, "ie");
+
+ if(c == -1)
+ break;
+
+ switch(c){
+ case 'i':
+ do_int = 1;
+ break;
+ case 'e':
+ do_ext = 1;
+ break;
+ case '?':
+ break;
+ }
+ }
+
+ usb_find_busses();
+ usb_find_devices();
+
+ printf("bus/device idVendor/idProduct\n");
+ for (bus = usb_busses; bus; bus = bus->next) {
+ for (dev = bus->devices; dev; dev = dev->next) {
+
+ if ((dev->descriptor.idVendor == USB_BELKIN_VENDOR_ID) &&
+ (dev->descriptor.idProduct == USB_BELKIN_PRODUCT_ID)) {
+ printf("Belkin USB Adapter found\n");
+ goto endloop;
+ }
+
+ printf("%s/%s %04X/%04X\n", bus->dirname, dev->filename,
+ dev->descriptor.idVendor, dev->descriptor.idProduct);
+
+ if (!dev->config) {
+ fprintf(stderr, "Couldn't retrieve descriptors\n");
+ continue;
+ }
+ }
+ }
+
+ endloop:
+ if(bus && dev){
+ struct usb_dev_handle *devh = usb_open(dev);
+ int ret;
+ unsigned char *dummy = malloc(1);
+
+ if(!devh){
+ fprintf(stderr, " could not open dev: %s\n", strerror(errno));
+ exit(1);
+ }
+
+ ret = usb_claim_interface(devh, 0);
+ if(ret < 0){
+ fprintf(stderr, "usb_claim_interface failed, ret = %d\n", ret);
+ }
+
+ if(do_int){
+ ret = get_op_mode(devh, dummy);
+ if(ret < 0){
+ fprintf(stderr, "get_op_mode failed, ret = %d (no problem)", ret);
+ }
+
+ printf("download int\n");
+ ret = fw_download_int(devh, InternalRFMD, sizeof(InternalRFMD));
+ if(ret < 0){
+ fprintf(stderr, "download int failed: %s\n", strerror(errno));
+ goto close;
+ }
+
+ sleep(1);
+
+ printf("remap\n");
+ ret = set_remap(devh);
+ if(ret < 0){
+ fprintf(stderr, "remap failed: %s\n", strerror(errno));
+ goto close;
+ }
+
+ sleep(2);
+
+ /*
+ usb_close(devh);
+ usb_init();
+ devh = usb_open(dev);
+ */
+
+ printf("reset\n");
+ ret = usb_reset(devh);
+ if(ret < 0){
+ fprintf(stderr, "reset failed: %s\n", strerror(errno));
+ goto close;
+ }
+
+ }
+
+ if(do_ext){
+ usb_set_configuration(devh, 1);
+ if(ret < 0){
+ fprintf(stderr, "usb_set_configuration failed: %s\n", strerror(errno));
+ // goto close;
+ }
+
+ printf("download ext\n");
+ ret = fw_download_ext(devh, ExternalRFMD, sizeof(ExternalRFMD));
+ if(ret < 0){
+ fprintf(stderr, "download ext failed: %s\n", strerror(errno));
+ goto close;
+ }
+ }
+close:
+ usb_release_interface(devh, 0);
+ usb_close(devh);
+
+ }else{
+ printf("Belkin USB Adapter NOT found\n");
+ exit(1);
+ }
+
+ return 0;
+}
diff --git a/externalr.h b/externalr.h
new file mode 100644
index 0000000..8aec953
--- /dev/null
+++ b/externalr.h
@@ -0,0 +1,1500 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 1999-2000 by Atmel Corporation */
+/* */
+/* This software is copyrighted by and is the sole property of Atmel */
+/* Corporation. All rights, title, ownership, or other interests */
+/* in the software remain the property of Atmel Corporation. This */
+/* software may only be used in accordance with the corresponding */
+/* license agreement. Any un-authorized use, duplication, transmission, */
+/* distribution, or disclosure of this software is expressly forbidden. */
+/* */
+/* This Copyright notice may not be removed or modified without prior */
+/* written consent of Atmel Corporation. */
+/* */
+/* Atmel Corporation, Inc. reserves the right to modify this software */
+/* without notice. */
+/* */
+/* Atmel Corporation. */
+/* 2325 Orchard Parkway literature@atmel.com */
+/* San Jose, CA 95131 http://www.atmel.com */
+/* */
+/**************************************************************************/
+/**************************************************************************/
+/* */
+/* Automatically generated FW file for AT76C502A */
+/* */
+/**************************************************************************/
+
+
+UCHAR ExternalRFMD[] = {0x80,0xB5,0x10,0x49,0x00,0x20,0x08,0x70,0x0F,0x48
+ ,0x81,0x79,0xC0,0x79,0x00,0x02,0x08,0x43,0x68,0x28
+ ,0x04,0xD0,0x03,0x21,0x0B,0x20,0x00,0xF0,0xEB,0xFC
+ ,0x80,0xBD,0x08,0x21,0x0B,0x20,0x00,0xF0,0xE6,0xFC
+ ,0xC0,0x20,0xFE,0xF7,0xFD,0xF8,0x07,0x1C,0x00,0xF0
+ ,0xA6,0xFA,0x38,0x1C,0xFE,0xF7,0xF7,0xF8,0x01,0x21
+ ,0x0B,0x20,0x00,0xF0,0xD9,0xFC,0x80,0xBD,0x94,0x01
+ ,0x00,0x02,0xC4,0x09,0x00,0x02,0xB0,0xB5,0x27,0x4C
+ ,0x20,0x78,0x0A,0x28,0x40,0xD2,0x02,0xA3,0x1B,0x5C
+ ,0x5B,0x00,0x9F,0x44,0x00,0x1C,0x3C,0x05,0x09,0x0D
+ ,0x3C,0x11,0x15,0x19,0x3C,0x1D,0xA0,0x78,0x20,0x49
+ ,0x45,0x18,0x16,0xE0,0xA0,0x78,0x1F,0x49,0x45,0x18
+ ,0x12,0xE0,0xA0,0x78,0x1E,0x49,0x45,0x18,0x0E,0xE0
+ ,0xA0,0x78,0x1D,0x49,0x45,0x18,0x0A,0xE0,0xA0,0x78
+ ,0x1C,0x49,0x45,0x18,0x06,0xE0,0xA0,0x78,0x1B,0x49
+ ,0x45,0x18,0x02,0xE0,0xA0,0x78,0x1A,0x49,0x45,0x18
+ ,0x00,0x2D,0x1E,0xD0,0xC0,0x20,0xFE,0xF7,0xBF,0xF8
+ ,0x61,0x78,0x07,0x1C,0x00,0x20,0x00,0x29,0x07,0xD9
+ ,0x21,0x18,0x09,0x79,0x01,0x30,0x29,0x70,0x61,0x78
+ ,0x01,0x35,0x81,0x42,0xF7,0xD8,0x02,0xF0,0x32,0xFE
+ ,0x38,0x1C,0xFE,0xF7,0xAD,0xF8,0x01,0x21,0x01,0x20
+ ,0x00,0xF0,0x8F,0xFC,0xB0,0xBD,0x04,0x21,0x01,0x20
+ ,0x00,0xF0,0x8A,0xFC,0xB0,0xBD,0x03,0x21,0x01,0x20
+ ,0x00,0xF0,0x85,0xFC,0xB0,0xBD,0xCC,0x09,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0x5C,0x00,0x00,0x02,0xC0,0x00
+ ,0x00,0x02,0x80,0x00,0x00,0x02,0x18,0x00,0x00,0x02
+ ,0x00,0x00,0x00,0x02,0x14,0x01,0x00,0x02,0xF0,0xB5
+ ,0x82,0xB0,0x5A,0x49,0x0E,0x20,0x08,0x83,0x5A,0x4A
+ ,0x60,0x39,0x57,0x4C,0x01,0x92,0x50,0x7A,0xCD,0x1D
+ ,0xCF,0x1D,0xE6,0x1D,0x19,0x36,0x69,0x37,0x49,0x35
+ ,0x00,0x28,0x2F,0xD0,0xF0,0x7B,0x54,0x49,0x00,0x28
+ ,0x18,0xD0,0xF0,0x79,0x01,0x28,0x01,0xDB,0x0E,0x28
+ ,0x05,0xDD,0x03,0x21,0x03,0x20,0x00,0xF0,0x55,0xFC
+ ,0x02,0xB0,0xF0,0xBD,0x00,0x20,0x00,0x22,0x0B,0x18
+ ,0x9A,0x73,0x0A,0x54,0x01,0x30,0x00,0x04,0x00,0x0C
+ ,0x0E,0x28,0xF7,0xDB,0xFA,0x71,0x01,0x21,0xE9,0x71
+ ,0x29,0xE0,0xF0,0x79,0x41,0x18,0x49,0x7B,0x00,0x29
+ ,0x0A,0xD1,0x02,0xF0,0x96,0xF9,0x00,0x06,0x00,0x0E
+ ,0xF0,0x71,0x04,0xD1,0x03,0x21,0x03,0x20,0x00,0xF0
+ ,0x36,0xFC,0xDF,0xE7,0x00,0x22,0xEA,0x71,0x16,0xE0
+ ,0xF8,0x7A,0x3D,0x49,0x40,0x00,0x08,0x5A,0xF1,0x79
+ ,0x00,0x91,0x4A,0x1E,0x01,0x21,0x91,0x40,0x08,0x40
+ ,0x0B,0xD1,0x00,0x98,0x02,0xF0,0x7C,0xF9,0xF0,0x71
+ ,0xF0,0x79,0x00,0x28,0x04,0xD1,0x03,0x21,0x03,0x20
+ ,0x00,0xF0,0x1C,0xFC,0xC5,0xE7,0xC0,0x20,0xFE,0xF7
+ ,0x32,0xF8,0x06,0x1C,0x04,0x20,0xFB,0xF7,0x40,0xFE
+ ,0x2F,0x49,0x00,0x20,0x2F,0x4A,0x0B,0x18,0x12,0x5C
+ ,0x01,0x30,0x00,0x04,0x00,0x0C,0x04,0x28,0x1A,0x74
+ ,0xF6,0xDB,0x2C,0x48,0x2C,0x4A,0x00,0x88,0x00,0x23
+ ,0x10,0x80,0xC8,0x1D,0x09,0x30,0x0E,0x22,0x04,0x21
+ ,0x01,0xF0,0x8C,0xFE,0x01,0x21,0xA9,0x71,0x27,0x48
+ ,0x04,0x21,0x01,0x75,0x00,0x21,0xB9,0x72,0x06,0x22
+ ,0x21,0x1C,0x25,0x48,0xFE,0xF7,0xF0,0xFB,0xA1,0x1D
+ ,0x20,0x22,0x23,0x48,0xFE,0xF7,0xEB,0xFB,0xE0,0x1D
+ ,0x19,0x30,0x81,0x7B,0x21,0x4A,0x51,0x71,0x00,0x21
+ ,0x69,0x70,0x01,0x9A,0x20,0x23,0x91,0x71,0x81,0x79
+ ,0x1E,0x4A,0x91,0x74,0xC0,0x79,0xD0,0x74,0x20,0x8D
+ ,0x90,0x82,0x60,0x8D,0xD0,0x82,0xA0,0x8D,0x10,0x83
+ ,0x1A,0x48,0x01,0x78,0x19,0x43,0x01,0x70,0x01,0x21
+ ,0xF9,0x70,0x01,0x9A,0x51,0x71,0xB8,0x78,0x01,0x28
+ ,0x02,0xD1,0x00,0x20,0x03,0xF0,0xC0,0xF9,0x00,0x20
+ ,0xB8,0x70,0x30,0x1C,0xFD,0xF7,0xDF,0xFF,0x01,0x20
+ ,0x28,0x70,0x08,0x21,0x03,0x20,0x00,0xF0,0xBF,0xFB
+ ,0x68,0xE7,0xCC,0x09,0x00,0x02,0xA4,0x09,0x00,0x02
+ ,0xB0,0x00,0x00,0x02,0x14,0x01,0x00,0x02,0x6C,0x02
+ ,0x00,0x02,0x00,0x00,0x00,0x02,0x84,0x02,0x00,0x02
+ ,0x38,0x01,0x00,0x02,0x80,0x00,0x00,0x02,0x44,0x09
+ ,0x00,0x02,0xFC,0x00,0x00,0x02,0xDC,0x00,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0xC0,0x00,0x00,0x02,0x94,0x01
+ ,0x00,0x02,0xF0,0xB5,0x82,0xB0,0x41,0x49,0x40,0x4E
+ ,0x01,0x91,0x48,0x7A,0xF4,0x1D,0x19,0x34,0x00,0x28
+ ,0x3F,0x4F,0x13,0xD0,0xF8,0x79,0x00,0x28,0x05,0xD1
+ ,0x03,0x21,0x04,0x20,0x00,0xF0,0x8E,0xFB,0x02,0xB0
+ ,0xF0,0xBD,0xE0,0x79,0x3A,0x49,0x40,0x18,0x40,0x7B
+ ,0x00,0x28,0x13,0xD1,0x03,0x21,0x04,0x20,0x00,0xF0
+ ,0x82,0xFB,0xF2,0xE7,0xF8,0x7A,0x35,0x49,0x40,0x00
+ ,0x08,0x5A,0xE1,0x79,0x01,0x22,0x01,0x39,0x8A,0x40
+ ,0x10,0x40,0x04,0xD1,0x03,0x21,0x04,0x20,0x00,0xF0
+ ,0x73,0xFB,0xE3,0xE7,0xC0,0x20,0xFD,0xF7,0x89,0xFF
+ ,0x00,0x90,0xA0,0x79,0x2D,0x4D,0x02,0x28,0x02,0xD1
+ ,0x03,0x20,0xA8,0x71,0x03,0xE0,0x01,0x28,0x40,0xD1
+ ,0x04,0x20,0xA8,0x71,0x04,0x20,0xFB,0xF7,0x8C,0xFD
+ ,0x27,0x49,0x00,0x20,0x88,0x70,0xA0,0x79,0x26,0x49
+ ,0x06,0x22,0x88,0x70,0x08,0x1F,0x31,0x1C,0xFE,0xF7
+ ,0x53,0xFB,0xB1,0x1D,0x20,0x22,0x23,0x48,0xFE,0xF7
+ ,0x4E,0xFB,0xA0,0x7A,0x1F,0x49,0x48,0x71,0x00,0x20
+ ,0x68,0x70,0x01,0x99,0x88,0x71,0x08,0x21,0x04,0x20
+ ,0x00,0xF0,0x45,0xFB,0x01,0x20,0xF8,0x70,0x01,0x99
+ ,0x48,0x71,0xB8,0x78,0x01,0x28,0x02,0xD1,0x00,0x20
+ ,0x03,0xF0,0x31,0xF9,0x00,0x20,0xB8,0x70,0x17,0x48
+ ,0x20,0x23,0x01,0x78,0x19,0x43,0x01,0x70,0x01,0x78
+ ,0x10,0x23,0x99,0x43,0x01,0x70,0x00,0x98,0xFD,0xF7
+ ,0x47,0xFF,0x30,0x8D,0x81,0x02,0x04,0x20,0xFB,0xF7
+ ,0x3A,0xFD,0xE0,0x79,0x03,0xF0,0x93,0xF8,0x95,0xE7
+ ,0x03,0x21,0x04,0x20,0x00,0xF0,0x20,0xFB,0x00,0x98
+ ,0xFD,0xF7,0x37,0xFF,0x8D,0xE7,0xCC,0x09,0x00,0x02
+ ,0xB0,0x00,0x00,0x02,0xB4,0x09,0x00,0x02,0x14,0x01
+ ,0x00,0x02,0x6C,0x02,0x00,0x02,0x94,0x09,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0x00,0x01,0x00,0x02,0xDC,0x00
+ ,0x00,0x02,0x94,0x01,0x00,0x02,0xF0,0xB5,0x25,0x48
+ ,0x10,0x23,0x01,0x78,0x22,0x4C,0x99,0x43,0x01,0x70
+ ,0x01,0x78,0x20,0x23,0x99,0x43,0x01,0x70,0x21,0x48
+ ,0x21,0x49,0xC0,0x7A,0x40,0x00,0x09,0x5A,0xE7,0x18
+ ,0xF8,0x79,0x01,0x25,0x42,0x1E,0x2B,0x1C,0x93,0x40
+ ,0x19,0x40,0x04,0xD1,0x03,0x21,0x05,0x20,0x00,0xF0
+ ,0xEC,0xFA,0xF0,0xBD,0xB9,0x79,0x01,0x29,0x04,0xD0
+ ,0x03,0x21,0x05,0x20,0x00,0xF0,0xE4,0xFA,0xF0,0xBD
+ ,0x03,0xF0,0x4F,0xF8,0xC0,0x20,0xFD,0xF7,0xF8,0xFE
+ ,0x06,0x1C,0x38,0x7A,0x12,0x4F,0x78,0x71,0x12,0x48
+ ,0xC1,0x1D,0x39,0x31,0x8D,0x70,0xA1,0x1D,0x1C,0x30
+ ,0x0C,0x1C,0x7A,0x79,0xFE,0xF7,0xCE,0xFA,0x7A,0x79
+ ,0x0E,0x4F,0x21,0x1C,0xF8,0x1D,0x0D,0x30,0xFE,0xF7
+ ,0xC7,0xFA,0x00,0x20,0xF9,0x1D,0x29,0x31,0x88,0x71
+ ,0x00,0xF0,0x13,0xF8,0x30,0x1C,0xFD,0xF7,0xDA,0xFE
+ ,0xF0,0xBD,0x00,0x00,0xCC,0x09,0x00,0x02,0x94,0x01
+ ,0x00,0x02,0xB4,0x09,0x00,0x02,0x6C,0x02,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0xC0,0x00,0x00,0x02,0x80,0x00
+ ,0x00,0x02,0xF0,0xB5,0xF9,0xF7,0x25,0xFF,0xFE,0xF7
+ ,0x47,0xFB,0xF9,0xF7,0x21,0xFF,0x2C,0x4F,0x02,0x21
+ ,0xB9,0x73,0x00,0x21,0xF9,0x73,0x38,0x74,0x01,0x0A
+ ,0x79,0x74,0x01,0x0C,0x00,0x0E,0xB9,0x74,0x27,0x4E
+ ,0xF8,0x74,0xF9,0x1D,0x07,0x31,0xF0,0x1D,0x06,0x22
+ ,0x35,0x30,0xFE,0xF7,0x93,0xFA,0x24,0x4C,0x01,0x25
+ ,0xF8,0x1D,0x29,0x30,0x25,0x75,0x05,0x71,0x22,0x48
+ ,0xF1,0x1D,0x42,0x79,0xF8,0x1D,0x0D,0x30,0x15,0x31
+ ,0xFE,0xF7,0x85,0xFA,0x1F,0x48,0x1F,0x4A,0x00,0x21
+ ,0x53,0x5C,0x46,0x18,0x01,0x31,0x04,0x29,0x33,0x74
+ ,0xF9,0xD3,0x1C,0x49,0x00,0x23,0x09,0x88,0x39,0x80
+ ,0x02,0x7D,0x04,0x21,0x10,0x30,0x01,0xF0,0x03,0xFD
+ ,0x19,0x48,0x20,0x23,0x01,0x78,0x19,0x43,0x01,0x70
+ ,0x01,0x78,0x10,0x23,0x19,0x43,0x01,0x70,0x10,0x48
+ ,0x85,0x70,0xFB,0xF7,0x56,0xFC,0x39,0x88,0x89,0x02
+ ,0x09,0x1A,0x06,0x20,0xFB,0xF7,0x74,0xFC,0xE0,0x1D
+ ,0x49,0x30,0x45,0x70,0x05,0x21,0x81,0x71,0x0E,0x48
+ ,0x01,0x68,0x0E,0x48,0xC2,0x69,0x11,0x43,0xC1,0x61
+ ,0x0D,0x48,0x01,0x21,0x05,0x70,0x05,0x20,0x00,0xF0
+ ,0x51,0xFA,0xF0,0xBD,0x80,0x00,0x00,0x02,0xC0,0x00
+ ,0x00,0x02,0x44,0x09,0x00,0x02,0x04,0x01,0x00,0x02
+ ,0x00,0x00,0x00,0x02,0x84,0x02,0x00,0x02,0x38,0x01
+ ,0x00,0x02,0x94,0x01,0x00,0x02,0xA4,0x02,0x00,0x02
+ ,0x40,0x00,0x00,0x04,0x3A,0x01,0x00,0x02,0xF0,0xB5
+ ,0x54,0x4F,0x54,0x4E,0xFC,0x1D,0xF9,0x1D,0x09,0x31
+ ,0x59,0x34,0x0D,0x1C,0xF0,0x1D,0x0D,0x30,0x22,0x79
+ ,0xFE,0xF7,0x2B,0xFA,0x22,0x79,0x29,0x1C,0x4F,0x48
+ ,0xFE,0xF7,0x26,0xFA,0x20,0x79,0x4E,0x49,0x4E,0x4A
+ ,0x48,0x71,0xB8,0x7B,0x00,0x28,0x03,0xD1,0x10,0x70
+ ,0xF0,0x72,0x50,0x70,0x08,0xE0,0x01,0x20,0x10,0x70
+ ,0xF0,0x72,0xF8,0x7B,0xD1,0x1D,0x39,0x31,0x50,0x70
+ ,0xF8,0x78,0x08,0x70,0x00,0x25,0x0D,0x20,0x68,0x43
+ ,0xC1,0x19,0x43,0x4A,0x30,0x31,0x80,0x18,0x0D,0x22
+ ,0x0C,0x30,0xFE,0xF7,0x07,0xFA,0x01,0x35,0x04,0x2D
+ ,0xF2,0xD3,0x60,0x79,0x00,0x28,0x03,0xD0,0x3C,0x49
+ ,0x01,0x20,0x48,0x72,0x02,0xE0,0x3A,0x49,0x00,0x20
+ ,0x48,0x72,0x78,0x7B,0x3A,0x49,0x0E,0x28,0x02,0xDC
+ ,0x01,0x28,0x00,0xDB,0x08,0x75,0xB8,0x78,0x37,0x4A
+ ,0x10,0x74,0x38,0x7B,0x01,0x28,0x02,0xD1,0x32,0x4B
+ ,0xD8,0x70,0x02,0xE0,0x30,0x4B,0x00,0x20,0xD8,0x70
+ ,0xF8,0x88,0x10,0x81,0xB8,0x88,0x50,0x81,0x38,0x78
+ ,0x2D,0x4A,0xD0,0x70,0xE0,0x88,0x2F,0x4A,0x30,0x80
+ ,0x00,0x20,0x3B,0x18,0x1C,0x7A,0x0D,0x18,0x2C,0x74
+ ,0x1B,0x7A,0x13,0x54,0x01,0x30,0x04,0x28,0xF6,0xD3
+ ,0x30,0x88,0x29,0x4A,0x00,0x23,0x10,0x80,0xC8,0x1D
+ ,0x09,0x30,0x0F,0x1C,0x0E,0x22,0x04,0x21,0x01,0xF0
+ ,0x58,0xFC,0x00,0xF0,0xFA,0xF8,0x24,0x4C,0x25,0x49
+ ,0xE0,0x1D,0x69,0x30,0xC0,0x7A,0x08,0x5C,0x38,0x75
+ ,0x23,0x4F,0x38,0x78,0x02,0x28,0x28,0xD1,0x02,0xF0
+ ,0xA5,0xFB,0x03,0xF0,0xC6,0xF8,0x17,0x49,0x88,0x78
+ ,0x00,0x28,0x07,0xD0,0xFB,0xF7,0xA1,0xFB,0x31,0x88
+ ,0x89,0x02,0x09,0x1A,0x06,0x20,0xFB,0xF7,0xBF,0xFB
+ ,0x01,0x20,0x00,0xF0,0xC6,0xF9,0x02,0xF0,0x44,0xFB
+ ,0x01,0x20,0xF9,0xF7,0x21,0xFE,0x01,0x20,0x80,0x06
+ ,0x80,0x69,0xFE,0xF7,0x3C,0xFA,0xFB,0xF7,0x82,0xFB
+ ,0xFB,0xF7,0x08,0xF8,0xFE,0xF7,0x18,0xFA,0x80,0x06
+ ,0x80,0x0E,0xA0,0x62,0x01,0x20,0x38,0x70,0xF0,0xBD
+ ,0x02,0xF0,0x2E,0xFB,0xF0,0xBD,0x00,0x00,0xCC,0x09
+ ,0x00,0x02,0x80,0x00,0x00,0x02,0xDC,0x00,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0x18,0x00,0x00,0x02,0x00,0x00
+ ,0x00,0x02,0xC0,0x00,0x00,0x02,0x84,0x02,0x00,0x02
+ ,0x38,0x01,0x00,0x02,0x44,0x09,0x00,0x02,0x7C,0x02
+ ,0x00,0x02,0x3B,0x01,0x00,0x02,0x80,0xB5,0x1D,0x49
+ ,0x1B,0x4A,0x0F,0x68,0x0B,0x2F,0x23,0xD2,0x01,0xA3
+ ,0xDB,0x5D,0x5B,0x00,0x9F,0x44,0x1F,0x05,0x0A,0x0D
+ ,0x10,0x12,0x15,0x18,0x1F,0x1B,0x1E,0x00,0x06,0x23
+ ,0xFF,0x20,0x01,0x30,0x8B,0x60,0x14,0xE0,0xFF,0x20
+ ,0x41,0x30,0x11,0xE0,0xFF,0x20,0x51,0x30,0x0E,0xE0
+ ,0x0B,0x20,0x0C,0xE0,0xFF,0x20,0x31,0x30,0x09,0xE0
+ ,0xFF,0x20,0x11,0x30,0x06,0xE0,0xFF,0x20,0x61,0x30
+ ,0x03,0xE0,0xFF,0x20,0x71,0x30,0x00,0xE0,0x00,0x20
+ ,0x01,0x23,0x4B,0x60,0x89,0x68,0x00,0xF0,0xD4,0xF9
+ ,0x04,0x21,0x0C,0x20,0x00,0xF0,0x45,0xF9,0x0F,0x20
+ ,0x00,0x06,0x81,0x88,0x03,0x4B,0x19,0x43,0x81,0x80
+ ,0x80,0xBD,0x58,0x0A,0x00,0x02,0x98,0x02,0x00,0x02
+ ,0x08,0x08,0x00,0x00,0xB0,0xB5,0x0D,0x4D,0x00,0x24
+ ,0xE8,0x1D,0x49,0x30,0x0C,0x4F,0x04,0x70,0xF8,0x7C
+ ,0x02,0xF0,0x9C,0xFE,0xE8,0x1D,0x69,0x30,0x84,0x72
+ ,0x38,0x8B,0x81,0x02,0x04,0x20,0xFB,0xF7,0x38,0xFB
+ ,0xB8,0x7C,0x00,0x28,0x03,0xD1,0x01,0x20,0xA8,0x77
+ ,0x00,0x05,0xB0,0xBD,0x20,0x1C,0xB0,0xBD,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0xC0,0x00,0x00,0x02,0x04,0x48
+ ,0x00,0x21,0xC2,0x1D,0x49,0x32,0x91,0x70,0x01,0x21
+ ,0x81,0x77,0x10,0x20,0xF7,0x46,0x00,0x00,0x44,0x09
+ ,0x00,0x02,0x03,0x48,0x00,0x21,0xC1,0x73,0x01,0x21
+ ,0x81,0x73,0x08,0x07,0xF7,0x46,0x00,0x00,0x54,0x09
+ ,0x00,0x02,0x04,0x48,0x00,0x21,0xC2,0x1D,0x49,0x32
+ ,0x51,0x71,0x01,0x21,0x81,0x77,0x08,0x05,0xF7,0x46
+ ,0x00,0x00,0x44,0x09,0x00,0x02,0xB0,0xB5,0x04,0x20
+ ,0xFB,0xF7,0x1E,0xFB,0x0F,0x48,0xC7,0x1D,0x49,0x37
+ ,0xB9,0x79,0x01,0x29,0x16,0xD1,0x03,0x21,0x70,0x30
+ ,0x81,0x72,0x00,0x25,0x0B,0x4C,0x7D,0x71,0xE0,0x7C
+ ,0x01,0xF0,0x3B,0xFE,0x00,0x28,0x07,0xD1,0x3D,0x70
+ ,0x02,0x20,0xB8,0x71,0x01,0x21,0x03,0x20,0x00,0xF0
+ ,0xDA,0xF8,0xB0,0xBD,0x01,0x21,0x39,0x70,0xE0,0x74
+ ,0xB0,0xBD,0x02,0xF0,0xFB,0xF9,0xB0,0xBD,0x44,0x09
+ ,0x00,0x02,0xC0,0x00,0x00,0x02,0x12,0x49,0xC9,0x7D
+ ,0x32,0x29,0x1A,0xD0,0x09,0xDC,0x10,0x29,0x11,0xD0
+ ,0x20,0x29,0x11,0xD0,0x30,0x29,0x11,0xD0,0x31,0x29
+ ,0x08,0xD1,0x03,0x20,0x06,0xE0,0x40,0x29,0x0F,0xD0
+ ,0x41,0x29,0x0F,0xD0,0x50,0x29,0x00,0xD1,0x07,0x20
+ ,0x08,0x49,0xC8,0x72,0xF7,0x46,0x00,0x20,0xFA,0xE7
+ ,0x01,0x20,0xF8,0xE7,0x02,0x20,0xF6,0xE7,0x04,0x20
+ ,0xF4,0xE7,0x05,0x20,0xF2,0xE7,0x06,0x20,0xF0,0xE7
+ ,0x00,0x00,0x00,0x00,0x00,0x02,0xB4,0x09,0x00,0x02
+ ,0xF0,0xB5,0x1E,0x4D,0x01,0x24,0x28,0x78,0x01,0x28
+ ,0x30,0xD1,0x1C,0x4C,0x1D,0x49,0xE0,0x7A,0x1D,0x4E
+ ,0x08,0x5C,0x30,0x75,0xC0,0x20,0xFD,0xF7,0xAF,0xFC
+ ,0x07,0x1C,0x1A,0x48,0x01,0x78,0x02,0x29,0x06,0xD1
+ ,0x01,0x21,0x01,0x70,0x30,0x7D,0x02,0xF0,0x03,0xFD
+ ,0x20,0x73,0x0D,0xE0,0x07,0x20,0x40,0x06,0xC1,0x69
+ ,0x10,0x23,0x99,0x43,0xC1,0x61,0x13,0x48,0x01,0x21
+ ,0x41,0x71,0x00,0x20,0x02,0xF0,0x73,0xFE,0x00,0x20
+ ,0xA0,0x70,0x20,0x7B,0x01,0x28,0x01,0xD1,0x00,0x20
+ ,0x28,0x70,0x20,0x7B,0x01,0x21,0x00,0x28,0x00,0xD1
+ ,0x05,0x21,0x38,0x1C,0x0C,0x1C,0xFD,0xF7,0x87,0xFC
+ ,0x21,0x06,0x09,0x0E,0x06,0x20,0x00,0xF0,0x68,0xF8
+ ,0xF0,0xBD,0x00,0x00,0xB3,0x02,0x00,0x02,0xB4,0x09
+ ,0x00,0x02,0x7C,0x02,0x00,0x02,0x00,0x00,0x00,0x02
+ ,0xB2,0x02,0x00,0x02,0xB0,0x00,0x00,0x02,0x00,0xB5
+ ,0x12,0x48,0x01,0x78,0x0D,0x29,0x1A,0xD2,0x02,0xA3
+ ,0x5B,0x5C,0x5B,0x00,0x9F,0x44,0x00,0x1C,0x16,0x07
+ ,0x16,0x07,0x07,0x07,0x0B,0x0E,0x16,0x16,0x07,0x07
+ ,0x07,0x00,0x0B,0x49,0x01,0x20,0x08,0x70,0x00,0xBD
+ ,0xFF,0xF7,0x9F,0xFF,0x00,0xBD,0x08,0x49,0x02,0x20
+ ,0x08,0x70,0x08,0x21,0x07,0x20,0x00,0xF0,0x3B,0xF8
+ ,0x00,0xBD,0x00,0x78,0x02,0x21,0x00,0xF0,0x36,0xF8
+ ,0x00,0xBD,0x00,0x00,0xC4,0x09,0x00,0x02,0xD5,0x01
+ ,0x00,0x02,0x3C,0x01,0x00,0x02,0x00,0xB5,0x15,0x48
+ ,0x01,0x78,0x0D,0x29,0x20,0xD2,0x02,0xA3,0x5B,0x5C
+ ,0x5B,0x00,0x9F,0x44,0x00,0x1C,0x1C,0x07,0x1C,0x0A
+ ,0x0D,0x13,0x1C,0x1C,0x1C,0x1C,0x10,0x16,0x19,0x00
+ ,0xFF,0xF7,0x47,0xFB,0x00,0xBD,0xFF,0xF7,0xA4,0xFB
+ ,0x00,0xBD,0xFF,0xF7,0x75,0xFC,0x00,0xBD,0x00,0xF0
+ ,0xA2,0xFD,0x00,0xBD,0xFF,0xF7,0x07,0xFD,0x00,0xBD
+ ,0xFF,0xF7,0x12,0xFB,0x00,0xBD,0xFF,0xF7,0x91,0xFE
+ ,0x00,0xBD,0x00,0x78,0x02,0x21,0x00,0xF0,0x04,0xF8
+ ,0x00,0xBD,0x00,0x00,0xC4,0x09,0x00,0x02,0x04,0x4A
+ ,0x10,0x70,0x04,0x48,0x01,0x70,0x04,0x48,0x00,0x21
+ ,0x01,0x70,0x41,0x70,0xF7,0x46,0x00,0x00,0x5C,0x02
+ ,0x00,0x02,0x5D,0x02,0x00,0x02,0xC4,0x09,0x00,0x02
+ ,0x04,0x48,0x00,0x21,0xC2,0x1D,0x69,0x32,0x51,0x70
+ ,0x01,0x21,0x81,0x77,0x08,0x02,0xF7,0x46,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0x80,0xB5,0x0F,0x4F,0x01,0x28
+ ,0x03,0xD1,0xF9,0xF7,0x56,0xFC,0xF8,0x62,0x38,0x63
+ ,0x0C,0x48,0x01,0x21,0x80,0x89,0x0C,0x4A,0xB8,0x87
+ ,0x39,0x72,0x79,0x72,0x39,0x73,0x00,0x20,0x38,0x74
+ ,0x38,0x60,0xB8,0x72,0xF8,0x72,0x10,0x70,0xB9,0x73
+ ,0x79,0x60,0x06,0x49,0xCA,0x7A,0x06,0x49,0xCA,0x70
+ ,0x88,0x70,0x08,0x70,0x80,0xBD,0x00,0x00,0x44,0x09
+ ,0x00,0x02,0xC0,0x00,0x00,0x02,0xE0,0x01,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0xC8,0x01,0x00,0x02,0xB0,0xB5
+ ,0xF3,0x25,0x2D,0x05,0x07,0x1C,0xA8,0x68,0x06,0x20
+ ,0xE8,0x60,0x0C,0x1C,0x28,0x69,0x80,0x08,0xFC,0xD3
+ ,0x0A,0x20,0xF9,0xF7,0x10,0xFC,0xA8,0x68,0x78,0x09
+ ,0x08,0x23,0x18,0x40,0x02,0x23,0x18,0x43,0xE8,0x60
+ ,0x28,0x69,0x80,0x08,0xFC,0xD3,0x38,0x06,0x00,0x0E
+ ,0xE8,0x60,0x28,0x69,0x80,0x08,0xFC,0xD3,0xA8,0x68
+ ,0x20,0x06,0x00,0x0E,0xE8,0x60,0x28,0x69,0x80,0x08
+ ,0xFC,0xD3,0xA8,0x68,0xB0,0xBD,0xF0,0xB5,0x14,0x1C
+ ,0x0D,0x1C,0x07,0x1C,0xFC,0xF7,0x69,0xFE,0x00,0x26
+ ,0x00,0x2F,0x10,0xD9,0xFC,0xF7,0xB6,0xFE,0x40,0x08
+ ,0xFB,0xD2,0x28,0x20,0xF9,0xF7,0xE7,0xFB,0xA9,0x5D
+ ,0xA0,0x19,0xFF,0xF7,0xC5,0xFF,0x28,0x20,0xF9,0xF7
+ ,0xE0,0xFB,0x01,0x36,0xBE,0x42,0xEE,0xD3,0xFC,0xF7
+ ,0x71,0xFE,0x00,0x20,0xF0,0xBD,0xF0,0xB5,0x84,0xB0
+ ,0x02,0x1C,0x48,0x4B,0x08,0x1C,0x19,0x68,0x46,0x4F
+ ,0x00,0x29,0x74,0xD0,0x59,0x68,0x01,0x29,0x72,0xD1
+ ,0x00,0x24,0x0F,0x21,0x09,0x06,0x8C,0x80,0x8C,0x81
+ ,0x0C,0x88,0xFE,0x1D,0x3C,0x36,0xF5,0x1F,0x09,0x89
+ ,0x07,0x3D,0xEC,0x1F,0x12,0x3C,0x19,0x68,0xE3,0x1F
+ ,0x07,0x3B,0x03,0x93,0x20,0x33,0x02,0x93,0x04,0x3B
+ ,0x01,0x93,0x0A,0x33,0x00,0x93,0x0A,0x29,0x2F,0xD1
+ ,0x0B,0x22,0x04,0x20,0x01,0x99,0xFF,0xF7,0xB8,0xFF
+ ,0xFF,0x22,0x06,0x20,0x01,0x32,0x02,0x99,0xFF,0xF7
+ ,0xB2,0xFF,0xFF,0x22,0x0E,0x20,0x39,0x1C,0x41,0x32
+ ,0xFF,0xF7,0xAC,0xFF,0xFF,0x22,0x0E,0x20,0x51,0x32
+ ,0x03,0x99,0xFF,0xF7,0xA6,0xFF,0xFF,0x22,0x0E,0x20
+ ,0x21,0x1C,0x11,0x32,0xFF,0xF7,0xA0,0xFF,0xFF,0x22
+ ,0x0E,0x20,0x29,0x1C,0x61,0x32,0xFF,0xF7,0x9A,0xFF
+ ,0xFF,0x22,0x0E,0x20,0x31,0x1C,0x71,0x32,0xFF,0xF7
+ ,0x94,0xFF,0xFF,0x22,0x01,0x20,0x31,0x32,0x00,0x99
+ ,0xFF,0xF7,0x8E,0xFF,0x02,0xE0,0x39,0x1C,0xFF,0xF7
+ ,0x8A,0xFF,0xFC,0xF7,0xF7,0xFD,0x06,0x22,0xFF,0x21
+ ,0x01,0x31,0x02,0x98,0xFC,0xF7,0x58,0xFE,0x04,0x22
+ ,0x0B,0x21,0x01,0x98,0xFC,0xF7,0x53,0xFE,0x0E,0x22
+ ,0xFF,0x21,0x38,0x1C,0x41,0x31,0xFC,0xF7,0x4D,0xFE
+ ,0x0E,0x22,0xFF,0x21,0x51,0x31,0x03,0x98,0xFC,0xF7
+ ,0x47,0xFE,0x0E,0x22,0xFF,0x21,0x28,0x1C,0x61,0x31
+ ,0xFC,0xF7,0x41,0xFE,0x0E,0x22,0xFF,0x21,0x30,0x1C
+ ,0x71,0x31,0xFC,0xF7,0x3B,0xFE,0x01,0xE0,0x11,0xE0
+ ,0x10,0xE0,0x0E,0x22,0xFF,0x21,0x20,0x1C,0x11,0x31
+ ,0xFC,0xF7,0x32,0xFE,0x01,0x22,0xFF,0x21,0x31,0x31
+ ,0x00,0x98,0xFC,0xF7,0x2C,0xFE,0xFC,0xF7,0xE1,0xFD
+ ,0x03,0x4B,0x00,0x24,0x1C,0x60,0x04,0xB0,0xF0,0xBD
+ ,0x58,0x0A,0x00,0x02,0x98,0x02,0x00,0x02,0x80,0xB4
+ ,0x0C,0x4F,0x00,0x28,0x05,0xD1,0x00,0x29,0x03,0xD1
+ ,0x01,0x2A,0x01,0xD1,0x01,0x2B,0x03,0xD1,0x20,0x20
+ ,0x38,0x73,0x80,0xBC,0xF7,0x46,0x80,0x20,0x38,0x73
+ ,0x05,0x48,0x06,0x49,0x00,0x68,0x10,0x23,0x08,0x73
+ ,0x38,0x7B,0x18,0x43,0x38,0x73,0xF2,0xE7,0x00,0x00
+ ,0x70,0x03,0x00,0x0D,0x2C,0x02,0x00,0x02,0x30,0x03
+ ,0x00,0x0D,0x80,0xB4,0x0B,0x4F,0x00,0x28,0x05,0xD1
+ ,0x00,0x29,0x03,0xD1,0x01,0x2A,0x01,0xD1,0x03,0x2B
+ ,0x03,0xD0,0x20,0x20,0x38,0x73,0x80,0xBC,0xF7,0x46
+ ,0x80,0x20,0x38,0x73,0x04,0x49,0x00,0x20,0x08,0x73
+ ,0x38,0x7B,0x10,0x23,0x18,0x43,0x38,0x73,0xF3,0xE7
+ ,0x70,0x03,0x00,0x0D,0x30,0x03,0x00,0x0D,0x80,0xB4
+ ,0x0C,0x4F,0x00,0x28,0x05,0xD1,0x00,0x29,0x03,0xD1
+ ,0x02,0x2A,0x01,0xD1,0x01,0x2B,0x03,0xD1,0x20,0x20
+ ,0x38,0x73,0x80,0xBC,0xF7,0x46,0x80,0x20,0x38,0x73
+ ,0x05,0x48,0x00,0x21,0x01,0x73,0x01,0x73,0x38,0x7B
+ ,0x10,0x23,0x18,0x43,0x38,0x73,0xF2,0xE7,0x00,0x00
+ ,0x70,0x03,0x00,0x0D,0x30,0x03,0x00,0x0D,0x00,0xB5
+ ,0x00,0x28,0x05,0xD1,0x00,0x29,0x03,0xD1,0x00,0x2A
+ ,0x01,0xD1,0x03,0x2B,0x03,0xD0,0x06,0x49,0x20,0x20
+ ,0x08,0x73,0x00,0xBD,0xFC,0xF7,0x4F,0xFB,0x04,0x49
+ ,0x00,0x20,0x08,0x80,0x03,0x49,0x08,0x80,0x00,0xBD
+ ,0x00,0x00,0x70,0x03,0x00,0x0D,0x40,0x02,0x00,0x02
+ ,0x42,0x02,0x00,0x02,0xB0,0xB4,0x20,0x25,0x00,0x28
+ ,0x18,0x4C,0x03,0xD1,0x02,0x2A,0x01,0xD1,0x01,0x2B
+ ,0x02,0xD1,0x25,0x73,0xB0,0xBC,0xF7,0x46,0x08,0x06
+ ,0x00,0x0E,0x02,0x2B,0x05,0xD1,0x00,0x28,0x01,0xD0
+ ,0x25,0x73,0xF5,0xE7,0x00,0x27,0x10,0xE0,0x03,0x2B
+ ,0x0E,0xD1,0x00,0x28,0x08,0xD0,0x02,0x28,0x08,0xD0
+ ,0x80,0x28,0x04,0xD0,0x85,0x28,0x11,0xD1,0x0A,0x48
+ ,0x07,0x88,0x03,0xE0,0x00,0x27,0x01,0xE0,0x09,0x48
+ ,0x07,0x88,0x80,0x20,0x20,0x73,0x08,0x48,0x00,0x21
+ ,0x07,0x73,0x01,0x73,0x20,0x7B,0x10,0x23,0x18,0x43
+ ,0x20,0x73,0xD7,0xE7,0x25,0x73,0xD5,0xE7,0x70,0x03
+ ,0x00,0x0D,0x42,0x02,0x00,0x02,0x40,0x02,0x00,0x02
+ ,0x30,0x03,0x00,0x0D,0x90,0xB5,0x20,0x27,0x00,0x28
+ ,0x0C,0x4C,0x03,0xD1,0x00,0x2A,0x01,0xD1,0x03,0x2B
+ ,0x01,0xD0,0x27,0x73,0x90,0xBD,0x09,0x06,0x09,0x0E
+ ,0x01,0x20,0x02,0x29,0x04,0xD0,0x85,0x29,0x07,0xD1
+ ,0x05,0x49,0x08,0x80,0x01,0xE0,0x05,0x49,0x08,0x80
+ ,0xFC,0xF7,0xED,0xFA,0x90,0xBD,0x27,0x73,0x90,0xBD
+ ,0x70,0x03,0x00,0x0D,0x42,0x02,0x00,0x02,0x40,0x02
+ ,0x00,0x02,0x80,0xB4,0x0C,0x4F,0x00,0x28,0x05,0xD1
+ ,0x00,0x29,0x03,0xD1,0x02,0x2A,0x01,0xD1,0x01,0x2B
+ ,0x03,0xD1,0x20,0x20,0x38,0x73,0x80,0xBC,0xF7,0x46
+ ,0x80,0x20,0x38,0x73,0x05,0x48,0x00,0x21,0x01,0x73
+ ,0x01,0x73,0x38,0x7B,0x10,0x23,0x18,0x43,0x38,0x73
+ ,0xF2,0xE7,0x00,0x00,0x70,0x03,0x00,0x0D,0x30,0x03
+ ,0x00,0x0D,0x00,0xB5,0x02,0x28,0x03,0xD1,0x0A,0x29
+ ,0x26,0xD1,0x16,0x4B,0x24,0xE0,0x04,0x28,0x01,0xD1
+ ,0x15,0x4B,0x20,0xE0,0x05,0x28,0x01,0xD1,0x14,0x4B
+ ,0x1C,0xE0,0x00,0x28,0x1A,0xD1,0x0A,0x29,0x17,0xD2
+ ,0x02,0xA3,0x5B,0x5C,0x5B,0x00,0x9F,0x44,0x00,0x1C
+ ,0x13,0x05,0x07,0x09,0x13,0x0B,0x0D,0x0F,0x13,0x11
+ ,0x0D,0x4B,0x0C,0xE0,0x0D,0x4B,0x0A,0xE0,0x0D,0x4B
+ ,0x08,0xE0,0x0D,0x4B,0x06,0xE0,0x0D,0x4B,0x04,0xE0
+ ,0x0D,0x4B,0x02,0xE0,0x0D,0x4B,0x00,0xE0,0x0D,0x4B
+ ,0x0D,0x49,0x98,0x18,0x08,0x60,0x00,0xF0,0x5B,0xF8
+ ,0x00,0xBD,0x58,0x0A,0x00,0x02,0xC4,0x02,0x00,0x02
+ ,0xC8,0x0A,0x00,0x02,0x04,0x01,0x00,0x02,0x5C,0x00
+ ,0x00,0x02,0xC0,0x00,0x00,0x02,0x80,0x00,0x00,0x02
+ ,0x18,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0x14,0x01
+ ,0x00,0x02,0x10,0x01,0x00,0x02,0x58,0x02,0x00,0x02
+ ,0x80,0xB4,0x17,0x1C,0x00,0x22,0x01,0x2F,0x17,0x4B
+ ,0x23,0xD1,0x02,0x28,0x10,0xD1,0x16,0x48,0x87,0x79
+ ,0xC0,0x79,0x00,0x02,0x07,0x43,0x08,0x29,0x07,0xD0
+ ,0x14,0x48,0x87,0x60,0x0C,0x27,0x1F,0x70,0x5A,0x70
+ ,0x9A,0x70,0x01,0x60,0x42,0x60,0x80,0xBC,0xF7,0x46
+ ,0x06,0x28,0xFB,0xD1,0x0F,0x48,0x00,0x78,0x01,0x28
+ ,0xF7,0xD1,0xFF,0x20,0x0D,0x21,0x09,0x06,0x43,0x30
+ ,0x88,0x80,0x0B,0x49,0x01,0x20,0x08,0x71,0x0B,0x49
+ ,0x08,0x70,0xEC,0xE7,0x18,0x79,0x18,0x70,0x5A,0x70
+ ,0x9A,0x70,0x18,0x78,0x0A,0x28,0xE5,0xD1,0x07,0x48
+ ,0x02,0x70,0xE2,0xE7,0xC4,0x09,0x00,0x02,0x30,0x02
+ ,0x00,0x02,0x98,0x02,0x00,0x02,0x36,0x01,0x00,0x02
+ ,0xE0,0x03,0x00,0x0D,0x37,0x01,0x00,0x02,0x94,0x01
+ ,0x00,0x02,0x90,0xB4,0x1A,0x4A,0x80,0x20,0x10,0x73
+ ,0x19,0x49,0x1A,0x48,0x0B,0x88,0x07,0x88,0xBB,0x42
+ ,0x11,0xD1,0x11,0x7B,0xC9,0x09,0x09,0xD2,0x00,0x88
+ ,0x40,0x07,0x03,0xD0,0xE0,0x20,0x10,0x73,0x90,0xBC
+ ,0xF7,0x46,0xD0,0x20,0x10,0x73,0xFA,0xE7,0x10,0x7B
+ ,0x20,0x23,0x18,0x43,0x10,0x73,0xF5,0xE7,0x00,0x88
+ ,0x0B,0x88,0xC0,0x1A,0x08,0x28,0x00,0xD9,0x08,0x20
+ ,0x0B,0x88,0x1B,0x18,0x0B,0x80,0x00,0x28,0x08,0xD0
+ ,0x0A,0x4B,0x0A,0x49,0x0F,0x68,0x3C,0x78,0x01,0x37
+ ,0x0F,0x60,0x1C,0x73,0x01,0x38,0xF8,0xD1,0x10,0x7B
+ ,0x10,0x23,0x18,0x43,0x10,0x73,0xDC,0xE7,0x00,0x00
+ ,0x70,0x03,0x00,0x0D,0x56,0x02,0x00,0x02,0x54,0x02
+ ,0x00,0x02,0x30,0x03,0x00,0x0D,0x58,0x02,0x00,0x02
+ ,0x90,0xB5,0x20,0x24,0x00,0x28,0x0B,0x4F,0x03,0xD1
+ ,0x00,0x2A,0x01,0xD1,0x03,0x2B,0x01,0xD0,0x3C,0x73
+ ,0x90,0xBD,0x08,0x06,0x00,0x0E,0x01,0xD0,0x80,0x28
+ ,0x01,0xD1,0x3C,0x73,0x90,0xBD,0x04,0x48,0x00,0x79
+ ,0x00,0xF0,0x3A,0xF8,0x60,0x20,0x38,0x73,0x90,0xBD
+ ,0x00,0x00,0x70,0x03,0x00,0x0D,0x30,0x02,0x00,0x02
+ ,0xB0,0xB4,0x13,0x48,0x01,0x2B,0x03,0xD1,0x20,0x21
+ ,0x01,0x73,0xB0,0xBC,0xF7,0x46,0x10,0x49,0x00,0x23
+ ,0x0D,0x78,0x02,0x22,0x0F,0x4C,0x10,0x4F,0x01,0x2D
+ ,0x02,0xD0,0x0D,0x78,0x02,0x2D,0x02,0xD1,0x0A,0x70
+ ,0x3B,0x70,0x23,0x70,0x80,0x21,0x01,0x73,0x0B,0x49
+ ,0x01,0x25,0x0D,0x73,0x0B,0x73,0x0A,0x73,0x0B,0x73
+ ,0x3A,0x78,0x10,0x23,0x0A,0x73,0x22,0x78,0x0A,0x73
+ ,0x01,0x7B,0x19,0x43,0x01,0x73,0xDE,0xE7,0x00,0x00
+ ,0x70,0x03,0x00,0x0D,0x60,0x02,0x00,0x02,0x5D,0x02
+ ,0x00,0x02,0x5C,0x02,0x00,0x02,0x30,0x03,0x00,0x0D
+ ,0x80,0xB4,0x01,0x22,0x00,0x23,0x02,0x28,0x10,0x49
+ ,0x12,0xD1,0x18,0x1C,0x10,0x4B,0x04,0x27,0x18,0x71
+ ,0x0F,0x4B,0x1F,0x70,0x18,0x70,0x0F,0x4F,0x82,0x23
+ ,0x3B,0x71,0x0E,0x4B,0x18,0x80,0x0E,0x4B,0x18,0x80
+ ,0x0E,0x4B,0x18,0x80,0x0A,0x70,0x80,0xBC,0xF7,0x46
+ ,0x85,0x28,0xFB,0xD1,0x0C,0x48,0x03,0x80,0x0C,0x48
+ ,0x02,0x70,0x08,0x78,0x01,0x28,0xF4,0xD1,0x02,0x20
+ ,0x08,0x70,0xF1,0xE7,0x00,0x00,0x61,0x02,0x00,0x02
+ ,0x70,0x03,0x00,0x0D,0xC0,0x03,0x00,0x0D,0xB0,0x03
+ ,0x00,0x0D,0x4E,0x02,0x00,0x02,0x4C,0x02,0x00,0x02
+ ,0x40,0x02,0x00,0x02,0x42,0x02,0x00,0x02,0x4B,0x02
+ ,0x00,0x02,0x90,0xB5,0x0F,0x1C,0x19,0x1C,0x29,0x4B
+ ,0x14,0x1C,0x27,0x4A,0x98,0x42,0x06,0xD1,0x13,0x68
+ ,0x0A,0x1C,0x38,0x1C,0x21,0x1C,0xFF,0xF7,0xAC,0xFD
+ ,0x90,0xBD,0x24,0x4B,0x98,0x42,0x06,0xD1,0x13,0x68
+ ,0x0A,0x1C,0x38,0x1C,0x21,0x1C,0xFF,0xF7,0xC2,0xFD
+ ,0x90,0xBD,0x81,0x23,0x1B,0x02,0x98,0x42,0x06,0xD1
+ ,0x13,0x68,0x0A,0x1C,0x38,0x1C,0x21,0x1C,0xFF,0xF7
+ ,0xD3,0xFD,0x90,0xBD,0xFF,0x23,0x0C,0x33,0x98,0x42
+ ,0x06,0xD1,0x13,0x68,0x0A,0x1C,0x38,0x1C,0x21,0x1C
+ ,0xFF,0xF7,0xE6,0xFD,0x90,0xBD,0x41,0x23,0x5B,0x02
+ ,0x98,0x42,0x06,0xD1,0x13,0x68,0x0A,0x1C,0x38,0x1C
+ ,0x21,0x1C,0xFF,0xF7,0xF7,0xFD,0x90,0xBD,0x0F,0x4B
+ ,0x98,0x42,0x06,0xD1,0x13,0x68,0x0A,0x1C,0x38,0x1C
+ ,0x21,0x1C,0xFF,0xF7,0x29,0xFE,0x90,0xBD,0x01,0x23
+ ,0xDB,0x03,0x98,0x42,0x06,0xD1,0x13,0x68,0x0A,0x1C
+ ,0x38,0x1C,0x21,0x1C,0xFF,0xF7,0x40,0xFE,0x90,0xBD
+ ,0x06,0x49,0x20,0x20,0x08,0x73,0x90,0xBD,0x00,0x00
+ ,0x28,0x02,0x00,0x02,0x08,0x80,0x00,0x00,0x0A,0x81
+ ,0x00,0x00,0x03,0x02,0x00,0x00,0x70,0x03,0x00,0x0D
+ ,0x10,0x49,0x09,0x78,0x01,0x29,0x1B,0xD1,0x40,0x08
+ ,0x19,0xD3,0x0D,0x20,0x00,0x06,0x01,0x78,0x20,0x23
+ ,0x19,0x43,0x01,0x70,0x0B,0x48,0x00,0x68,0xC1,0x43
+ ,0x0B,0x48,0xC2,0x69,0x11,0x40,0xC1,0x61,0x00,0x20
+ ,0x07,0x21,0x49,0x06,0x7D,0x22,0x12,0x01,0x88,0x61
+ ,0x01,0x30,0x90,0x42,0xFC,0xD3,0xFF,0x20,0x48,0x61
+ ,0xFF,0xE7,0xFE,0xE7,0xF7,0x46,0x00,0x00,0x36,0x01
+ ,0x00,0x02,0xA4,0x02,0x00,0x02,0x40,0x00,0x00,0x04
+ ,0xF0,0xB5,0xC0,0x20,0xFD,0xF7,0x28,0xF8,0x22,0x4C
+ ,0x23,0x4F,0x21,0x7A,0x23,0x4A,0x39,0x70,0x11,0x79
+ ,0x79,0x70,0x21,0x7B,0xF9,0x70,0x11,0x7B,0xB9,0x70
+ ,0x0D,0x21,0x09,0x06,0x8B,0x88,0x07,0x25,0x6D,0x06
+ ,0xBB,0x80,0xEE,0x69,0x01,0x23,0x5B,0x02,0x33,0x43
+ ,0xEB,0x61,0x00,0x23,0x01,0x33,0x32,0x2B,0xFC,0xD3
+ ,0xEE,0x69,0x18,0x4B,0x33,0x40,0xEB,0x61,0x00,0x23
+ ,0x01,0x33,0x64,0x2B,0xFC,0xD3,0x15,0x4D,0x00,0x23
+ ,0x2B,0x70,0x15,0x4B,0x80,0x25,0x1D,0x73,0x01,0x25
+ ,0x1D,0x72,0x82,0x25,0x1D,0x71,0x07,0x25,0x1D,0x70
+ ,0x11,0x4B,0x05,0x26,0x1E,0x73,0x86,0x26,0x1E,0x72
+ ,0x1D,0x71,0x24,0x23,0x23,0x71,0x3B,0x78,0x23,0x72
+ ,0xFB,0x78,0x23,0x73,0x7B,0x78,0x13,0x71,0xBB,0x78
+ ,0x13,0x73,0x0A,0x4A,0x0A,0x81,0xBA,0x88,0x8A,0x80
+ ,0xFC,0xF7,0xE4,0xFF,0xF0,0xBD,0x00,0x00,0xC0,0x03
+ ,0x00,0x0D,0xBC,0x02,0x00,0x02,0xE0,0x03,0x00,0x0D
+ ,0xFF,0xFD,0x00,0x00,0x10,0x00,0x00,0x0D,0xB0,0x03
+ ,0x00,0x0D,0xA0,0x03,0x00,0x0D,0xFF,0x0F,0x00,0x00
+ ,0x80,0xB5,0x0C,0x49,0x00,0x20,0x08,0x60,0x0B,0x49
+ ,0x0E,0x4F,0x08,0x80,0x0B,0x49,0x08,0x70,0x0B,0x49
+ ,0x08,0x70,0x38,0x68,0x01,0x7A,0x10,0x29,0x02,0xD1
+ ,0xFB,0xF7,0x4A,0xFB,0x38,0x60,0x38,0x68,0x01,0x7A
+ ,0x40,0x29,0x02,0xD1,0xFB,0xF7,0x43,0xFB,0x38,0x60
+ ,0x80,0xBD,0x44,0x02,0x00,0x02,0x48,0x02,0x00,0x02
+ ,0x50,0x02,0x00,0x02,0x4A,0x02,0x00,0x02,0x64,0x02
+ ,0x00,0x02,0xF0,0xB5,0x23,0x4E,0x04,0x1C,0x0F,0x1C
+ ,0x13,0x1C,0x20,0x22,0xB5,0x78,0xF1,0x78,0x03,0x2B
+ ,0x20,0x48,0x01,0xD0,0x02,0x73,0xF0,0xBD,0x02,0x2D
+ ,0x09,0xD1,0x01,0x29,0x01,0xD3,0x0A,0x29,0x01,0xD9
+ ,0x02,0x73,0xF0,0xBD,0x08,0x29,0x01,0xD1,0x02,0x73
+ ,0xF0,0xBD,0x00,0x2F,0x09,0xD1,0xFC,0xF7,0x51,0xF8
+ ,0x06,0x2D,0x07,0xD1,0xF9,0xF7,0xDC,0xF8,0x15,0x48
+ ,0x00,0x21,0x01,0x70,0x01,0xE0,0x00,0x21,0x01,0x73
+ ,0x13,0x48,0x02,0x2D,0x07,0xD1,0x00,0x2C,0x0E,0xD1
+ ,0x11,0x49,0x01,0x60,0x11,0x48,0x00,0x21,0x01,0x70
+ ,0x08,0xE0,0x01,0x2D,0xD7,0xD0,0x0F,0x49,0x01,0x60
+ ,0x0F,0x48,0x00,0x21,0x01,0x70,0x0F,0x48,0x01,0x70
+ ,0x0F,0x48,0x31,0x1C,0x07,0x80,0x0E,0x48,0x00,0x27
+ ,0x07,0x80,0x0E,0x48,0x08,0x22,0xFD,0xF7,0x4D,0xFB
+ ,0x03,0x48,0x07,0x70,0xF0,0xBD,0x30,0x02,0x00,0x02
+ ,0x70,0x03,0x00,0x0D,0x60,0x02,0x00,0x02,0x58,0x02
+ ,0x00,0x02,0x58,0x0A,0x00,0x02,0x94,0x01,0x00,0x02
+ ,0xC8,0x09,0x00,0x02,0x5D,0x02,0x00,0x02,0x5C,0x02
+ ,0x00,0x02,0x54,0x02,0x00,0x02,0x56,0x02,0x00,0x02
+ ,0x38,0x02,0x00,0x02,0xB0,0xB5,0x11,0x4F,0x14,0x1C
+ ,0xBB,0x78,0xFF,0x78,0x03,0x2C,0x0F,0x4A,0x02,0xD0
+ ,0x20,0x20,0x10,0x73,0xB0,0xBD,0x0E,0x4D,0x00,0x24
+ ,0x2C,0x80,0x0D,0x4C,0x01,0x2B,0x21,0x80,0x0A,0xD1
+ ,0x80,0x20,0x10,0x73,0x0B,0x48,0x0C,0x49,0x00,0x78
+ ,0x10,0x23,0x08,0x73,0x10,0x7B,0x18,0x43,0x10,0x73
+ ,0xB0,0xBD,0x02,0x1C,0x18,0x1C,0x39,0x1C,0xFF,0xF7
+ ,0x26,0xFD,0xB0,0xBD,0x00,0x00,0x30,0x02,0x00,0x02
+ ,0x70,0x03,0x00,0x0D,0x56,0x02,0x00,0x02,0x54,0x02
+ ,0x00,0x02,0x53,0x02,0x00,0x02,0x30,0x03,0x00,0x0D
+ ,0xB0,0xB5,0x0F,0x1C,0x18,0x4D,0x19,0x1C,0x14,0x1C
+ ,0xA8,0x42,0x02,0xD0,0x17,0x4B,0x00,0x22,0x1A,0x70
+ ,0x16,0x4A,0xA8,0x42,0x06,0xD1,0x13,0x68,0x0A,0x1C
+ ,0x38,0x1C,0x21,0x1C,0xFF,0xF7,0xD1,0xFD,0xB0,0xBD
+ ,0x12,0x4B,0x98,0x42,0x04,0xD1,0x12,0x68,0x20,0x1C
+ ,0xFF,0xF7,0x55,0xFF,0xB0,0xBD,0x0F,0x4B,0x98,0x42
+ ,0x06,0xD1,0x13,0x68,0x0A,0x1C,0x38,0x1C,0x21,0x1C
+ ,0xFF,0xF7,0xDD,0xFD,0xB0,0xBD,0x0B,0x4B,0x98,0x42
+ ,0x04,0xD1,0x12,0x68,0x20,0x1C,0xFF,0xF7,0xA3,0xFF
+ ,0xB0,0xBD,0x0B,0x1C,0x39,0x1C,0x22,0x1C,0xFF,0xF7
+ ,0x39,0xFE,0xB0,0xBD,0x01,0x02,0x00,0x00,0x61,0x02
+ ,0x00,0x02,0x28,0x02,0x00,0x02,0x0E,0x40,0x00,0x00
+ ,0x22,0xC1,0x00,0x00,0x33,0xC1,0x00,0x00,0xF0,0xB5
+ ,0x22,0x4B,0xE0,0x25,0x01,0x27,0x98,0x42,0x1D,0x49
+ ,0x1D,0x4C,0x1E,0x4A,0x08,0xD1,0x90,0x78,0x01,0x28
+ ,0x01,0xD1,0x0D,0x73,0x01,0xE0,0xFF,0xF7,0x54,0xFD
+ ,0x27,0x71,0xF0,0xBD,0x1A,0x4B,0x20,0x26,0x98,0x42
+ ,0x21,0xD1,0x0E,0x73,0x19,0x48,0x27,0x71,0x00,0x78
+ ,0x00,0x28,0xF4,0xD1,0x90,0x78,0x02,0x28,0x02,0xD1
+ ,0xD0,0x78,0x08,0x28,0xEE,0xD0,0x90,0x78,0x01,0x28
+ ,0x0C,0xD1,0x13,0x49,0x00,0x20,0x08,0x70,0x12,0x48
+ ,0x00,0x78,0x02,0x28,0x02,0xD1,0x11,0x48,0x07,0x70
+ ,0xF0,0xBD,0x11,0x48,0x07,0x70,0xF0,0xBD,0xD1,0x78
+ ,0x90,0x78,0x01,0x22,0xFF,0xF7,0xEB,0xFC,0xF0,0xBD
+ ,0x10,0x78,0x00,0x0A,0x01,0xD2,0x0E,0x73,0x00,0xE0
+ ,0x0D,0x73,0x27,0x71,0xF0,0xBD,0x70,0x03,0x00,0x0D
+ ,0xD0,0x03,0x00,0x0D,0x30,0x02,0x00,0x02,0x33,0xC1
+ ,0x00,0x00,0x0E,0x40,0x00,0x00,0x60,0x02,0x00,0x02
+ ,0x94,0x01,0x00,0x02,0x53,0x02,0x00,0x02,0x5F,0x02
+ ,0x00,0x02,0xDD,0x01,0x00,0x02,0x80,0xB5,0x00,0x20
+ ,0x1C,0x49,0x0F,0x27,0x3F,0x06,0x08,0x70,0xB8,0x80
+ ,0x39,0x88,0xB8,0x81,0x1A,0x4A,0x39,0x89,0xD1,0x69
+ ,0xD1,0x04,0xCB,0x68,0xC9,0x6B,0x18,0x49,0x09,0x68
+ ,0x90,0x61,0x17,0x49,0x02,0x20,0xC8,0x74,0x17,0x48
+ ,0x01,0x7A,0x0C,0x30,0x08,0x29,0x19,0xD2,0x01,0xA3
+ ,0x5B,0x5C,0x5B,0x00,0x9F,0x44,0x15,0x03,0x06,0x15
+ ,0x09,0x0C,0x0F,0x12,0x00,0xF0,0xFA,0xFB,0x80,0xBD
+ ,0x00,0xF0,0x7B,0xF9,0x80,0xBD,0x00,0xF0,0x10,0xFA
+ ,0x80,0xBD,0x00,0xF0,0x1B,0xF8,0x80,0xBD,0x00,0xF0
+ ,0xC4,0xF8,0x80,0xBD,0x00,0xF0,0x73,0xFA,0x80,0xBD
+ ,0x02,0x21,0x0A,0x20,0xFF,0xF7,0x38,0xFA,0x06,0x48
+ ,0xB8,0x80,0x80,0xBD,0x00,0x00,0x94,0x01,0x00,0x02
+ ,0x80,0x00,0x00,0x04,0x40,0x00,0x00,0x04,0x44,0x09
+ ,0x00,0x02,0xC4,0x09,0x00,0x02,0x08,0x08,0x00,0x00
+ ,0xF0,0xB5,0x4B,0x4F,0x60,0xC8,0x39,0x1C,0x60,0xC1
+ ,0x38,0x78,0x0F,0x25,0x2D,0x06,0x0E,0x28,0x48,0x4C
+ ,0x01,0xDC,0x00,0x28,0x05,0xD1,0x03,0x21,0x0A,0x20
+ ,0xFF,0xF7,0x17,0xFA,0xAC,0x80,0xF0,0xBD,0x44,0x48
+ ,0x90,0x21,0x41,0x70,0xB9,0x78,0x00,0x26,0x01,0x29
+ ,0x01,0xD1,0xC6,0x70,0x01,0xE0,0x40,0x21,0xC1,0x70
+ ,0x41,0x7C,0x89,0x07,0x89,0x0F,0x41,0x74,0xFA,0x78
+ ,0x41,0x7C,0x92,0x00,0x02,0x23,0x1A,0x43,0x11,0x43
+ ,0x41,0x74,0x39,0x79,0x01,0x75,0x79,0x79,0x41,0x75
+ ,0x38,0x49,0x09,0x78,0x01,0x29,0x01,0xD1,0xF9,0x79
+ ,0x41,0x77,0xFF,0x20,0xF5,0x30,0x35,0x49,0x49,0x68
+ ,0xC9,0x0B,0x03,0xD3,0x01,0x1C,0x01,0x38,0x00,0x29
+ ,0xF7,0xD1,0x07,0x21,0x49,0x06,0xC8,0x69,0x80,0x23
+ ,0x18,0x43,0xC8,0x61,0xFF,0x20,0x2D,0x30,0xF8,0xF7
+ ,0x45,0xFE,0x07,0x21,0x49,0x06,0xC8,0x69,0x80,0x23
+ ,0x98,0x43,0xC8,0x61,0x02,0xF0,0xE6,0xF8,0x38,0x78
+ ,0x00,0x21,0x01,0xF0,0x4D,0xFE,0x00,0x21,0x08,0x20
+ ,0xF8,0xF7,0xD7,0xFE,0x00,0x21,0x09,0x20,0xF8,0xF7
+ ,0xD3,0xFE,0x00,0x21,0x0A,0x20,0xF8,0xF7,0xCF,0xFE
+ ,0x20,0x4F,0xF8,0x69,0xBB,0x01,0x18,0x43,0xF8,0x61
+ ,0x00,0x20,0xF8,0xF7,0x3D,0xFE,0x0A,0x20,0xF8,0xF7
+ ,0x22,0xFE,0x01,0x20,0x80,0x06,0x46,0x61,0xC0,0x68
+ ,0x19,0x48,0x78,0x61,0x78,0x68,0xC0,0x0B,0x05,0xD3
+ ,0x06,0x21,0x0A,0x20,0xFF,0xF7,0xB1,0xF9,0xAC,0x80
+ ,0xF0,0xBD,0x00,0x22,0xFF,0x21,0x7D,0x20,0xC0,0x00
+ ,0xAC,0x80,0x00,0xF0,0xA6,0xFA,0x11,0x48,0x01,0x21
+ ,0x89,0x06,0x88,0x63,0x10,0x48,0x11,0x4A,0x48,0x63
+ ,0xAE,0x80,0x04,0x20,0xD0,0x74,0xB8,0x60,0x00,0x03
+ ,0x78,0x60,0x48,0x6A,0x0A,0x30,0x08,0x62,0x0C,0x48
+ ,0x01,0x21,0xA8,0x80,0x0A,0x20,0xFF,0xF7,0x92,0xF9
+ ,0xF0,0xBD,0x00,0x00,0xCC,0x02,0x00,0x02,0x08,0x08
+ ,0x00,0x00,0xCC,0x07,0x00,0x02,0xB0,0x02,0x00,0x02
+ ,0x40,0x00,0x00,0x04,0x04,0x24,0x00,0x00,0x00,0x72
+ ,0x01,0x02,0x64,0x10,0x00,0x00,0x44,0x09,0x00,0x02
+ ,0x88,0x88,0x00,0x00,0xF0,0xB5,0x4C,0x4F,0x60,0xC8
+ ,0x39,0x1C,0x60,0xC1,0x38,0x78,0x0F,0x25,0x2D,0x06
+ ,0x0E,0x28,0x49,0x4C,0x01,0xDC,0x00,0x28,0x05,0xD1
+ ,0x03,0x21,0x0A,0x20,0xFF,0xF7,0x6B,0xF9,0xAC,0x80
+ ,0xF0,0xBD,0x45,0x48,0x90,0x21,0x41,0x70,0xB9,0x78
+ ,0x00,0x26,0x01,0x29,0x01,0xD1,0xC6,0x70,0x01,0xE0
+ ,0x40,0x21,0xC1,0x70,0x41,0x7C,0x89,0x07,0x89,0x0F
+ ,0x41,0x74,0xFA,0x78,0x41,0x7C,0x92,0x00,0x02,0x23
+ ,0x1A,0x43,0x11,0x43,0x41,0x74,0x39,0x79,0x01,0x75
+ ,0x79,0x79,0x41,0x75,0x39,0x49,0x09,0x78,0x01,0x29
+ ,0x01,0xD1,0xF9,0x79,0x41,0x77,0xFF,0x20,0xF5,0x30
+ ,0x36,0x49,0x49,0x68,0xC9,0x0B,0x03,0xD3,0x01,0x1C
+ ,0x01,0x38,0x00,0x29,0xF7,0xD1,0x07,0x21,0x49,0x06
+ ,0xC8,0x69,0x80,0x23,0x18,0x43,0xC8,0x61,0xFF,0x20
+ ,0x2D,0x30,0xF8,0xF7,0x99,0xFD,0x07,0x21,0x49,0x06
+ ,0xC8,0x69,0x80,0x23,0x98,0x43,0xC8,0x61,0x02,0xF0
+ ,0x3A,0xF8,0x38,0x78,0x00,0x21,0x01,0xF0,0xA1,0xFD
+ ,0x0B,0x21,0x08,0x20,0xF8,0xF7,0x2B,0xFE,0xB7,0x21
+ ,0x09,0x20,0xF8,0xF7,0x27,0xFE,0x00,0x21,0x0A,0x20
+ ,0xF8,0xF7,0x23,0xFE,0x14,0x20,0xF8,0xF7,0x7E,0xFD
+ ,0x1F,0x4F,0xF8,0x69,0xBB,0x01,0x18,0x43,0xF8,0x61
+ ,0x00,0x20,0xF8,0xF7,0x8E,0xFD,0x0A,0x20,0xF8,0xF7
+ ,0x73,0xFD,0x01,0x20,0x80,0x06,0x46,0x61,0xC0,0x68
+ ,0x19,0x48,0x78,0x61,0x78,0x68,0xC0,0x0B,0x05,0xD3
+ ,0x06,0x21,0x0A,0x20,0xFF,0xF7,0x02,0xF9,0xAC,0x80
+ ,0xF0,0xBD,0x00,0x22,0x55,0x21,0x7D,0x20,0xC0,0x00
+ ,0xAC,0x80,0x00,0xF0,0xF7,0xF9,0x11,0x48,0x01,0x21
+ ,0x89,0x06,0x88,0x63,0x10,0x48,0x10,0x4A,0x48,0x63
+ ,0xAE,0x80,0x04,0x20,0xD0,0x74,0xB8,0x60,0x00,0x03
+ ,0x78,0x60,0x48,0x6A,0x0A,0x30,0x08,0x62,0x0C,0x48
+ ,0x01,0x21,0xA8,0x80,0x0A,0x20,0xFF,0xF7,0xE3,0xF8
+ ,0xF0,0xBD,0xCC,0x02,0x00,0x02,0x08,0x08,0x00,0x00
+ ,0xCC,0x07,0x00,0x02,0xB0,0x02,0x00,0x02,0x40,0x00
+ ,0x00,0x04,0x04,0x24,0x00,0x00,0x00,0x72,0x01,0x02
+ ,0x64,0x10,0x00,0x00,0x44,0x09,0x00,0x02,0x88,0x88
+ ,0x00,0x00,0xF0,0xB5,0x42,0x4C,0xC0,0xC8,0x21,0x1C
+ ,0xC0,0xC1,0xA0,0x78,0x40,0x4D,0x80,0x08,0x80,0x00
+ ,0x0F,0x27,0x3F,0x06,0x00,0x28,0x05,0xD0,0x03,0x21
+ ,0x0A,0x20,0xFF,0xF7,0xBD,0xF8,0xBD,0x80,0xF0,0xBD
+ ,0x20,0x78,0x0E,0x28,0x01,0xDC,0x00,0x28,0x05,0xD1
+ ,0x03,0x21,0x0A,0x20,0xFF,0xF7,0xB2,0xF8,0xBD,0x80
+ ,0xF0,0xBD,0x08,0x21,0x0A,0x20,0xFF,0xF7,0xAC,0xF8
+ ,0x33,0x48,0x00,0x26,0x06,0x70,0x33,0x48,0x06,0x60
+ ,0x46,0x60,0x00,0x20,0xF8,0xF7,0x1F,0xFD,0xA1,0x78
+ ,0x30,0x48,0x01,0x29,0x01,0xD1,0xC6,0x70,0x01,0xE0
+ ,0x40,0x21,0xC1,0x70,0x21,0x79,0x01,0x75,0x61,0x79
+ ,0x41,0x75,0x2C,0x49,0x09,0x78,0x01,0x29,0x01,0xD1
+ ,0xE1,0x79,0x41,0x77,0xFF,0x20,0xF5,0x30,0x29,0x49
+ ,0x49,0x68,0xC9,0x0B,0x03,0xD3,0x01,0x1C,0x01,0x38
+ ,0x00,0x29,0xF7,0xD1,0x07,0x21,0x49,0x06,0xC8,0x69
+ ,0x80,0x23,0x18,0x43,0xC8,0x61,0xFF,0x20,0x2D,0x30
+ ,0xF8,0xF7,0xE1,0xFC,0x07,0x21,0x49,0x06,0xC8,0x69
+ ,0x80,0x23,0x98,0x43,0xC8,0x61,0x01,0xF0,0x82,0xFF
+ ,0x20,0x78,0x00,0x21,0x01,0xF0,0xE9,0xFC,0x00,0x28
+ ,0x05,0xD1,0x05,0x21,0x0A,0x20,0xFF,0xF7,0x6B,0xF8
+ ,0xBD,0x80,0xF0,0xBD,0x14,0x20,0xF8,0xF7,0xCA,0xFC
+ ,0x00,0x20,0xF8,0xF7,0xDF,0xFC,0x13,0x48,0x41,0x68
+ ,0xC9,0x0B,0x05,0xD3,0x06,0x21,0x0A,0x20,0xFF,0xF7
+ ,0x5B,0xF8,0xBD,0x80,0xF0,0xBD,0x86,0x60,0x20,0x20
+ ,0x41,0x05,0x48,0x61,0x0D,0x48,0x01,0x21,0x01,0x73
+ ,0xC1,0x74,0xB8,0x88,0x0B,0x4B,0x18,0x43,0xB8,0x80
+ ,0x0A,0x20,0xFF,0xF7,0x4A,0xF8,0xF0,0xBD,0x00,0x00
+ ,0xCC,0x02,0x00,0x02,0x08,0x08,0x00,0x00,0x94,0x01
+ ,0x00,0x02,0xC4,0x02,0x00,0x02,0xCC,0x07,0x00,0x02
+ ,0xB0,0x02,0x00,0x02,0x40,0x00,0x00,0x04,0x44,0x09
+ ,0x00,0x02,0x48,0x48,0x00,0x00,0xF0,0xB5,0x2F,0x4F
+ ,0x60,0xC8,0x39,0x1C,0x60,0xC1,0x38,0x78,0x0F,0x25
+ ,0x2D,0x06,0x0E,0x28,0x2C,0x4C,0x01,0xDC,0x00,0x28
+ ,0x05,0xD1,0x03,0x21,0x0A,0x20,0xFF,0xF7,0x25,0xF8
+ ,0xAC,0x80,0xF0,0xBD,0x28,0x48,0x00,0x26,0x46,0x70
+ ,0x41,0x7C,0xFD,0x23,0x19,0x40,0x41,0x74,0x25,0x49
+ ,0x09,0x78,0x01,0x29,0x01,0xD1,0xF9,0x79,0x41,0x77
+ ,0xFF,0x20,0xF5,0x30,0x22,0x49,0x49,0x68,0xC9,0x0B
+ ,0x03,0xD3,0x01,0x1C,0x01,0x38,0x00,0x29,0xF7,0xD1
+ ,0x07,0x21,0x49,0x06,0xC8,0x69,0x80,0x23,0x18,0x43
+ ,0xC8,0x61,0xFF,0x20,0x2D,0x30,0xF8,0xF7,0x66,0xFC
+ ,0x07,0x21,0x49,0x06,0xC8,0x69,0x80,0x23,0x98,0x43
+ ,0xC8,0x61,0x01,0xF0,0x07,0xFF,0xAE,0x80,0x38,0x78
+ ,0x00,0x21,0x01,0xF0,0x6D,0xFC,0x00,0x28,0x02,0xD1
+ ,0x13,0x49,0x05,0x20,0x48,0x70,0x14,0x20,0xF8,0xF7
+ ,0x51,0xFC,0x00,0x20,0xF8,0xF7,0x66,0xFC,0x0D,0x48
+ ,0x41,0x68,0xC9,0x0B,0x05,0xD3,0x06,0x21,0x0A,0x20
+ ,0xFE,0xF7,0xE2,0xFF,0xAC,0x80,0xF0,0xBD,0x86,0x60
+ ,0x01,0x20,0x80,0x06,0x46,0x61,0x01,0x21,0x0A,0x20
+ ,0xAC,0x80,0xFE,0xF7,0xD7,0xFF,0xF0,0xBD,0xCC,0x02
+ ,0x00,0x02,0x08,0x08,0x00,0x00,0xCC,0x07,0x00,0x02
+ ,0xB0,0x02,0x00,0x02,0x40,0x00,0x00,0x04,0xC4,0x09
+ ,0x00,0x02,0xF0,0xB5,0x01,0x1C,0xB8,0xC9,0x58,0x4E
+ ,0x30,0x1C,0xB8,0xC0,0x30,0x7A,0x0F,0x24,0x24,0x06
+ ,0x0E,0x28,0x55,0x4F,0x01,0xDC,0x00,0x28,0x05,0xD1
+ ,0x03,0x21,0x0A,0x20,0xFE,0xF7,0xB8,0xFF,0xA7,0x80
+ ,0xF0,0xBD,0x51,0x4D,0xA8,0x70,0x70,0x78,0x68,0x70
+ ,0x30,0x78,0x28,0x70,0x70,0x88,0xA8,0x60,0x70,0x68
+ ,0xE8,0x60,0x00,0x20,0xE8,0x70,0x68,0x60,0x28,0x61
+ ,0xF0,0x68,0x68,0x61,0x00,0x20,0xF8,0xF7,0x1F,0xFC
+ ,0x6A,0x78,0x40,0x21,0x48,0x48,0x00,0x2A,0x16,0xD0
+ ,0x01,0x2A,0x17,0xD0,0x02,0x2A,0x18,0xD0,0x03,0x2A
+ ,0x01,0xD1,0x60,0x22,0x42,0x70,0x42,0x7C,0x92,0x07
+ ,0x92,0x0F,0x42,0x74,0xB3,0x7A,0x42,0x7C,0x9B,0x00
+ ,0x1A,0x43,0x42,0x74,0x72,0x7A,0x01,0x2A,0x0A,0xD1
+ ,0x00,0x22,0xC2,0x70,0x08,0xE0,0x00,0x22,0x42,0x70
+ ,0xED,0xE7,0x20,0x22,0x42,0x70,0xEA,0xE7,0x41,0x70
+ ,0xE8,0xE7,0xC1,0x70,0x37,0x49,0x09,0x78,0x01,0x29
+ ,0x01,0xD1,0xF1,0x7A,0x41,0x77,0xFF,0x20,0x35,0x4E
+ ,0xF5,0x30,0x71,0x68,0xC9,0x0B,0x03,0xD3,0x01,0x1C
+ ,0x01,0x38,0x00,0x29,0xF8,0xD1,0x07,0x21,0x49,0x06
+ ,0xC8,0x69,0x80,0x23,0x18,0x43,0xC8,0x61,0xFF,0x20
+ ,0x2D,0x30,0xF8,0xF7,0xC8,0xFB,0x07,0x21,0x49,0x06
+ ,0xC8,0x69,0x80,0x23,0x98,0x43,0xC8,0x61,0x01,0xF0
+ ,0x69,0xFE,0xA8,0x78,0x00,0x21,0x01,0xF0,0xD0,0xFB
+ ,0x25,0x49,0xC8,0x69,0x8B,0x01,0x18,0x43,0xC8,0x61
+ ,0x14,0x20,0xF8,0xF7,0xB4,0xFB,0x00,0x20,0xF8,0xF7
+ ,0xC9,0xFB,0x0A,0x20,0xF8,0xF7,0xAE,0xFB,0x00,0x26
+ ,0x01,0x20,0x80,0x06,0x46,0x61,0xC0,0x68,0x1C,0x49
+ ,0x1C,0x48,0x48,0x61,0x48,0x68,0xC0,0x0B,0x05,0xD3
+ ,0x06,0x21,0x0A,0x20,0xFE,0xF7,0x3B,0xFF,0xA7,0x80
+ ,0xF0,0xBD,0xE8,0x68,0x00,0xF0,0xAC,0xF8,0x68,0x60
+ ,0xE8,0x78,0xF8,0xF7,0xF0,0xFB,0x68,0x68,0xF9,0xF7
+ ,0xDF,0xFD,0xA7,0x80,0x29,0x78,0xE8,0x68,0x00,0x22
+ ,0x00,0xF0,0x27,0xF8,0x10,0x49,0xA6,0x80,0x03,0x20
+ ,0xC8,0x74,0x0C,0x49,0x22,0x20,0x88,0x60,0x08,0x05
+ ,0x41,0x6A,0x0C,0x4B,0xC9,0x18,0x01,0x62,0x0C,0x48
+ ,0x01,0x21,0xA0,0x80,0x0A,0x20,0xFE,0xF7,0x17,0xFF
+ ,0xF0,0xBD,0xD0,0x0A,0x00,0x02,0x08,0x08,0x00,0x00
+ ,0xB8,0x0A,0x00,0x02,0xCC,0x07,0x00,0x02,0xB0,0x02
+ ,0x00,0x02,0x40,0x00,0x00,0x04,0x04,0x24,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0x10,0x27,0x00,0x00,0x88,0x88
+ ,0x00,0x00,0xF0,0xB5,0x07,0x1C,0x00,0x2A,0x0B,0xD1
+ ,0x00,0x20,0x00,0x2F,0x14,0x4A,0x06,0xD9,0x09,0x06
+ ,0x09,0x0E,0x11,0x70,0x01,0x32,0x01,0x30,0xB8,0x42
+ ,0xFA,0xD3,0xF0,0xBD,0xF8,0xF7,0x68,0xFB,0xFC,0xF7
+ ,0x8A,0xFF,0xFC,0xF7,0x6A,0xFF,0xBC,0x08,0x26,0x1C
+ ,0x0B,0x4D,0x04,0xD0,0xFC,0xF7,0x64,0xFF,0x01,0xC5
+ ,0x01,0x3C,0xFA,0xD1,0xB0,0x00,0x3F,0x1A,0xFC,0xF7
+ ,0x5D,0xFF,0x69,0x1C,0x03,0x2F,0x28,0x70,0x02,0xD1
+ ,0x00,0x0C,0x08,0x70,0xF0,0xBD,0x02,0x2F,0xE2,0xD1
+ ,0x00,0x0A,0x08,0x70,0xF0,0xBD,0x00,0x00,0x00,0x72
+ ,0x01,0x02,0x88,0xB4,0x01,0x20,0x80,0x06,0xC1,0x6B
+ ,0x00,0xAB,0x19,0x80,0x1A,0x49,0x1B,0x4A,0xC9,0x7C
+ ,0x1B,0x4F,0x03,0x29,0x21,0xD1,0x00,0xA9,0x09,0x88
+ ,0x20,0x23,0x0B,0x40,0x18,0x49,0x0C,0xD0,0x87,0x63
+ ,0xCF,0x68,0x03,0x23,0x1B,0x03,0x3B,0x43,0x43,0x63
+ ,0x4B,0x78,0x15,0x4F,0xFF,0x5C,0x11,0x23,0x9B,0x02
+ ,0x3B,0x43,0x53,0x60,0x00,0xAA,0x12,0x88,0x92,0x08
+ ,0x16,0xD3,0x0A,0x69,0x01,0x32,0x0A,0x61,0x4B,0x69
+ ,0x9A,0x42,0x10,0xD2,0x89,0x68,0x42,0x6A,0x89,0x18
+ ,0x01,0x62,0x0B,0xE0,0x04,0x29,0x09,0xD1,0x00,0xA9
+ ,0x09,0x88,0xC9,0x08,0x05,0xD3,0x87,0x63,0x64,0x21
+ ,0x41,0x63,0x01,0x20,0x80,0x03,0x50,0x60,0x88,0xBC
+ ,0xF7,0x46,0x44,0x09,0x00,0x02,0x40,0x00,0x00,0x04
+ ,0x00,0x72,0x01,0x02,0xB8,0x0A,0x00,0x02,0xC0,0x01
+ ,0x00,0x02,0xF0,0xB5,0x04,0x30,0xC7,0x00,0x19,0x4C
+ ,0x00,0x26,0xE6,0x70,0x60,0x78,0x01,0x28,0x15,0xD0
+ ,0x02,0x28,0x15,0xD0,0x03,0x28,0x25,0xD1,0x0B,0x20
+ ,0x39,0x1C,0xFC,0xF7,0xBB,0xFE,0x0D,0x1C,0x79,0x1A
+ ,0x0B,0x20,0xFC,0xF7,0xB6,0xFE,0x07,0x1C,0x00,0x2D
+ ,0x18,0xD9,0x01,0x37,0x04,0x2D,0x13,0xD2,0x01,0x20
+ ,0xE0,0x70,0x13,0xE0,0x7F,0x08,0x11,0xE0,0x79,0x00
+ ,0x0B,0x20,0x0F,0x1C,0xFC,0xF7,0xA6,0xFE,0x0C,0x1C
+ ,0x79,0x1A,0x0B,0x20,0xFC,0xF7,0xA1,0xFE,0x07,0x1C
+ ,0x00,0x2C,0x04,0xD9,0x01,0x37,0x02,0xE0,0xE6,0x70
+ ,0x00,0xE0,0xE6,0x70,0x38,0x04,0x00,0x0C,0xF0,0xBD
+ ,0xB8,0x0A,0x00,0x02,0xF0,0xB5,0x4B,0x4F,0x60,0xC8
+ ,0x39,0x1C,0x60,0xC1,0x38,0x78,0x0F,0x26,0x36,0x06
+ ,0x0E,0x28,0x48,0x4D,0x01,0xDC,0x00,0x28,0x05,0xD1
+ ,0x03,0x21,0x0A,0x20,0xFE,0xF7,0x41,0xFE,0xB5,0x80
+ ,0xF0,0xBD,0x44,0x48,0x90,0x21,0x41,0x70,0xB9,0x78
+ ,0x00,0x24,0x01,0x29,0x01,0xD1,0xC4,0x70,0x01,0xE0
+ ,0x40,0x21,0xC1,0x70,0x41,0x7C,0x89,0x07,0x89,0x0F
+ ,0x41,0x74,0xFA,0x78,0x41,0x7C,0x92,0x00,0x11,0x43
+ ,0x41,0x74,0x39,0x79,0x01,0x75,0x79,0x79,0x41,0x75
+ ,0x39,0x49,0x09,0x78,0x01,0x29,0x01,0xD1,0xF9,0x79
+ ,0x41,0x77,0xFF,0x20,0xF5,0x30,0x36,0x49,0x49,0x68
+ ,0xC9,0x0B,0x03,0xD3,0x01,0x1C,0x01,0x38,0x00,0x29
+ ,0xF7,0xD1,0x07,0x21,0x49,0x06,0xC8,0x69,0x80,0x23
+ ,0x18,0x43,0xC8,0x61,0xFF,0x20,0x2D,0x30,0xF8,0xF7
+ ,0x71,0xFA,0x07,0x21,0x49,0x06,0xC8,0x69,0x80,0x23
+ ,0x98,0x43,0xC8,0x61,0x01,0xF0,0x12,0xFD,0x38,0x78
+ ,0x00,0x21,0x01,0xF0,0x79,0xFA,0x0B,0x21,0x08,0x20
+ ,0xF8,0xF7,0x03,0xFB,0xB7,0x21,0x09,0x20,0xF8,0xF7
+ ,0xFF,0xFA,0x00,0x21,0x0A,0x20,0xF8,0xF7,0xFB,0xFA
+ ,0x14,0x20,0xF8,0xF7,0x56,0xFA,0x1F,0x4F,0xF8,0x69
+ ,0xBB,0x01,0x18,0x43,0xF8,0x61,0x00,0x20,0xF8,0xF7
+ ,0x66,0xFA,0x0A,0x20,0xF8,0xF7,0x4B,0xFA,0x01,0x20
+ ,0x80,0x06,0x44,0x61,0xC0,0x68,0x19,0x48,0x78,0x61
+ ,0x78,0x68,0xC0,0x0B,0x05,0xD3,0x06,0x21,0x0A,0x20
+ ,0xFE,0xF7,0xDA,0xFD,0xB5,0x80,0xF0,0xBD,0x01,0x22
+ ,0x55,0x21,0x7D,0x20,0xC0,0x00,0xB5,0x80,0xFF,0xF7
+ ,0xCF,0xFE,0x11,0x48,0x01,0x21,0x89,0x06,0x88,0x63
+ ,0x10,0x48,0x10,0x4A,0x48,0x63,0xB4,0x80,0x04,0x20
+ ,0xB8,0x60,0xD0,0x74,0x00,0x03,0x78,0x60,0x48,0x6A
+ ,0x0A,0x30,0x08,0x62,0x0C,0x48,0x01,0x21,0xB0,0x80
+ ,0x0A,0x20,0xFE,0xF7,0xBB,0xFD,0xF0,0xBD,0xCC,0x02
+ ,0x00,0x02,0x08,0x08,0x00,0x00,0xCC,0x07,0x00,0x02
+ ,0xB0,0x02,0x00,0x02,0x40,0x00,0x00,0x04,0x04,0x24
+ ,0x00,0x00,0x00,0x72,0x01,0x02,0x64,0x10,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0x88,0x88,0x00,0x00,0x80,0xB5
+ ,0x15,0x49,0x01,0x27,0xC9,0x7C,0x01,0x29,0x13,0xD1
+ ,0x13,0x4B,0x18,0x40,0x0E,0xD0,0x88,0x06,0xC0,0x68
+ ,0x81,0x09,0x0A,0xD3,0x04,0x21,0x01,0x40,0x10,0x48
+ ,0x03,0xD0,0x41,0x68,0x01,0x31,0x41,0x60,0x02,0xE0
+ ,0x01,0x68,0x01,0x31,0x01,0x60,0x38,0x1C,0x80,0xBD
+ ,0x02,0x29,0x01,0xD1,0x38,0x1C,0x80,0xBD,0x03,0x29
+ ,0x01,0xD0,0x04,0x29,0x06,0xD1,0x07,0x4B,0x18,0x40
+ ,0x01,0xD0,0xFF,0xF7,0xAF,0xFE,0x38,0x1C,0x80,0xBD
+ ,0x00,0x20,0x80,0xBD,0x00,0x00,0x44,0x09,0x00,0x02
+ ,0x40,0x40,0x00,0x00,0xC4,0x02,0x00,0x02,0x80,0x80
+ ,0x00,0x00,0xFF,0xB5,0x84,0xB0,0x00,0x20,0x00,0x24
+ ,0x00,0x26,0x00,0x27,0x00,0x25,0x03,0x90,0x02,0x90
+ ,0x01,0x90,0x68,0x46,0x04,0x22,0x5A,0x49,0xFC,0xF7
+ ,0x61,0xFD,0x05,0x99,0x00,0x20,0x00,0x29,0x1B,0xDD
+ ,0x04,0x99,0x80,0x23,0x09,0x5C,0x0A,0x1C,0x9A,0x43
+ ,0x16,0x2A,0x02,0xD1,0x00,0xAB,0xD9,0x70,0x0D,0xE0
+ ,0x0B,0x2A,0x02,0xD1,0x00,0xAB,0x99,0x70,0x08,0xE0
+ ,0x04,0x2A,0x02,0xD1,0x00,0xAB,0x59,0x70,0x03,0xE0
+ ,0x02,0x2A,0x01,0xD1,0x00,0xAB,0x19,0x70,0x05,0x99
+ ,0x01,0x30,0x88,0x42,0xE3,0xDB,0x00,0x20,0x69,0x46
+ ,0x09,0x5C,0x00,0x29,0x0D,0xD0,0x09,0x0A,0x04,0xD3
+ ,0x00,0x2E,0x00,0xD1,0x07,0x1C,0x01,0x26,0x04,0x1C
+ ,0x01,0x99,0x02,0x90,0x00,0x29,0x02,0xD1,0x01,0x21
+ ,0x01,0x91,0x05,0x1C,0x01,0x30,0x04,0x28,0xEA,0xDB
+ ,0x01,0x99,0x00,0x20,0x00,0x29,0x01,0xD1,0x08,0xB0
+ ,0xF0,0xBD,0x00,0x2E,0x01,0xD1,0x2C,0x1C,0x2F,0x1C
+ ,0x3A,0x49,0x00,0x22,0x8B,0x18,0x1B,0x7C,0x00,0x2B
+ ,0x00,0xD0,0x03,0x92,0x01,0x32,0x04,0x2A,0xF7,0xDB
+ ,0x06,0x9B,0x01,0x26,0x0E,0x2B,0x34,0x4A,0x03,0xD1
+ ,0x34,0x4B,0x1B,0x78,0x01,0x2B,0x0A,0xD1,0x03,0x98
+ ,0x84,0x42,0x02,0xDD,0x03,0x98,0x90,0x72,0x00,0xE0
+ ,0x94,0x72,0x02,0x98,0xD0,0x72,0xD7,0x71,0x42,0xE0
+ ,0x2D,0x4B,0x1B,0x78,0x00,0x2B,0x3E,0xD1,0x01,0x2D
+ ,0x10,0xD9,0xD0,0x71,0x96,0x72,0xD6,0x72,0x07,0x9B
+ ,0x00,0x27,0x01,0x2B,0x35,0xD1,0x82,0x20,0x00,0xAB
+ ,0x18,0x70,0x84,0x20,0x58,0x70,0x0B,0x20,0x98,0x70
+ ,0x16,0x20,0xD8,0x70,0x2B,0xE0,0x01,0x2C,0x0D,0xDD
+ ,0x00,0xAC,0x64,0x78,0x23,0x0A,0x01,0xD3,0x96,0x72
+ ,0x08,0xE0,0x00,0xAC,0x24,0x78,0x23,0x0A,0x01,0xD3
+ ,0x90,0x72,0x02,0xE0,0x95,0x72,0x00,0xE0,0x94,0x72
+ ,0x01,0x2F,0x0D,0xD9,0x00,0xAC,0x24,0x78,0x23,0x0A
+ ,0x01,0xD3,0xD0,0x71,0x08,0xE0,0x00,0xAC,0x64,0x78
+ ,0x23,0x0A,0x01,0xD3,0xD6,0x71,0x02,0xE0,0xD5,0x71
+ ,0x00,0xE0,0xD7,0x71,0x02,0x9B,0x00,0x2B,0x05,0xDD
+ ,0x00,0xAB,0x5B,0x78,0x00,0x2B,0x01,0xD0,0xD6,0x72
+ ,0x00,0xE0,0xD0,0x72,0x00,0x20,0x6B,0x46,0x1B,0x5C
+ ,0x0C,0x18,0x01,0x30,0x04,0x28,0x23,0x74,0xF8,0xDB
+ ,0xC8,0x19,0x01,0x7C,0x80,0x23,0x19,0x43,0x01,0x74
+ ,0xD0,0x7A,0x05,0x49,0xC8,0x70,0x30,0x1C,0x86,0xE7
+ ,0x60,0x99,0x00,0x00,0x00,0x00,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0xB1,0x02,0x00,0x02,0xC8,0x01,0x00,0x02
+ ,0xF0,0xB4,0x44,0x78,0x00,0x26,0x05,0x2C,0x01,0xD8
+ ,0x00,0x2C,0x02,0xD1,0x30,0x1C,0xF0,0xBC,0xF7,0x46
+ ,0x00,0x22,0x00,0x27,0x00,0x2C,0x17,0xD9,0xC3,0x19
+ ,0x9D,0x78,0x6B,0x06,0x5B,0x0E,0x02,0x2B,0x08,0xD0
+ ,0x04,0x2B,0x06,0xD0,0x0B,0x2B,0x04,0xD0,0x16,0x2B
+ ,0x02,0xD0,0x2C,0x2B,0x0B,0xD1,0x04,0xE0,0x2C,0x2B
+ ,0x02,0xD0,0x13,0x1C,0xCD,0x54,0x01,0x32,0x01,0x37
+ ,0xA7,0x42,0xE8,0xD3,0x03,0xE0,0x00,0x2B,0x01,0xD1
+ ,0x30,0x1C,0xDD,0xE7,0x10,0x1C,0xDB,0xE7,0xF1,0xB5
+ ,0x85,0xB0,0x00,0x20,0x01,0x90,0x68,0x46,0x04,0x22
+ ,0x70,0x49,0xFC,0xF7,0x6F,0xFC,0x70,0x4E,0x04,0x24
+ ,0x30,0x68,0x45,0x68,0x80,0x89,0x2F,0x28,0x02,0xDA
+ ,0x00,0x20,0x06,0xB0,0xF0,0xBD,0x05,0x98,0x6B,0x49
+ ,0x01,0x28,0x04,0x91,0x09,0xD1,0x06,0x22,0xE8,0x1D
+ ,0x09,0x30,0x04,0x99,0xFC,0xF7,0x3C,0xFC,0x00,0x28
+ ,0x01,0xD0,0x00,0x20,0xEE,0xE7,0x20,0x20,0xE9,0x1D
+ ,0x19,0x31,0x28,0x5C,0x49,0x78,0x09,0x02,0x08,0x43
+ ,0x00,0x04,0x00,0x0C,0x02,0x90,0x14,0x28,0x04,0xDB
+ ,0x7D,0x23,0x02,0x98,0xDB,0x00,0x98,0x42,0x01,0xDD
+ ,0x00,0x20,0xDB,0xE7,0x22,0x20,0x28,0x5C,0x80,0x08
+ ,0x01,0xD2,0x00,0x20,0xD5,0xE7,0x30,0x68,0x24,0x27
+ ,0x80,0x89,0x04,0x38,0x24,0x28,0x45,0xDD,0x56,0x49
+ ,0x03,0x91,0xE8,0x5D,0x00,0x28,0x09,0xD0,0x01,0x28
+ ,0x20,0xD0,0x03,0x28,0x39,0xD1,0xE8,0x19,0x41,0x78
+ ,0x01,0x29,0x27,0xD0,0x00,0x20,0xC0,0xE7,0xEE,0x19
+ ,0x70,0x78,0x00,0x28,0x00,0xD1,0xBB,0xE7,0x4D,0x49
+ ,0x4A,0x79,0x82,0x42,0x01,0xD0,0x00,0x20,0xB5,0xE7
+ ,0x03,0x99,0xB0,0x1C,0xFC,0xF7,0xFB,0xFB,0x00,0x28
+ ,0x01,0xD0,0x00,0x20,0xAD,0xE7,0x70,0x78,0xC0,0x19
+ ,0x87,0x1C,0x01,0x20,0x01,0x90,0x14,0xE0,0xE8,0x19
+ ,0x69,0x46,0x06,0x1C,0xFF,0xF7,0x66,0xFF,0x04,0x1C
+ ,0x01,0xD1,0x00,0x20,0x9E,0xE7,0x70,0x78,0xC0,0x19
+ ,0x87,0x1C,0x07,0xE0,0x3D,0x49,0x80,0x78,0x09,0x7D
+ ,0x88,0x42,0x01,0xD0,0x00,0x20,0x93,0xE7,0x03,0x37
+ ,0x35,0x4E,0x30,0x68,0x80,0x89,0x04,0x38,0xB8,0x42
+ ,0xBE,0xDC,0x01,0x98,0x00,0x28,0x01,0xD1,0x00,0x20
+ ,0x87,0xE7,0x34,0x49,0x68,0x46,0x01,0x23,0x0A,0x7D
+ ,0x21,0x1C,0xFF,0xF7,0x78,0xFE,0x00,0x28,0x00,0xD1
+ ,0x7D,0xE7,0x04,0x20,0xF9,0xF7,0x10,0xFE,0x2E,0x48
+ ,0x20,0x23,0x01,0x78,0x2E,0x4F,0x19,0x43,0x01,0x70
+ ,0x01,0x78,0x10,0x23,0x19,0x43,0x01,0x70,0xE9,0x18
+ ,0x0C,0x1C,0xF8,0x1D,0x06,0x22,0x07,0x30,0xFC,0xF7
+ ,0xD1,0xFB,0x06,0x22,0x21,0x1C,0x04,0x98,0xFC,0xF7
+ ,0xCC,0xFB,0x21,0x4C,0xF8,0x1D,0x62,0x79,0x03,0x99
+ ,0x0D,0x30,0xFC,0xF7,0xC5,0xFB,0x22,0x48,0x01,0x25
+ ,0xFE,0x1D,0x29,0x36,0x05,0x75,0x35,0x71,0x02,0x98
+ ,0x38,0x80,0xA5,0x70,0x05,0x98,0x01,0x28,0x08,0xD1
+ ,0x00,0x21,0x00,0x20,0x01,0xF0,0xE5,0xFA,0x13,0x49
+ ,0x00,0x20,0x09,0x68,0x48,0x61,0x07,0xE0,0xF9,0xF7
+ ,0x9E,0xFD,0x39,0x88,0x89,0x02,0x09,0x1A,0x06,0x20
+ ,0xF9,0xF7,0xBC,0xFD,0x14,0x49,0x00,0x20,0x48,0x70
+ ,0x05,0x20,0x88,0x71,0x05,0x98,0x01,0x28,0x04,0xD1
+ ,0x01,0x21,0x04,0x20,0xFE,0xF7,0x9E,0xFB,0x00,0xE0
+ ,0xB5,0x71,0x0E,0x48,0x01,0x68,0x0E,0x48,0xC2,0x69
+ ,0x11,0x43,0xC1,0x61,0x0D,0x48,0x05,0x70,0x28,0x1C
+ ,0x28,0xE7,0x64,0x99,0x00,0x00,0x48,0x01,0x00,0x02
+ ,0xFC,0x00,0x00,0x02,0xDC,0x00,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0x00,0x00,0x00,0x02,0x94,0x01,0x00,0x02
+ ,0x80,0x00,0x00,0x02,0x44,0x09,0x00,0x02,0x94,0x09
+ ,0x00,0x02,0xA4,0x02,0x00,0x02,0x40,0x00,0x00,0x04
+ ,0x3A,0x01,0x00,0x02,0xF0,0xB5,0x84,0xB0,0x5A,0x49
+ ,0x04,0x22,0x01,0xA8,0xFC,0xF7,0x6F,0xFB,0x59,0x4F
+ ,0x59,0x49,0x38,0x68,0x00,0x25,0x46,0x68,0x06,0x22
+ ,0xF0,0x1D,0x09,0x30,0x03,0x91,0xFC,0xF7,0x46,0xFB
+ ,0x00,0x28,0x02,0xD0,0x00,0x20,0x04,0xB0,0xF0,0xBD
+ ,0x39,0x68,0x38,0x1C,0x89,0x89,0x2F,0x29,0x01,0xDA
+ ,0x00,0x20,0xF6,0xE7,0x20,0x22,0xF3,0x1D,0x19,0x33
+ ,0xB2,0x5C,0x5B,0x78,0x1B,0x02,0x1A,0x43,0x12,0x04
+ ,0x12,0x0C,0x00,0x92,0x14,0x2A,0x04,0xDB,0x7D,0x23
+ ,0x00,0x9A,0xDB,0x00,0x9A,0x42,0x01,0xDD,0x00,0x20
+ ,0xE3,0xE7,0x22,0x22,0xB2,0x5C,0x52,0x08,0x01,0xD2
+ ,0x00,0x20,0xDD,0xE7,0x24,0x27,0x04,0x39,0x24,0x29
+ ,0x34,0xDD,0xF0,0x5D,0x00,0x28,0x09,0xD0,0x01,0x28
+ ,0x11,0xD0,0x03,0x28,0x2B,0xD1,0xF0,0x19,0x41,0x78
+ ,0x01,0x29,0x19,0xD0,0x00,0x20,0xCC,0xE7,0xF0,0x19
+ ,0x40,0x78,0x20,0x28,0x01,0xD9,0x00,0x25,0x00,0xE0
+ ,0x01,0x25,0xC0,0x19,0x87,0x1C,0x15,0xE0,0xF0,0x19
+ ,0x02,0x90,0x01,0xA9,0xFF,0xF7,0x7B,0xFE,0x04,0x1C
+ ,0x01,0xD1,0x00,0x20,0xB9,0xE7,0x02,0x98,0x40,0x78
+ ,0xC0,0x19,0x87,0x1C,0x07,0xE0,0x2E,0x49,0x80,0x78
+ ,0x09,0x7D,0x88,0x42,0x01,0xD0,0x00,0x20,0xAD,0xE7
+ ,0x03,0x37,0x28,0x48,0x00,0x68,0x80,0x89,0x04,0x38
+ ,0xB8,0x42,0xCC,0xDC,0x00,0x2D,0x01,0xD1,0x00,0x20
+ ,0xA2,0xE7,0x25,0x49,0x01,0x23,0x0A,0x7D,0x21,0x1C
+ ,0x01,0xA8,0xFF,0xF7,0x8D,0xFD,0x00,0x28,0x00,0xD1
+ ,0x98,0xE7,0x22,0x4C,0x06,0x22,0xE0,0x1D,0x07,0x30
+ ,0x1F,0x4F,0x03,0x99,0xFC,0xF7,0xF2,0xFA,0xE0,0x1D
+ ,0x0D,0x30,0x20,0x22,0xF9,0x1D,0x15,0x31,0xFC,0xF7
+ ,0xEB,0xFA,0xF8,0x1D,0x39,0x30,0x81,0x78,0xE0,0x1D
+ ,0x29,0x30,0x01,0x71,0x01,0x79,0x18,0x48,0x20,0x23
+ ,0x01,0x75,0x00,0x9A,0x17,0x49,0x22,0x80,0x0A,0x78
+ ,0x1A,0x43,0x0A,0x70,0x0A,0x78,0x10,0x23,0x1A,0x43
+ ,0x0A,0x70,0x00,0x21,0x13,0x4A,0x50,0x30,0x41,0x70
+ ,0x91,0x70,0x05,0x21,0x81,0x71,0x04,0x20,0xF9,0xF7
+ ,0xFB,0xFC,0x01,0x21,0x04,0x20,0xFE,0xF7,0xCB,0xFA
+ ,0x0E,0x48,0x01,0x68,0x0E,0x48,0xC2,0x69,0x11,0x43
+ ,0xC1,0x61,0x0D,0x49,0x01,0x20,0x08,0x70,0x5D,0xE7
+ ,0x00,0x00,0x68,0x99,0x00,0x00,0x48,0x01,0x00,0x02
+ ,0xFC,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0xC0,0x00
+ ,0x00,0x02,0x80,0x00,0x00,0x02,0x44,0x09,0x00,0x02
+ ,0x94,0x01,0x00,0x02,0x04,0x01,0x00,0x02,0xA4,0x02
+ ,0x00,0x02,0x40,0x00,0x00,0x04,0x3A,0x01,0x00,0x02
+ ,0xF0,0xB4,0x1D,0x4A,0x1D,0x4B,0xD1,0x1D,0x69,0x31
+ ,0xC9,0x7A,0x49,0x00,0x5F,0x5A,0xD1,0x1D,0x59,0x31
+ ,0x0B,0x8B,0x01,0x3B,0x1B,0x04,0x1B,0x14,0x0B,0x83
+ ,0x00,0x2B,0x26,0xDD,0x17,0x4B,0x01,0x25,0x5C,0x7A
+ ,0x50,0x32,0xD3,0x79,0x00,0x2B,0x04,0xD1,0x05,0x30
+ ,0x0E,0x28,0x05,0xD9,0x0E,0x38,0x03,0xE0,0x01,0x30
+ ,0x0E,0x28,0x00,0xD9,0x01,0x20,0x00,0x2C,0x05,0xD1
+ ,0x2B,0x1C,0x46,0x1E,0xB3,0x40,0x3B,0x40,0x10,0xD1
+ ,0x07,0xE0,0xD3,0x79,0x00,0x2B,0x0C,0xD1,0x0A,0x4B
+ ,0x1B,0x18,0x5B,0x7B,0x00,0x2B,0x07,0xD1,0x0B,0x8B
+ ,0x01,0x3B,0x1B,0x04,0x1B,0x14,0x0B,0x83,0x00,0x2B
+ ,0xDC,0xDC,0x00,0x20,0xF0,0xBC,0xF7,0x46,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0x6C,0x02,0x00,0x02,0xB0,0x00
+ ,0x00,0x02,0x14,0x01,0x00,0x02,0xF0,0xB5,0x29,0x4C
+ ,0x07,0x1C,0x00,0x26,0x27,0x70,0xE0,0x1D,0x03,0x30
+ ,0x66,0x70,0x66,0x80,0x06,0x22,0x25,0x49,0xFC,0xF7
+ ,0x55,0xFA,0x25,0x4D,0xE0,0x1D,0x09,0x30,0x06,0x22
+ ,0xE9,0x1D,0x35,0x31,0xFC,0xF7,0x4D,0xFA,0xFF,0x20
+ ,0x20,0x71,0x60,0x71,0xA0,0x71,0xE0,0x71,0x20,0x72
+ ,0x60,0x72,0x38,0x1C,0x40,0x28,0x1D,0x4F,0x1D,0xD0
+ ,0x00,0xF0,0xE8,0xF8,0x00,0xF0,0xF0,0xF8,0xE5,0x1D
+ ,0x1D,0x35,0x28,0x1C,0x00,0xF0,0x0B,0xF9,0x2D,0x18
+ ,0x28,0x1C,0x00,0xF0,0x23,0xF9,0x2D,0x18,0x16,0x48
+ ,0x80,0x7D,0x02,0x28,0x03,0xD1,0x28,0x1C,0x00,0xF0
+ ,0x33,0xF9,0x2D,0x18,0x28,0x1C,0x00,0xF0,0x3D,0xF9
+ ,0x28,0x18,0x00,0x1B,0xF8,0x64,0xB8,0x64,0xF0,0xBD
+ ,0x26,0x76,0x0F,0x4E,0xE0,0x1D,0x72,0x79,0x13,0x30
+ ,0xE9,0x1D,0x15,0x31,0x62,0x76,0xFC,0xF7,0x1A,0xFA
+ ,0x70,0x79,0x00,0x19,0x1A,0x30,0x00,0xF0,0x03,0xF9
+ ,0x70,0x79,0x20,0x30,0x00,0x06,0x00,0x0E,0xB8,0x64
+ ,0xF0,0xBD,0x00,0x00,0x04,0x08,0x00,0x02,0x5C,0x00
+ ,0x00,0x02,0xC0,0x00,0x00,0x02,0x44,0x09,0x00,0x02
+ ,0x00,0x00,0x00,0x02,0x04,0x01,0x00,0x02,0xF8,0xB5
+ ,0x07,0x1C,0xFF,0xF7,0x9C,0xFF,0x00,0x26,0x80,0x2F
+ ,0x47,0x4D,0x0E,0xD1,0xC0,0x20,0xFB,0xF7,0x13,0xFE
+ ,0x04,0x1C,0x45,0x48,0x41,0x7B,0x03,0x29,0x03,0xD0
+ ,0x20,0x1C,0xFB,0xF7,0x0B,0xFE,0xF8,0xBD,0x01,0x21
+ ,0x41,0x73,0x10,0xE0,0x40,0x2F,0x05,0xD1,0x40,0x48
+ ,0x01,0x21,0x81,0x74,0x3F,0x48,0x46,0x80,0x08,0xE0
+ ,0x50,0x2F,0x06,0xD1,0x3E,0x48,0x3E,0x49,0x06,0x22
+ ,0xFC,0xF7,0xDC,0xF9,0x01,0x21,0x29,0x71,0x3C,0x48
+ ,0xF7,0xF7,0xAF,0xFF,0x50,0x2F,0x02,0xD1,0x36,0x48
+ ,0xC0,0x6C,0x01,0xE0,0x34,0x48,0x80,0x6C,0x33,0x49
+ ,0x88,0x66,0x37,0x48,0x89,0x6E,0xC0,0x79,0xF9,0xF7
+ ,0xEF,0xFA,0x30,0x49,0x50,0x2F,0xC8,0x66,0x0C,0xD1
+ ,0x2E,0x48,0x2E,0x49,0xC0,0x6E,0x48,0x80,0x31,0x48
+ ,0xC0,0x79,0xF9,0xF7,0x83,0xFF,0x2B,0x49,0x49,0x88
+ ,0x40,0x18,0x29,0x49,0x48,0x80,0x28,0x48,0x27,0x49
+ ,0x80,0x2F,0x48,0x66,0x16,0xD1,0xFC,0xF7,0x31,0xFA
+ ,0x2A,0x49,0x89,0x89,0x49,0x00,0x01,0x31,0x08,0x40
+ ,0x21,0x49,0x88,0x62,0x27,0x48,0x00,0x88,0x08,0x62
+ ,0x89,0x6A,0x8B,0x00,0x59,0x18,0x89,0x00,0x09,0x18
+ ,0x08,0x20,0xF9,0xF7,0xB3,0xFB,0x20,0x1C,0xFB,0xF7
+ ,0xB8,0xFD,0xF8,0xF7,0xEC,0xFF,0xF9,0xF7,0x56,0xF8
+ ,0x00,0x90,0x80,0x2F,0x05,0xD1,0x00,0x98,0x00,0x28
+ ,0x23,0xD1,0x01,0x21,0x69,0x70,0x20,0xE0,0x40,0x2F
+ ,0x1E,0xD1,0x12,0x4C,0xC0,0x20,0xA6,0x74,0xFB,0xF7
+ ,0xA4,0xFD,0x07,0x1C,0xA8,0x79,0x01,0x28,0x12,0xD1
+ ,0x00,0x98,0x00,0x28,0x0D,0xD1,0xE0,0x1D,0x69,0x30
+ ,0x81,0x7A,0x00,0x29,0x0A,0xD1,0x01,0x21,0x81,0x72
+ ,0x0E,0x49,0xC8,0x8A,0x81,0x02,0x04,0x20,0xF9,0xF7
+ ,0x88,0xFB,0x01,0xE0,0x01,0x21,0x69,0x71,0x38,0x1C
+ ,0xFB,0xF7,0x8A,0xFD,0x7D,0xE7,0x00,0x00,0x94,0x09
+ ,0x00,0x02,0x54,0x09,0x00,0x02,0x44,0x09,0x00,0x02
+ ,0x04,0x08,0x00,0x02,0x08,0x08,0x00,0x02,0x30,0x01
+ ,0x00,0x02,0x1A,0x08,0x00,0x02,0x04,0x01,0x00,0x02
+ ,0xC0,0x00,0x00,0x02,0xA8,0x01,0x00,0x02,0x03,0x49
+ ,0x02,0x48,0x09,0x88,0x01,0x80,0xF7,0x46,0x00,0x00
+ ,0x24,0x08,0x00,0x02,0x80,0x00,0x00,0x02,0x0D,0x49
+ ,0x0C,0x48,0x8A,0x7A,0x92,0x00,0x02,0x80,0xC9,0x7A
+ ,0x00,0x29,0x03,0xD0,0x01,0x88,0x10,0x23,0x19,0x43
+ ,0x01,0x80,0x08,0x49,0x49,0x7A,0x01,0x29,0x04,0xD1
+ ,0x01,0x88,0x22,0x23,0x19,0x43,0x01,0x80,0xF7,0x46
+ ,0x01,0x88,0x02,0x23,0x19,0x43,0x01,0x80,0xF7,0x46
+ ,0x26,0x08,0x00,0x02,0x80,0x00,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0x90,0xB4,0x01,0x1C,0x00,0x20,0x0A,0x4A
+ ,0x08,0x70,0x53,0x79,0x00,0x2B,0x08,0xD9,0x08,0x4B
+ ,0x1F,0x18,0x3F,0x7D,0x0C,0x18,0x01,0x30,0xA7,0x70
+ ,0x57,0x79,0x87,0x42,0xF7,0xD8,0x50,0x79,0x48,0x70
+ ,0x50,0x79,0x90,0xBC,0x02,0x30,0xF7,0x46,0x00,0x00
+ ,0x04,0x01,0x00,0x02,0x80,0x00,0x00,0x02,0x90,0xB4
+ ,0x01,0x1C,0x01,0x20,0x08,0x70,0x00,0x20,0x08,0x4B
+ ,0x00,0x22,0x9F,0x18,0x3F,0x7C,0x00,0x2F,0x02,0xD0
+ ,0x0C,0x18,0xA7,0x70,0x01,0x30,0x01,0x32,0x04,0x2A
+ ,0xF5,0xD3,0x48,0x70,0x90,0xBC,0x02,0x30,0xF7,0x46
+ ,0x00,0x00,0x00,0x00,0x00,0x02,0x03,0x21,0x01,0x70
+ ,0x01,0x22,0x42,0x70,0x01,0x30,0x80,0x18,0x02,0x4A
+ ,0x12,0x7D,0x02,0x70,0x08,0x1C,0xF7,0x46,0x00,0x00
+ ,0x00,0x00,0x00,0x02,0x06,0x21,0x01,0x70,0x02,0x21
+ ,0x41,0x70,0x04,0x49,0x02,0x30,0x0A,0x89,0x02,0x70
+ ,0x09,0x89,0x09,0x0A,0x41,0x70,0x04,0x20,0xF7,0x46
+ ,0x00,0x00,0x80,0x00,0x00,0x02,0x0A,0x21,0x01,0x70
+ ,0x02,0x21,0x41,0x70,0x00,0x21,0x81,0x70,0x02,0x30
+ ,0x41,0x1C,0x07,0x20,0x08,0x70,0x04,0x20,0xF7,0x46
+ ,0xF0,0xB5,0x83,0xB0,0x51,0x48,0x52,0x4D,0x48,0x21
+ ,0x01,0x70,0x01,0x26,0xEC,0x1D,0x29,0x34,0x46,0x70
+ ,0x62,0x79,0x11,0x21,0x4E,0x4F,0x02,0x2A,0x01,0xD1
+ ,0x41,0x70,0x05,0xE0,0x03,0x2A,0x03,0xD1,0xBA,0x78
+ ,0x08,0x2A,0x00,0xD1,0x41,0x70,0x4A,0x49,0x09,0x68
+ ,0x89,0x78,0x00,0x29,0x03,0xD0,0x41,0x78,0x08,0x23
+ ,0x19,0x43,0x41,0x70,0x46,0x49,0x00,0x23,0x00,0x22
+ ,0x46,0x48,0xC9,0x79,0xF7,0xF7,0x8F,0xFE,0x45,0x48
+ ,0x45,0x49,0x06,0x22,0xFC,0xF7,0xA4,0xF8,0xE9,0x1D
+ ,0x07,0x31,0x0D,0x1C,0x06,0x22,0x42,0x48,0xFC,0xF7
+ ,0x9D,0xF8,0x29,0x1C,0x06,0x22,0x41,0x48,0xFC,0xF7
+ ,0x98,0xF8,0x40,0x4D,0x18,0x20,0xA8,0x66,0x39,0x48
+ ,0x18,0x21,0xC0,0x79,0xF9,0xF7,0xB6,0xF9,0xE8,0x66
+ ,0x32,0x48,0xEE,0x1D,0x68,0x66,0x01,0x20,0x49,0x36
+ ,0xF0,0x70,0xF8,0xF7,0xD9,0xFE,0xF8,0xF7,0x43,0xFF
+ ,0x02,0x90,0x00,0x20,0xF0,0x70,0x02,0x98,0x00,0x28
+ ,0x01,0xD0,0x03,0xB0,0xF0,0xBD,0x02,0x26,0x2C,0x48
+ ,0x6E,0x60,0xC0,0x79,0x32,0x49,0x40,0x00,0x08,0x5A
+ ,0x31,0x49,0xC9,0x88,0x40,0x18,0x31,0x49,0x09,0x88
+ ,0x41,0x18,0x01,0x20,0xF9,0xF7,0x81,0xFA,0x00,0x22
+ ,0xD2,0x43,0x6E,0x74,0x00,0x92,0x01,0x22,0x10,0x21
+ ,0x01,0xAB,0x2B,0x48,0xFB,0xF7,0x1D,0xFC,0x00,0x20
+ ,0x1E,0x49,0x68,0x74,0x0A,0x68,0x53,0x78,0x00,0x2B
+ ,0x22,0xD0,0x93,0x78,0x01,0x33,0x1B,0x06,0x1B,0x0E
+ ,0x93,0x70,0x04,0x2B,0x02,0xDA,0x09,0x68,0x48,0x70
+ ,0xD2,0xE7,0x60,0x79,0x01,0x28,0x1F,0xDD,0x02,0x28
+ ,0x03,0xD1,0xBA,0x78,0x08,0x23,0x9A,0x43,0xBA,0x70
+ ,0x03,0x28,0x17,0xD1,0x0E,0x48,0x40,0x78,0x40,0x09
+ ,0x06,0xD3,0x01,0x20,0xF8,0x70,0xB8,0x78,0x08,0x23
+ ,0x98,0x43,0xB8,0x70,0x0C,0xE0,0x01,0x20,0xB8,0x71
+ ,0x09,0xE0,0x60,0x79,0x03,0x28,0x06,0xD1,0x05,0x4A
+ ,0x01,0x20,0x52,0x78,0x52,0x09,0x00,0xD3,0x00,0x20
+ ,0xF8,0x70,0x09,0x68,0x40,0x20,0x08,0x70,0xAB,0xE7
+ ,0x00,0x00,0x04,0x08,0x00,0x02,0x80,0x00,0x00,0x02
+ ,0xB4,0x09,0x00,0x02,0xD0,0x01,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0x06,0x08,0x00,0x02,0x0E,0x08,0x00,0x02
+ ,0x5C,0x00,0x00,0x02,0x14,0x08,0x00,0x02,0x08,0x08
+ ,0x00,0x02,0x44,0x09,0x00,0x02,0xB0,0x01,0x00,0x02
+ ,0x00,0x00,0x00,0x02,0xAE,0x01,0x00,0x02,0xF8,0x06
+ ,0x00,0x02,0xF8,0xB4,0x00,0x26,0x82,0x1C,0x06,0x29
+ ,0x01,0xD3,0x48,0x08,0x02,0xD3,0x00,0x20,0xF8,0xBC
+ ,0xF7,0x46,0x00,0x24,0x03,0x23,0x00,0x25,0xCF,0x1E
+ ,0x17,0xD0,0x01,0x39,0xD0,0x5C,0x99,0x42,0x02,0xD1
+ ,0x00,0x28,0x0F,0xD1,0x0C,0xE0,0x0E,0x28,0x0C,0xD8
+ ,0x01,0x28,0x0A,0xD3,0xA8,0x42,0x08,0xD3,0xD5,0x18
+ ,0x6D,0x78,0x03,0x33,0x03,0x34,0x2D,0x18,0xA7,0x42
+ ,0xEC,0xD8,0x01,0x2E,0x01,0xD1,0x00,0x20,0xE0,0xE7
+ ,0x1B,0x48,0xC0,0x79,0x01,0x28,0x00,0xD1,0xDB,0xE7
+ ,0x19,0x48,0xC1,0x1D,0x29,0x31,0x49,0x7A,0x00,0x29
+ ,0x01,0xD1,0x01,0x20,0xD3,0xE7,0x91,0x78,0x3A,0x30
+ ,0x00,0x23,0x81,0x70,0x51,0x78,0x41,0x70,0x11,0x78
+ ,0x01,0x70,0x03,0x21,0x00,0x2F,0x1B,0xD9,0x50,0x5C
+ ,0x00,0x28,0x18,0xD0,0x0F,0x4D,0x01,0x26,0x2C,0x18
+ ,0x66,0x73,0x54,0x18,0x00,0x94,0x64,0x78,0x24,0x18
+ ,0xA0,0x42,0x0A,0xD2,0x0A,0x4D,0x01,0x26,0x2D,0x18
+ ,0x6E,0x73,0x00,0x9E,0x10,0x3D,0xB6,0x78,0x01,0x30
+ ,0xA0,0x42,0xEE,0x73,0xF4,0xD3,0x03,0x31,0x03,0x33
+ ,0x9F,0x42,0xE3,0xD8,0x01,0x20,0xAA,0xE7,0x00,0x00
+ ,0xB4,0x09,0x00,0x02,0x80,0x00,0x00,0x02,0x14,0x01
+ ,0x00,0x02,0xF1,0xB5,0x81,0xB0,0x22,0x4F,0x01,0x9E
+ ,0x3F,0x68,0x00,0x24,0xBF,0x89,0x00,0x21,0x24,0x20
+ ,0x3D,0x1F,0x00,0x95,0x24,0x2D,0x39,0xD9,0x1E,0x4F
+ ,0x7F,0x7A,0x35,0x5C,0x03,0x2D,0x08,0xD0,0x07,0x2D
+ ,0x0D,0xD1,0x35,0x18,0x6D,0x78,0x01,0x24,0x03,0x1C
+ ,0x02,0x35,0x28,0x18,0x0A,0xE0,0x35,0x18,0x6D,0x78
+ ,0x01,0x21,0x02,0x1C,0x02,0x35,0x28,0x18,0x05,0xE0
+ ,0x35,0x18,0x6D,0x78,0x02,0x35,0x28,0x18,0x00,0x29
+ ,0x01,0xD0,0x00,0x2F,0x02,0xD0,0x00,0x9D,0x85,0x42
+ ,0xE1,0xD8,0x00,0x29,0x17,0xD0,0xB0,0x18,0x40,0x78
+ ,0x01,0x28,0x01,0xD0,0x02,0xB0,0xF0,0xBD,0x01,0x2F
+ ,0x0F,0xD1,0x00,0x2C,0x0D,0xD0,0x01,0x98,0xC0,0x18
+ ,0x41,0x78,0xFF,0xF7,0x5E,0xFF,0x00,0x28,0x00,0xD1
+ ,0xF1,0xE7,0x05,0x48,0xC1,0x79,0x00,0x29,0x01,0xD1
+ ,0x01,0x21,0xC1,0x71,0xEA,0xE7,0x48,0x01,0x00,0x02
+ ,0xB0,0x00,0x00,0x02,0xB4,0x09,0x00,0x02,0x00,0xB5
+ ,0x05,0x49,0x89,0x7C,0x01,0x29,0x04,0xD1,0x01,0x78
+ ,0x80,0x29,0x01,0xD1,0xFF,0xF7,0xA8,0xFF,0x00,0xBD
+ ,0x00,0x00,0xC0,0x00,0x00,0x02,0x90,0xB5,0x10,0x4C
+ ,0x60,0x78,0x00,0x28,0x1A,0xD0,0x0F,0x4F,0x38,0x68
+ ,0x40,0x68,0x42,0x7E,0x18,0x30,0x00,0x2A,0x09,0xD0
+ ,0x0C,0x49,0x49,0x79,0x91,0x42,0x0F,0xD1,0x0B,0x49
+ ,0x02,0x30,0xFB,0xF7,0x1A,0xFF,0x00,0x28,0x09,0xD1
+ ,0x38,0x68,0x40,0x68,0xC1,0x1D,0x03,0x31,0x06,0x22
+ ,0x07,0x48,0xFB,0xF7,0x2E,0xFF,0x01,0x20,0xA0,0x70
+ ,0x90,0xBD,0x00,0x00,0x94,0x09,0x00,0x02,0x48,0x01
+ ,0x00,0x02,0x04,0x01,0x00,0x02,0x94,0x00,0x00,0x02
+ ,0x30,0x01,0x00,0x02,0xB0,0xB4,0x03,0x78,0x00,0x27
+ ,0x20,0x49,0x20,0x4A,0x08,0x2B,0x37,0xD1,0xD3,0x78
+ ,0x00,0x2B,0x04,0xD0,0xD0,0x7A,0x09,0x68,0x88,0x75
+ ,0xB0,0xBC,0xF7,0x46,0x00,0x79,0x40,0x08,0x03,0xD3
+ ,0x90,0x7A,0x09,0x68,0x88,0x75,0xF6,0xE7,0x0B,0x68
+ ,0x99,0x7D,0xD2,0x7A,0x91,0x42,0x01,0xDD,0x9A,0x75
+ ,0xEF,0xE7,0x15,0x4C,0x08,0x19,0x00,0x7C,0x00,0x28
+ ,0xEA,0xD1,0x08,0x1C,0x01,0x29,0x0A,0xD3,0x01,0x38
+ ,0x25,0x18,0x2D,0x7C,0x00,0x2D,0x03,0xD1,0x01,0x28
+ ,0xF8,0xD2,0x00,0x2F,0x01,0xD0,0x98,0x75,0xDC,0xE7
+ ,0x8A,0x42,0x06,0xD9,0x01,0x31,0x60,0x18,0x00,0x7C
+ ,0x00,0x28,0x03,0xD1,0x8A,0x42,0xF8,0xD8,0x00,0x2F
+ ,0x01,0xD0,0x99,0x75,0xCF,0xE7,0x9A,0x75,0xCD,0xE7
+ ,0xD0,0x79,0x09,0x68,0x88,0x75,0xC9,0xE7,0x00,0x00
+ ,0xC4,0x01,0x00,0x02,0x04,0x01,0x00,0x02,0x00,0x00
+ ,0x00,0x02,0x00,0xB5,0x07,0x48,0x81,0x79,0x03,0x29
+ ,0x02,0xD0,0x81,0x79,0x04,0x29,0x05,0xD1,0x00,0x21
+ ,0x81,0x71,0x07,0x21,0x04,0x20,0xFD,0xF7,0xCA,0xFE
+ ,0x00,0xBD,0x00,0x00,0x94,0x09,0x00,0x02,0x90,0xB5
+ ,0x27,0x48,0x27,0x49,0x00,0x68,0x47,0x68,0x22,0x20
+ ,0x38,0x5C,0x10,0x23,0x18,0x40,0x03,0xD0,0x08,0x78
+ ,0x00,0x28,0x41,0xD0,0x02,0xE0,0x08,0x78,0x00,0x28
+ ,0x3D,0xD1,0x24,0x20,0x38,0x5C,0x00,0x28,0x39,0xD1
+ ,0xF8,0x1D,0x1D,0x30,0x44,0x78,0x1D,0x49,0x00,0x2C
+ ,0x02,0xD0,0x4A,0x79,0xA2,0x42,0x30,0xD1,0x4A,0x79
+ ,0x1B,0x49,0x02,0x30,0xFB,0xF7,0x83,0xFE,0x00,0x28
+ ,0x29,0xD1,0x38,0x19,0x20,0x30,0xC0,0x79,0x00,0x19
+ ,0x28,0x30,0x39,0x5C,0x03,0x29,0x21,0xD1,0x38,0x18
+ ,0x14,0x49,0x80,0x78,0x09,0x7D,0x88,0x42,0x1B,0xD1
+ ,0x13,0x48,0x40,0x7A,0x00,0x28,0x05,0xD0,0x12,0x48
+ ,0x08,0x18,0x40,0x7B,0x00,0x28,0x12,0xD0,0x09,0xE0
+ ,0x10,0x48,0x10,0x4A,0xC0,0x7A,0x40,0x00,0x10,0x5A
+ ,0x01,0x22,0x01,0x39,0x8A,0x40,0x10,0x40,0x07,0xD0
+ ,0x01,0x20,0xF8,0xF7,0x7A,0xF9,0x00,0x28,0x02,0xD0
+ ,0x02,0x20,0xFF,0xF7,0xFD,0xF9,0x90,0xBD,0x48,0x01
+ ,0x00,0x02,0x18,0x00,0x00,0x02,0x04,0x01,0x00,0x02
+ ,0xDC,0x00,0x00,0x02,0x00,0x00,0x00,0x02,0xB0,0x00
+ ,0x00,0x02,0x14,0x01,0x00,0x02,0xB4,0x09,0x00,0x02
+ ,0x6C,0x02,0x00,0x02,0x80,0xB5,0xFD,0xF7,0x93,0xFD
+ ,0x1A,0x48,0x00,0xF0,0x58,0xFD,0x19,0x4B,0x1A,0x48
+ ,0x59,0x7A,0x01,0x29,0x04,0xD1,0x48,0x21,0x41,0x81
+ ,0x18,0x21,0x01,0x81,0x03,0xE0,0x90,0x21,0x41,0x81
+ ,0x30,0x21,0x01,0x81,0x41,0x89,0x02,0x89,0x14,0x4F
+ ,0x89,0x18,0x12,0x4A,0x11,0x80,0xC2,0x88,0x80,0x88
+ ,0x11,0x18,0x09,0x18,0x39,0x80,0x51,0x18,0xFF,0x31
+ ,0x10,0x4A,0x31,0x31,0x11,0x80,0x19,0x88,0x10,0x4F
+ ,0x48,0x43,0x0E,0x49,0x08,0x80,0xD8,0x79,0x0E,0x49
+ ,0x38,0x70,0x38,0x78,0x08,0x70,0xF7,0xF7,0xC0,0xFA
+ ,0xF8,0xF7,0x8C,0xFF,0x39,0x78,0x0B,0x48,0x40,0x5C
+ ,0x0B,0x49,0x08,0x70,0x80,0xBD,0x5C,0x00,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0x00,0x00,0x00,0x02,0xAC,0x01
+ ,0x00,0x02,0xA8,0x01,0x00,0x02,0xAA,0x01,0x00,0x02
+ ,0xAE,0x01,0x00,0x02,0x92,0x01,0x00,0x02,0x93,0x01
+ ,0x00,0x02,0xC0,0x01,0x00,0x02,0x91,0x01,0x00,0x02
+ ,0x80,0xB4,0x21,0x48,0x00,0x21,0x01,0x70,0x00,0x20
+ ,0x19,0x27,0x1F,0x4A,0xFF,0x02,0x11,0x54,0x01,0x30
+ ,0xB8,0x42,0xFB,0xDB,0x00,0x20,0x43,0x27,0x1C,0x4A
+ ,0x7F,0x02,0x11,0x54,0x01,0x30,0xB8,0x42,0xFB,0xDB
+ ,0x1A,0x48,0x18,0x4A,0x01,0x80,0x1A,0x48,0x1A,0x4B
+ ,0x02,0x60,0x13,0x60,0x02,0x68,0xD7,0x1D,0x15,0x37
+ ,0x57,0x60,0x02,0x68,0x08,0x3F,0x97,0x60,0x02,0x68
+ ,0x11,0x73,0x02,0x68,0x91,0x73,0x07,0x68,0x03,0x22
+ ,0xBA,0x75,0x02,0x68,0x91,0x82,0x00,0x68,0x11,0x4A
+ ,0x10,0x60,0x11,0x48,0x0C,0x4A,0x01,0x80,0x11,0x48
+ ,0x02,0x60,0x13,0x60,0x02,0x68,0xD3,0x1D,0x11,0x33
+ ,0x53,0x60,0x02,0x68,0x91,0x81,0x02,0x68,0x11,0x72
+ ,0x00,0x68,0x0C,0x49,0x08,0x60,0x0C,0x49,0x01,0x20
+ ,0x08,0x70,0x80,0xBC,0xF7,0x46,0x94,0x01,0x00,0x02
+ ,0x00,0x11,0x00,0x02,0x00,0xDA,0x00,0x02,0xF0,0x01
+ ,0x00,0x02,0xC4,0x01,0x00,0x02,0x00,0x00,0x00,0x80
+ ,0x68,0x02,0x00,0x02,0xF2,0x01,0x00,0x02,0x48,0x01
+ ,0x00,0x02,0x64,0x02,0x00,0x02,0xDF,0x01,0x00,0x02
+ ,0xF0,0xB5,0x82,0xB0,0x39,0x4E,0xF7,0x1D,0x69,0x37
+ ,0xB8,0x78,0x04,0x23,0x18,0x40,0x40,0x24,0x00,0x25
+ ,0x00,0x28,0x03,0xD1,0x7D,0x71,0x3C,0x71,0x02,0xB0
+ ,0xF0,0xBD,0x33,0x49,0xA4,0x20,0x08,0x70,0x10,0x20
+ ,0x48,0x70,0x32,0x48,0x03,0x23,0xC0,0x88,0x9B,0x03
+ ,0x18,0x43,0x48,0x80,0xC8,0x1D,0x03,0x30,0x06,0x22
+ ,0x2E,0x49,0xFB,0xF7,0x99,0xFD,0x2E,0x49,0x2E,0x48
+ ,0x06,0x22,0xFB,0xF7,0x94,0xFD,0x10,0x20,0x2D,0x49
+ ,0xB0,0x66,0xC8,0x79,0x10,0x21,0xF8,0xF7,0xB3,0xFE
+ ,0xF0,0x66,0x24,0x48,0x70,0x66,0x01,0x20,0x38,0x70
+ ,0xF8,0xF7,0xD8,0xFB,0xF8,0xF7,0x42,0xFC,0x3D,0x70
+ ,0x82,0x25,0x00,0x28,0x2E,0xD1,0x23,0x49,0x24,0x48
+ ,0xC9,0x79,0x24,0x4A,0xC0,0x88,0x49,0x00,0x51,0x5A
+ ,0x40,0x18,0x22,0x49,0x09,0x88,0x41,0x18,0x01,0x20
+ ,0x38,0x71,0x04,0x20,0x70,0x60,0x01,0x20,0xF8,0xF7
+ ,0x82,0xFF,0x00,0x22,0xD2,0x43,0x00,0x92,0x01,0x22
+ ,0x11,0x21,0x01,0xAB,0x1B,0x48,0xFB,0xF7,0x1F,0xF9
+ ,0x01,0x98,0x41,0x08,0x01,0xD3,0x3C,0x71,0x1A,0xE0
+ ,0x40,0x09,0x18,0xD3,0x78,0x79,0x17,0x49,0x01,0x30
+ ,0x00,0x06,0x00,0x0E,0x78,0x71,0x09,0x7C,0x88,0x42
+ ,0x01,0xDA,0x3D,0x71,0x0D,0xE0,0x3C,0x71,0x0B,0xE0
+ ,0x78,0x79,0x10,0x49,0x01,0x30,0x00,0x06,0x00,0x0E
+ ,0x78,0x71,0x09,0x7C,0x88,0x42,0x01,0xDA,0x3D,0x71
+ ,0x00,0xE0,0x3C,0x71,0x97,0xE7,0x44,0x09,0x00,0x02
+ ,0x04,0x08,0x00,0x02,0x80,0x00,0x00,0x02,0x5C,0x00
+ ,0x00,0x02,0x8E,0x00,0x00,0x02,0x08,0x08,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0x00,0x00,0x00,0x02,0xB0,0x01
+ ,0x00,0x02,0xAE,0x01,0x00,0x02,0x38,0x07,0x00,0x02
+ ,0xC0,0x00,0x00,0x02,0x80,0xB5,0xC0,0x20,0xFB,0xF7
+ ,0x44,0xF9,0x07,0x1C,0x12,0x48,0x01,0x68,0x01,0x31
+ ,0x01,0x60,0x11,0x48,0xFB,0xF7,0x64,0xFD,0x00,0x29
+ ,0x17,0xD1,0x0F,0x48,0x10,0x4A,0x03,0x78,0x10,0x49
+ ,0x00,0x2B,0x06,0xD1,0x09,0x68,0xD3,0x69,0x19,0x43
+ ,0xD1,0x61,0x01,0x21,0x01,0x70,0x0A,0xE0,0x0C,0x4B
+ ,0x9B,0x79,0x05,0x2B,0x06,0xD0,0x09,0x68,0xD3,0x69
+ ,0xC9,0x43,0x19,0x40,0xD1,0x61,0x00,0x21,0x01,0x70
+ ,0x38,0x1C,0xFB,0xF7,0x1F,0xF9,0x80,0xBD,0xD4,0x02
+ ,0x00,0x02,0x20,0x4E,0x00,0x00,0x3A,0x01,0x00,0x02
+ ,0x40,0x00,0x00,0x04,0xA4,0x02,0x00,0x02,0x94,0x09
+ ,0x00,0x02,0x90,0xB5,0xC0,0x20,0xFB,0xF7,0x0E,0xF9
+ ,0x07,0x1C,0x0F,0x48,0x81,0x7A,0x00,0x29,0x15,0xD1
+ ,0x01,0x7B,0x01,0x29,0x12,0xD1,0xC1,0x7A,0x00,0x29
+ ,0x0F,0xD1,0x00,0x24,0x0A,0x49,0x50,0x30,0x0C,0x70
+ ,0x44,0x70,0x00,0xF0,0x1E,0xFB,0x08,0x48,0x01,0x21
+ ,0x84,0x61,0x07,0x20,0xFD,0xF7,0xDC,0xFC,0x06,0x49
+ ,0x01,0x20,0x08,0x70,0x38,0x1C,0xFB,0xF7,0xF0,0xF8
+ ,0x90,0xBD,0x00,0x00,0x44,0x09,0x00,0x02,0x3C,0x01
+ ,0x00,0x02,0x80,0x00,0x00,0x04,0xB3,0x02,0x00,0x02
+ ,0x90,0xB5,0x14,0x4C,0x14,0x4F,0x61,0x79,0x03,0x29
+ ,0x0C,0xD1,0x01,0x23,0x1B,0x03,0x98,0x42,0x08,0xD1
+ ,0x19,0x21,0xC9,0x02,0x02,0x20,0xF8,0xF7,0xCF,0xFE
+ ,0xB8,0x78,0x08,0x23,0x98,0x43,0xB8,0x70,0xB8,0x78
+ ,0x01,0x28,0x0C,0xD1,0x00,0xF0,0xAA,0xFA,0x60,0x79
+ ,0x02,0x28,0x08,0xD1,0xB8,0x78,0x08,0x23,0x18,0x43
+ ,0xB8,0x70,0xB8,0x78,0x40,0x08,0x40,0x00,0xB8,0x70
+ ,0x90,0xBD,0xB8,0x78,0x40,0x08,0x40,0x00,0xB8,0x70
+ ,0x90,0xBD,0x00,0x00,0xB0,0x00,0x00,0x02,0xB4,0x09
+ ,0x00,0x02,0x80,0xB5,0x18,0x48,0x81,0x7A,0x00,0x29
+ ,0x1C,0xD1,0x01,0x7B,0x01,0x29,0x19,0xD1,0xC0,0x7A
+ ,0x00,0x28,0x16,0xD1,0x14,0x4F,0xF8,0x1D,0x29,0x30
+ ,0x40,0x79,0x03,0x28,0x14,0xD1,0xF8,0xF7,0x79,0xFE
+ ,0x39,0x88,0x11,0x4B,0x10,0x4F,0x89,0x02,0x08,0x1A
+ ,0x98,0x42,0x08,0xD9,0xC1,0x1A,0x06,0x20,0xF8,0xF7
+ ,0x92,0xFE,0x00,0xF0,0xBA,0xFA,0x01,0x20,0xB8,0x70
+ ,0x80,0xBD,0x00,0x20,0xB8,0x70,0x80,0xBD,0x01,0x20
+ ,0x80,0x06,0x08,0x49,0x40,0x6A,0x06,0x4B,0x49,0x68
+ ,0xC0,0x18,0x88,0x42,0xF2,0xD2,0x00,0xF0,0xA9,0xFA
+ ,0x80,0xBD,0x44,0x09,0x00,0x02,0x80,0x00,0x00,0x02
+ ,0xB4,0x09,0x00,0x02,0xB8,0x0B,0x00,0x00,0x80,0x00
+ ,0x00,0x04,0xF0,0xB5,0xC0,0x20,0xFB,0xF7,0x78,0xF8
+ ,0x05,0x1C,0x00,0x26,0x34,0x48,0x07,0x24,0x64,0x06
+ ,0x06,0x70,0xE0,0x69,0x10,0x23,0x98,0x43,0xE0,0x61
+ ,0x31,0x48,0xC1,0x69,0x03,0x0C,0x19,0x43,0xC1,0x61
+ ,0xC1,0x69,0x1B,0x23,0x99,0x43,0xC1,0x61,0xC1,0x69
+ ,0x73,0x1F,0x19,0x40,0xC1,0x61,0xC1,0x69,0x83,0x01
+ ,0x19,0x43,0xC1,0x61,0x2A,0x49,0xC2,0x69,0x09,0x68
+ ,0xC9,0x43,0x11,0x40,0xC1,0x61,0xA1,0x69,0x01,0x23
+ ,0x19,0x43,0xA1,0x61,0x0F,0x22,0x12,0x06,0x25,0x4B
+ ,0x11,0x89,0xD9,0x69,0x01,0x05,0x00,0x68,0xCF,0x68
+ ,0x10,0x88,0xC9,0x6B,0x04,0x27,0x21,0x48,0x23,0x49
+ ,0x06,0x70,0x21,0x48,0x9E,0x61,0x07,0x70,0x01,0x20
+ ,0x08,0x70,0x20,0x48,0x06,0x70,0x20,0x48,0x06,0x70
+ ,0x20,0x48,0xC6,0x74,0x20,0x48,0x06,0x70,0xFA,0xF7
+ ,0xA0,0xF9,0x1B,0x48,0x00,0x78,0x00,0x28,0x03,0xD1
+ ,0xA0,0x69,0xFD,0x23,0x18,0x40,0xA0,0x61,0xFA,0xF7
+ ,0x0C,0xFB,0xFA,0xF7,0x76,0xFB,0x0A,0x20,0xF7,0xF7
+ ,0x71,0xF8,0xFA,0xF7,0x69,0xFB,0x15,0x48,0x01,0x21
+ ,0xC2,0x1D,0x49,0x32,0x07,0x75,0x91,0x71,0x56,0x70
+ ,0x13,0x4B,0x02,0x22,0x1A,0x70,0x13,0x4B,0x70,0x30
+ ,0x19,0x70,0x12,0x4B,0x59,0x71,0x86,0x70,0x12,0x48
+ ,0x02,0x70,0xF7,0xF7,0x63,0xF8,0x28,0x1C,0xFB,0xF7
+ ,0x0E,0xF8,0xF0,0xBD,0x00,0x00,0xDE,0x01,0x00,0x02
+ ,0x40,0x00,0x00,0x04,0xB4,0x02,0x00,0x02,0x80,0x00
+ ,0x00,0x04,0x3C,0x01,0x00,0x02,0x53,0x02,0x00,0x02
+ ,0x5E,0x02,0x00,0x02,0x36,0x01,0x00,0x02,0x37,0x01
+ ,0x00,0x02,0x44,0x09,0x00,0x02,0x51,0x02,0x00,0x02
+ ,0xB2,0x02,0x00,0x02,0xB3,0x02,0x00,0x02,0xB0,0x00
+ ,0x00,0x02,0x3B,0x01,0x00,0x02,0x90,0xB5,0x22,0x49
+ ,0x00,0x27,0xC8,0x1D,0x49,0x30,0x82,0x79,0x01,0x2A
+ ,0x00,0xD0,0x47,0x71,0xCA,0x1D,0x69,0x32,0x93,0x79
+ ,0x1D,0x49,0x00,0x2B,0x03,0xD0,0x97,0x71,0x01,0x20
+ ,0x88,0x73,0x90,0xBD,0x52,0x78,0x00,0x2A,0x02,0xD0
+ ,0xFD,0xF7,0xCC,0xFB,0x90,0xBD,0x02,0x78,0x00,0x2A
+ ,0x03,0xD0,0x47,0x71,0xFD,0xF7,0x7D,0xFA,0x90,0xBD
+ ,0x42,0x79,0x00,0x2A,0x02,0xD0,0xFD,0xF7,0xAD,0xFA
+ ,0x90,0xBD,0x82,0x78,0x00,0x2A,0x02,0xD0,0xFD,0xF7
+ ,0x91,0xFA,0x90,0xBD,0xC9,0x7B,0x00,0x29,0x02,0xD0
+ ,0xFD,0xF7,0x97,0xFA,0x90,0xBD,0x80,0x79,0x05,0x28
+ ,0x0D,0xD1,0x0A,0x4C,0x20,0x68,0x01,0x7B,0xC9,0x09
+ ,0x02,0xD3,0xF9,0xF7,0x1A,0xFA,0x90,0xBD,0x01,0x7B
+ ,0x10,0x29,0x02,0xD1,0xF9,0xF7,0x2C,0xFB,0x20,0x60
+ ,0x38,0x1C,0x90,0xBD,0x00,0x00,0x44,0x09,0x00,0x02
+ ,0x54,0x09,0x00,0x02,0xC4,0x01,0x00,0x02,0xB0,0xB5
+ ,0x0C,0x1C,0x07,0x1C,0x01,0x28,0x01,0xD3,0x0E,0x2F
+ ,0x01,0xD9,0x00,0x20,0xB0,0xBD,0x1B,0x4D,0xE8,0x69
+ ,0x2B,0x0C,0x18,0x43,0xE8,0x61,0x19,0x48,0xE9,0x69
+ ,0x00,0x68,0x08,0x43,0xE8,0x61,0x18,0x48,0xE9,0x69
+ ,0x00,0x68,0x08,0x43,0xE8,0x61,0xE8,0x69,0x04,0x23
+ ,0x18,0x43,0xE8,0x61,0x14,0x48,0xF6,0xF7,0xCD,0xFF
+ ,0x00,0xF0,0xBF,0xF8,0x01,0x2C,0x01,0xD1,0x00,0xF0
+ ,0xF1,0xF9,0x00,0xF0,0x81,0xF8,0x10,0x48,0x00,0x78
+ ,0x01,0x28,0x0A,0xD1,0x0E,0x2F,0x04,0xD1,0xE8,0x69
+ ,0x40,0x23,0x98,0x43,0xE8,0x61,0x03,0xE0,0xE8,0x69
+ ,0x40,0x23,0x18,0x43,0xE8,0x61,0x38,0x1C,0x00,0xF0
+ ,0x11,0xF8,0xE8,0x69,0x01,0x23,0x9B,0x02,0x98,0x43
+ ,0xE8,0x61,0x01,0x20,0xB0,0xBD,0x40,0x00,0x00,0x04
+ ,0xB4,0x02,0x00,0x02,0xB8,0x02,0x00,0x02,0xDC,0x05
+ ,0x00,0x00,0xB1,0x02,0x00,0x02,0x90,0xB5,0x07,0x1C
+ ,0x07,0x20,0x40,0x06,0x81,0x69,0x04,0x23,0x19,0x43
+ ,0x81,0x61,0xFA,0xF7,0x2E,0xFA,0x0A,0x20,0xF6,0xF7
+ ,0x95,0xFF,0x17,0x4C,0x02,0x20,0x61,0x68,0x00,0xF0
+ ,0x30,0xF8,0x00,0x20,0x21,0x68,0x00,0xF0,0x2C,0xF8
+ ,0x13,0x48,0xBF,0x00,0x38,0x18,0x40,0x38,0xC1,0x6B
+ ,0x01,0x20,0x00,0xF0,0x24,0xF8,0x05,0x20,0x21,0x69
+ ,0x00,0xF0,0x20,0xF8,0x08,0x20,0xA1,0x68,0x00,0xF0
+ ,0x1C,0xF8,0x07,0x20,0xE1,0x68,0x00,0xF0,0x18,0xF8
+ ,0x0A,0x48,0x38,0x18,0x40,0x38,0xC1,0x6B,0x04,0x20
+ ,0x00,0xF0,0x11,0xF8,0xFF,0x20,0xF5,0x30,0xF6,0xF7
+ ,0x6D,0xFF,0xFA,0xF7,0x65,0xFA,0x0A,0x20,0xF6,0xF7
+ ,0x68,0xFF,0x90,0xBD,0x00,0x00,0xD8,0x02,0x00,0x02
+ ,0xEC,0x02,0x00,0x02,0x24,0x03,0x00,0x02,0x90,0xB4
+ ,0x0B,0x4A,0x13,0x68,0xDF,0x43,0x0A,0x4B,0xDC,0x69
+ ,0x27,0x40,0xDF,0x61,0x07,0x05,0x89,0x00,0x39,0x43
+ ,0x80,0x08,0x08,0x43,0x18,0x62,0x18,0x1C,0x01,0x6A
+ ,0xC9,0x0D,0xFC,0xD3,0x11,0x68,0xC2,0x69,0x11,0x43
+ ,0xC1,0x61,0x90,0xBC,0xF7,0x46,0xB8,0x02,0x00,0x02
+ ,0x40,0x00,0x00,0x04,0x80,0xB5,0x19,0x4F,0x00,0x20
+ ,0x39,0x78,0xF6,0xF7,0xE0,0xFF,0x79,0x78,0x01,0x20
+ ,0xF6,0xF7,0xDC,0xFF,0xB9,0x78,0x02,0x20,0xF6,0xF7
+ ,0xD8,0xFF,0xF9,0x78,0x03,0x20,0xF6,0xF7,0xD4,0xFF
+ ,0x79,0x7C,0x11,0x20,0xF6,0xF7,0xD0,0xFF,0x39,0x7D
+ ,0x14,0x20,0xF6,0xF7,0xCC,0xFF,0x79,0x7D,0x15,0x20
+ ,0xF6,0xF7,0xC8,0xFF,0x39,0x7F,0x1C,0x20,0xF6,0xF7
+ ,0xC4,0xFF,0xB9,0x7C,0x12,0x20,0xF6,0xF7,0xC0,0xFF
+ ,0xF9,0x7C,0x13,0x20,0xF6,0xF7,0xBC,0xFF,0x05,0x48
+ ,0x00,0x78,0x01,0x28,0x03,0xD1,0x79,0x7F,0x1D,0x20
+ ,0xF6,0xF7,0xB4,0xFF,0x80,0xBD,0x00,0x00,0xCC,0x07
+ ,0x00,0x02,0xB0,0x02,0x00,0x02,0x80,0xB5,0x07,0x27
+ ,0x7F,0x06,0xB8,0x69,0x40,0x08,0x40,0x00,0xB8,0x61
+ ,0xB8,0x69,0x01,0x23,0x18,0x43,0xB8,0x61,0x05,0x20
+ ,0xF6,0xF7,0xFE,0xFE,0xB8,0x69,0x40,0x08,0x40,0x00
+ ,0xB8,0x61,0x05,0x20,0xF6,0xF7,0xF7,0xFE,0x80,0xBD
+ ,0xF0,0xB5,0x38,0x4E,0x07,0x1C,0xF0,0x7A,0x03,0x28
+ ,0xFC,0xD0,0xC0,0x20,0xFA,0xF7,0xA3,0xFE,0x35,0x4D
+ ,0x04,0x1C,0xE8,0x69,0xAB,0x01,0x18,0x43,0xE8,0x61
+ ,0x98,0x03,0xC1,0x68,0xC0,0x6B,0x28,0x68,0x0F,0x20
+ ,0x00,0x06,0x01,0x88,0x00,0x89,0x2F,0x48,0xC0,0x69
+ ,0x2F,0x48,0xC1,0x19,0xC8,0x1F,0x09,0x38,0xC2,0x7B
+ ,0x2D,0x48,0xFF,0x2A,0x00,0xD0,0x02,0x75,0x4A,0x7B
+ ,0xFF,0x2A,0x00,0xD0,0x42,0x75,0x40,0x31,0x89,0x78
+ ,0xFF,0x29,0x02,0xD0,0x8A,0x07,0x00,0xD1,0x41,0x74
+ ,0x26,0x48,0x01,0x7D,0x14,0x20,0xF6,0xF7,0x66,0xFF
+ ,0x23,0x48,0x41,0x7D,0x15,0x20,0xF6,0xF7,0x61,0xFF
+ ,0x22,0x48,0x00,0x78,0x01,0x28,0x0A,0xD1,0x0E,0x2F
+ ,0x04,0xD1,0xE8,0x69,0x40,0x23,0x98,0x43,0xE8,0x61
+ ,0x03,0xE0,0xE8,0x69,0x40,0x23,0x18,0x43,0xE8,0x61
+ ,0x1B,0x48,0x07,0x75,0x00,0x7D,0xFF,0xF7,0x09,0xFF
+ ,0x01,0x20,0xFD,0xF7,0x60,0xFA,0xE8,0x69,0x18,0x4B
+ ,0x18,0x40,0xE8,0x61,0x06,0x20,0x70,0x72,0xFA,0x21
+ ,0x07,0x20,0xF8,0xF7,0x4C,0xFC,0x14,0x49,0x08,0x20
+ ,0xF8,0xF7,0x48,0xFC,0x20,0x1C,0xFA,0xF7,0x4D,0xFE
+ ,0x70,0x7C,0x01,0x28,0x05,0xD1,0x00,0x22,0x10,0x21
+ ,0x0F,0x48,0xFA,0xF7,0xE9,0xFC,0xF0,0xBD,0x70,0x7C
+ ,0x02,0x28,0xFB,0xD1,0x00,0x22,0x10,0x21,0x0C,0x48
+ ,0xFA,0xF7,0xE0,0xFC,0xF0,0xBD,0x00,0x00,0x44,0x09
+ ,0x00,0x02,0x40,0x00,0x00,0x04,0x80,0x00,0x00,0x04
+ ,0x58,0x0A,0x00,0x02,0xCC,0x07,0x00,0x02,0xB1,0x02
+ ,0x00,0x02,0x00,0x00,0x00,0x02,0xFF,0xEF,0x00,0x00
+ ,0x88,0x13,0x00,0x00,0xD8,0x06,0x00,0x02,0xF8,0x06
+ ,0x00,0x02,0xB0,0xB5,0x07,0x21,0x49,0x06,0xCA,0x69
+ ,0x52,0x09,0x03,0xD3,0xCA,0x69,0x10,0x23,0x9A,0x43
+ ,0xCA,0x61,0x18,0x4C,0x01,0x28,0x0C,0xD1,0x18,0x4D
+ ,0x6F,0x68,0xF6,0xF7,0x71,0xFE,0x39,0x1A,0x49,0x01
+ ,0x09,0x18,0x69,0x60,0x61,0x6B,0x09,0x1A,0x49,0x01
+ ,0x08,0x18,0x60,0x63,0x12,0x48,0x00,0x21,0x00,0x7D
+ ,0xFF,0xF7,0x63,0xFE,0x11,0x4F,0x11,0x4B,0xF9,0x1D
+ ,0x69,0x31,0x08,0x73,0x01,0x20,0x80,0x06,0xC0,0x68
+ ,0xE0,0x69,0x18,0x40,0xE0,0x61,0x01,0x20,0xFD,0xF7
+ ,0xF9,0xF9,0x01,0x20,0x38,0x72,0x06,0x20,0x78,0x72
+ ,0x07,0x20,0xFF,0x21,0x2D,0x31,0xF8,0xF7,0xE6,0xFB
+ ,0x4B,0x21,0xC9,0x00,0x08,0x20,0xF8,0xF7,0xE1,0xFB
+ ,0xB0,0xBD,0x40,0x00,0x00,0x04,0x80,0x00,0x00,0x04
+ ,0x00,0x00,0x00,0x02,0x44,0x09,0x00,0x02,0xFF,0xEF
+ ,0x00,0x00,0xF0,0xB5,0x24,0x4F,0xF8,0x69,0x3B,0x0C
+ ,0x18,0x43,0xF8,0x61,0xF8,0x69,0x1B,0x23,0x98,0x43
+ ,0xF8,0x61,0xF8,0x69,0x04,0x23,0x98,0x43,0xF8,0x61
+ ,0xF8,0x69,0x9B,0x02,0x18,0x43,0xF8,0x61,0x1C,0x48
+ ,0xF9,0x69,0x00,0x68,0xC0,0x43,0x08,0x40,0x07,0x24
+ ,0x64,0x06,0xF8,0x61,0xA0,0x69,0x01,0x23,0x18,0x43
+ ,0xA0,0x61,0x01,0x20,0xF8,0xF7,0xCF,0xFB,0x08,0x20
+ ,0xF8,0xF7,0xCC,0xFB,0x07,0x20,0xF8,0xF7,0xC9,0xFB
+ ,0x01,0x20,0x80,0x06,0xC1,0x68,0xC0,0x6B,0x11,0x4D
+ ,0x38,0x68,0x0F,0x20,0x00,0x06,0x00,0x88,0x01,0x26
+ ,0x6E,0x72,0xF8,0xF7,0x74,0xFB,0xE8,0x1D,0x69,0x30
+ ,0x0C,0x4D,0x86,0x70,0x6E,0x68,0xF6,0xF7,0x01,0xFE
+ ,0x31,0x1A,0x49,0x09,0x09,0x18,0x69,0x60,0x79,0x6B
+ ,0x09,0x1A,0x49,0x09,0x08,0x18,0x78,0x63,0xE0,0x69
+ ,0x10,0x23,0x18,0x43,0xE0,0x61,0xF0,0xBD,0x00,0x00
+ ,0x40,0x00,0x00,0x04,0xB4,0x02,0x00,0x02,0x44,0x09
+ ,0x00,0x02,0x80,0x00,0x00,0x04,0xF0,0xB4,0x2E,0x4D
+ ,0x01,0x27,0xE9,0x1D,0x19,0x31,0xCC,0x78,0x00,0x20
+ ,0x2C,0x4A,0xFF,0x2C,0x13,0xD0,0x23,0x09,0x11,0xD3
+ ,0x2B,0x7F,0x13,0x70,0x6E,0x7F,0x56,0x70,0xAE,0x7F
+ ,0x96,0x70,0xEB,0x7F,0xD3,0x70,0x0B,0x78,0x53,0x74
+ ,0x4B,0x78,0x13,0x75,0x8B,0x78,0x53,0x75,0x14,0x77
+ ,0x97,0x74,0xD0,0x74,0x0E,0xE0,0x10,0x70,0x60,0x23
+ ,0x53,0x70,0x40,0x23,0x93,0x70,0xD3,0x70,0x50,0x74
+ ,0xFF,0x23,0x13,0x75,0x57,0x23,0x53,0x75,0x48,0x23
+ ,0x13,0x77,0x97,0x74,0xD0,0x74,0x1A,0x4B,0x9C,0x78
+ ,0x1A,0x4B,0x04,0x2C,0x01,0xDA,0x58,0x73,0x05,0xE0
+ ,0x09,0x79,0xFF,0x29,0x01,0xD0,0x59,0x73,0x00,0xE0
+ ,0x58,0x73,0xD1,0x78,0x15,0x4B,0xC0,0x29,0x02,0xD1
+ ,0x1F,0x76,0xD0,0x70,0x00,0xE0,0x18,0x76,0x12,0x48
+ ,0x00,0x7D,0x40,0x19,0xC1,0x1F,0x09,0x39,0xC9,0x7B
+ ,0xFF,0x29,0x00,0xD0,0x11,0x75,0x41,0x7B,0xFF,0x29
+ ,0x00,0xD0,0x51,0x75,0x40,0x30,0x80,0x78,0xFF,0x28
+ ,0x02,0xD0,0x81,0x07,0x00,0xD1,0x50,0x74,0x50,0x78
+ ,0x09,0x49,0x40,0x09,0x80,0x07,0x80,0x0F,0x08,0x70
+ ,0xF0,0xBC,0xF7,0x46,0x58,0x0A,0x00,0x02,0xCC,0x07
+ ,0x00,0x02,0x10,0x01,0x00,0x02,0xDC,0x07,0x00,0x02
+ ,0x44,0x09,0x00,0x02,0x00,0x00,0x00,0x02,0x92,0x01
+ ,0x00,0x02,0x02,0x79,0x41,0x79,0x12,0x02,0x11,0x43
+ ,0xC2,0x78,0x12,0x04,0x11,0x43,0x82,0x78,0x12,0x06
+ ,0x0A,0x43,0x01,0x21,0x89,0x06,0x8A,0x61,0x42,0x78
+ ,0x00,0x78,0x00,0x02,0x10,0x43,0xC8,0x61,0xF7,0x46
+ ,0x00,0xB5,0x0C,0x49,0x0D,0x48,0x41,0x61,0x23,0x21
+ ,0x81,0x61,0x00,0x22,0x01,0x05,0x0A,0x61,0xC2,0x01
+ ,0x42,0x60,0x05,0x22,0xC2,0x60,0x08,0x4A,0x82,0x62
+ ,0xF2,0x22,0x82,0x60,0x32,0x22,0x4A,0x61,0xCA,0x68
+ ,0xC9,0x6B,0x00,0x68,0x00,0x21,0x00,0x20,0x00,0xF0
+ ,0x07,0xF8,0x00,0xBD,0x04,0x90,0x00,0x00,0x40,0x00
+ ,0x00,0x04,0x81,0xFF,0x00,0x00,0x02,0x1C,0x01,0x20
+ ,0x80,0x06,0x82,0x62,0x41,0x62,0xF7,0x46,0x80,0xB5
+ ,0x1D,0x48,0x20,0x23,0x81,0x69,0x1D,0x4F,0x99,0x43
+ ,0x81,0x61,0x1B,0x48,0x81,0x78,0x1C,0x48,0x00,0x29
+ ,0x0F,0xD0,0x01,0x7D,0x04,0x29,0x0C,0xD0,0x01,0x21
+ ,0xC1,0x77,0x03,0x21,0x41,0x77,0xF8,0xF7,0xA5,0xFA
+ ,0x39,0x88,0x89,0x02,0x09,0x1A,0x06,0x20,0xF8,0xF7
+ ,0xC3,0xFA,0x80,0xBD,0xF9,0x1D,0x29,0x31,0x0A,0x79
+ ,0x02,0x2A,0xF9,0xD1,0xC2,0x1D,0x49,0x32,0x92,0x79
+ ,0x05,0x2A,0xF4,0xD1,0x49,0x79,0x01,0x29,0xF1,0xDD
+ ,0xC7,0x1D,0x69,0x37,0xB8,0x78,0x01,0x28,0x04,0xD1
+ ,0x00,0x20,0xFF,0xF7,0x91,0xFE,0x00,0x20,0xB8,0x70
+ ,0xB8,0x78,0x40,0x08,0x40,0x00,0xB8,0x70,0xB8,0x78
+ ,0x08,0x23,0x98,0x43,0xB8,0x70,0x80,0xBD,0x80,0x00
+ ,0x00,0x04,0x04,0x01,0x00,0x02,0x80,0x00,0x00,0x02
+ ,0x44,0x09,0x00,0x02,0x80,0xB5,0xF8,0xF7,0x8F,0xFD
+ ,0x06,0x48,0x01,0x21,0x41,0x60,0x00,0x27,0x47,0x77
+ ,0x01,0x20,0xF6,0xF7,0xF9,0xFC,0x03,0x48,0x07,0x83
+ ,0x87,0x82,0x80,0xBD,0x00,0x00,0x44,0x09,0x00,0x02
+ ,0x20,0x00,0x20,0x0F,0x80,0xB5,0x0F,0x48,0x40,0x23
+ ,0x81,0x69,0x0E,0x4F,0x99,0x43,0x81,0x61,0xF8,0x69
+ ,0x9B,0x01,0x18,0x43,0xF8,0x61,0x14,0x20,0xF6,0xF7
+ ,0xCA,0xFC,0xF8,0x69,0x0A,0x4B,0x0A,0x49,0x18,0x40
+ ,0xF8,0x61,0x01,0x20,0x08,0x72,0x4A,0x7A,0x06,0x2A
+ ,0x00,0xD0,0x48,0x72,0x08,0x73,0x00,0x20,0xC8,0x72
+ ,0x05,0x49,0x08,0x70,0x80,0xBD,0x00,0x00,0x80,0x00
+ ,0x00,0x04,0x40,0x00,0x00,0x04,0xFF,0xEF,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0xE0,0x01,0x00,0x02,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ };
diff --git a/ieee802_11.h b/ieee802_11.h
new file mode 100644
index 0000000..c4121e7
--- /dev/null
+++ b/ieee802_11.h
@@ -0,0 +1,223 @@
+#ifndef _IEEE802_11_H
+#define _IEEE802_11_H
+
+#define IEEE802_11_DATA_LEN 2304
+/* Actually, the standard seems to be inconsistent about what the
+ maximum frame size really is. Section 6.2.1.1.2 says 2304 octets,
+ but the figure in Section 7.1.2 says 2312 octects. */
+#define IEEE802_11_HLEN 30
+#define IEEE802_11_FRAME_LEN (IEEE802_11_DATA_LEN + IEEE802_11_HLEN)
+
+struct ieee802_11_hdr {
+ u16 frame_ctl;
+ u16 duration_id;
+ u8 addr1[ETH_ALEN];
+ u8 addr2[ETH_ALEN];
+ u8 addr3[ETH_ALEN];
+ u16 seq_ctl;
+ u8 addr4[ETH_ALEN];
+} __attribute__ ((packed));
+
+/* defines for information element coding:
+ 1 byte ID, 1 byte length of information field, n bytes information field
+ (see 7.3.2 in [1]) */
+#define IE_ID_SSID 0 /* length 0 - 32 */
+#define IE_ID_SUPPORTED_RATES 1
+#define IE_ID_DS_PARAM_SET 3
+#define IE_ID_CF_PARAM_SET 4
+#define IE_ID_TIM 5
+#define IE_ID_IBSS_PARAM_SET 6
+#define IE_ID_CHALLENGE_TEXT 16
+
+#if defined(__LITTLE_ENDIAN)
+
+/* Frame control field constants */
+#define IEEE802_11_FCTL_VERS 0x0002
+#define IEEE802_11_FCTL_FTYPE 0x000c
+#define IEEE802_11_FCTL_STYPE 0x00f0
+#define IEEE802_11_FCTL_TODS 0x0100
+#define IEEE802_11_FCTL_FROMDS 0x0200
+#define IEEE802_11_FCTL_MOREFRAGS 0x0400
+#define IEEE802_11_FCTL_RETRY 0x0800
+#define IEEE802_11_FCTL_PM 0x1000
+#define IEEE802_11_FCTL_MOREDATA 0x2000
+#define IEEE802_11_FCTL_WEP 0x4000
+#define IEEE802_11_FCTL_ORDER 0x8000
+
+#define IEEE802_11_FTYPE_MGMT 0x0000
+#define IEEE802_11_FTYPE_CTL 0x0004
+#define IEEE802_11_FTYPE_DATA 0x0008
+
+/* management */
+#define IEEE802_11_STYPE_ASSOC_REQ 0x0000
+#define IEEE802_11_STYPE_ASSOC_RESP 0x0010
+#define IEEE802_11_STYPE_REASSOC_REQ 0x0020
+#define IEEE802_11_STYPE_REASSOC_RESP 0x0030
+#define IEEE802_11_STYPE_PROBE_REQ 0x0040
+#define IEEE802_11_STYPE_PROBE_RESP 0x0050
+#define IEEE802_11_STYPE_BEACON 0x0080
+#define IEEE802_11_STYPE_ATIM 0x0090
+#define IEEE802_11_STYPE_DISASSOC 0x00A0
+#define IEEE802_11_STYPE_AUTH 0x00B0
+#define IEEE802_11_STYPE_DEAUTH 0x00C0
+
+/* control */
+#define IEEE802_11_STYPE_PSPOLL 0x00A0
+#define IEEE802_11_STYPE_RTS 0x00B0
+#define IEEE802_11_STYPE_CTS 0x00C0
+#define IEEE802_11_STYPE_ACK 0x00D0
+#define IEEE802_11_STYPE_CFEND 0x00E0
+#define IEEE802_11_STYPE_CFENDACK 0x00F0
+
+/* data */
+#define IEEE802_11_STYPE_DATA 0x0000
+#define IEEE802_11_STYPE_DATA_CFACK 0x0010
+#define IEEE802_11_STYPE_DATA_CFPOLL 0x0020
+#define IEEE802_11_STYPE_DATA_CFACKPOLL 0x0030
+#define IEEE802_11_STYPE_NULLFUNC 0x0040
+#define IEEE802_11_STYPE_CFACK 0x0050
+#define IEEE802_11_STYPE_CFPOLL 0x0060
+#define IEEE802_11_STYPE_CFACKPOLL 0x0070
+
+#define IEEE802_11_SCTL_FRAG 0x000F
+#define IEEE802_11_SCTL_SEQ 0xFFF0
+
+/* capability field in beacon, (re)assocReq */
+#define IEEE802_11_CAPA_ESS 0x0001
+#define IEEE802_11_CAPA_IBSS 0x0002
+#define IEEE802_11_CAPA_CF_POLLABLE 0x0004
+#define IEEE802_11_CAPA_POLL_REQ 0x0008
+#define IEEE802_11_CAPA_PRIVACY 0x0010
+#define IEEE802_11_CAPA_SHORT_PREAMBLE 0x0020
+
+/* auth frame: algorithm type */
+#define IEEE802_11_AUTH_ALG_OPEN_SYSTEM 0x0000
+#define IEEE802_11_AUTH_ALG_SHARED_SECRET 0x0001
+
+/* disassoc/deauth frame: reason codes (see 802.11, ch. 7.3.1.7, table 18) */
+#define IEEE802_11_REASON_UNSPECIFIED 0x0001
+#define IEEE802_11_REASON_PREV_AUTH_INVALID 0x0002
+#define IEEE802_11_REASON_DEAUTH_LEAVING 0x0003
+#define IEEE802_11_REASON_DISASS_INACTIVITY 0x0004
+#define IEEE802_11_REASON_DISASS_TOO_MANY_STA 0x0005
+#define IEEE802_11_REASON_CL2_FROM_NONAUTH 0x0006
+#define IEEE802_11_REASON_CL3_FROM_NONASSOC 0x0007
+#define IEEE802_11_REASON_DISASS_LEAVING 0x0008
+#define IEEE802_11_REASON_NOT_AUTH 0x0009
+
+/* status in some response frames (802.11, ch. 7.3.1.9, table 19) */
+#define IEEE802_11_STATUS_SUCCESS 0x0000
+#define IEEE802_11_STATUS_UNSPECIFIED 0x0001
+#define IEEE802_11_STATUS_UNSUPP_CAPABILITIES 0x000a
+#define IEEE802_11_STATUS_NO_PREV_ASSOC 0x000b
+#define IEEE802_11_STATUS_ASSOC_FAILED 0x000c
+#define IEEE802_11_STATUS_UNSUPP_AUTH_ALG 0x000d
+#define IEEE802_11_STATUS_AUTH_INV_TRANS_SEQ 0x000e
+#define IEEE802_11_STATUS_AUTH_CHALLENGE_FAIL 0x000f
+#define IEEE802_11_STATUS_AUTH_TIMEOUT 0x0010
+#define IEEE802_11_STATUS_ASSOC_TOO_MANY_STA 0x0011
+#define IEEE802_11_STATUS_BASIC_RATE_SET 0x0012
+
+#else /* defined(__LITTLE_ENDIAN) */
+
+/* Frame control field constants */
+#define IEEE802_11_FCTL_VERS 0x0200
+#define IEEE802_11_FCTL_FTYPE 0x0c00
+#define IEEE802_11_FCTL_STYPE 0xf000
+#define IEEE802_11_FCTL_TODS 0x0001
+#define IEEE802_11_FCTL_FROMDS 0x0002
+#define IEEE802_11_FCTL_MOREFRAGS 0x0004
+#define IEEE802_11_FCTL_RETRY 0x0008
+#define IEEE802_11_FCTL_PM 0x0010
+#define IEEE802_11_FCTL_MOREDATA 0x0020
+#define IEEE802_11_FCTL_WEP 0x0040
+#define IEEE802_11_FCTL_ORDER 0x0080
+
+#define IEEE802_11_FTYPE_MGMT 0x0000
+#define IEEE802_11_FTYPE_CTL 0x0400
+#define IEEE802_11_FTYPE_DATA 0x0800
+
+/* management */
+#define IEEE802_11_STYPE_ASSOC_REQ 0x0000
+#define IEEE802_11_STYPE_ASSOC_RESP 0x1000
+#define IEEE802_11_STYPE_REASSOC_REQ 0x2000
+#define IEEE802_11_STYPE_REASSOC_RESP 0x3000
+#define IEEE802_11_STYPE_PROBE_REQ 0x4000
+#define IEEE802_11_STYPE_PROBE_RESP 0x5000
+#define IEEE802_11_STYPE_BEACON 0x8000
+#define IEEE802_11_STYPE_ATIM 0x9000
+#define IEEE802_11_STYPE_DISASSOC 0xA000
+#define IEEE802_11_STYPE_AUTH 0xB000
+#define IEEE802_11_STYPE_DEAUTH 0xC000
+
+/* control */
+#define IEEE802_11_STYPE_PSPOLL 0xA000
+#define IEEE802_11_STYPE_RTS 0xB000
+#define IEEE802_11_STYPE_CTS 0xC000
+#define IEEE802_11_STYPE_ACK 0xD000
+#define IEEE802_11_STYPE_CFEND 0xE000
+#define IEEE802_11_STYPE_CFENDACK 0xF000
+
+/* data */
+#define IEEE802_11_STYPE_DATA 0x0000
+#define IEEE802_11_STYPE_DATA_CFACK 0x1000
+#define IEEE802_11_STYPE_DATA_CFPOLL 0x2000
+#define IEEE802_11_STYPE_DATA_CFACKPOLL 0x3000
+#define IEEE802_11_STYPE_NULLFUNC 0x4000
+#define IEEE802_11_STYPE_CFACK 0x5000
+#define IEEE802_11_STYPE_CFPOLL 0x6000
+#define IEEE802_11_STYPE_CFACKPOLL 0x7000
+
+#define IEEE802_11_SCTL_FRAG 0x0F00
+#define IEEE802_11_SCTL_SEQ 0xF0FF
+
+/* capability field in beacon, (re)assocReq */
+#define IEEE802_11_CAPA_ESS 0x0100
+#define IEEE802_11_CAPA_IBSS 0x0200
+#define IEEE802_11_CAPA_CF_POLLABLE 0x0400
+#define IEEE802_11_CAPA_POLL_REQ 0x0800
+#define IEEE802_11_CAPA_PRIVACY 0x1000
+#define IEEE802_11_CAPA_SHORT_PREAMBLE 0x2000
+
+/* auth frame: algorithm type */
+#define IEEE802_11_AUTH_ALG_OPEN_SYSTEM 0x0000
+#define IEEE802_11_AUTH_ALG_SHARED_SECRET 0x0100
+
+/* disassoc/deauth frame: reason codes (see 802.11, ch. 7.3.1.7, table 18) */
+#define IEEE802_11_REASON_UNSPECIFIED 0x0100
+#define IEEE802_11_REASON_PREV_AUTH_INVALID 0x0200
+#define IEEE802_11_REASON_DEAUTH_LEAVING 0x0300
+#define IEEE802_11_REASON_DISASS_INACTIVITY 0x0400
+#define IEEE802_11_REASON_DISASS_TOO_MANY_STA 0x0500
+#define IEEE802_11_REASON_CL2_FROM_NONAUTH 0x0600
+#define IEEE802_11_REASON_CL3_FROM_NONASSOC 0x0700
+#define IEEE802_11_REASON_DISASS_LEAVING 0x0800
+#define IEEE802_11_REASON_NOT_AUTH 0x0900
+
+/* status in some response frames (802.11, ch. 7.3.1.9, table 19) */
+#define IEEE802_11_STATUS_SUCCESS 0x0000
+#define IEEE802_11_STATUS_UNSPECIFIED 0x0100
+#define IEEE802_11_STATUS_UNSUPP_CAPABILITIES 0x0a00
+#define IEEE802_11_STATUS_NO_PREV_ASSOC 0x0b00
+#define IEEE802_11_STATUS_ASSOC_FAILED 0x0c00
+#define IEEE802_11_STATUS_UNSUPP_AUTH_ALG 0x0d00
+#define IEEE802_11_STATUS_AUTH_INV_TRANS_SEQ 0x0e00
+#define IEEE802_11_STATUS_AUTH_CHALLENGE_FAIL 0x0f00
+#define IEEE802_11_STATUS_AUTH_TIMEOUT 0x1000
+#define IEEE802_11_STATUS_ASSOC_TOO_MANY_STA 0x1100
+#define IEEE802_11_STATUS_BASIC_RATE_SET 0x1200
+
+#endif
+
+#endif /* _IEEE802_11_H */
+
+
+
+
+
+
+
+
+
+
+
diff --git a/internalr.h b/internalr.h
new file mode 100644
index 0000000..fb305ec
--- /dev/null
+++ b/internalr.h
@@ -0,0 +1,2170 @@
+/**************************************************************************/
+/* */
+/* Copyright (c) 1999-2000 by Atmel Corporation */
+/* */
+/* This software is copyrighted by and is the sole property of Atmel */
+/* Corporation. All rights, title, ownership, or other interests */
+/* in the software remain the property of Atmel Corporation. This */
+/* software may only be used in accordance with the corresponding */
+/* license agreement. Any un-authorized use, duplication, transmission, */
+/* distribution, or disclosure of this software is expressly forbidden. */
+/* */
+/* This Copyright notice may not be removed or modified without prior */
+/* written consent of Atmel Corporation. */
+/* */
+/* Atmel Corporation, Inc. reserves the right to modify this software */
+/* without notice. */
+/* */
+/* Atmel Corporation. */
+/* 2325 Orchard Parkway literature@atmel.com */
+/* San Jose, CA 95131 http://www.atmel.com */
+/* */
+/**************************************************************************/
+/**************************************************************************/
+/* */
+/* Automatically generated FW file for AT76C502A */
+/* */
+/**************************************************************************/
+
+
+UCHAR InternalRFMD[] = {0x7C,0xF1,0x9F,0xE5,0x7C,0xF1,0x9F,0xE5,0x7C,0xF1
+ ,0x9F,0xE5,0x7C,0xF1,0x9F,0xE5,0x7C,0xF1,0x9F,0xE5
+ ,0x7C,0xF1,0x9F,0xE5,0x7C,0xF1,0x9F,0xE5,0x7C,0xF1
+ ,0x9F,0xE5,0xD3,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1
+ ,0x0E,0x04,0xA0,0xE3,0x00,0x10,0xA0,0xE3,0x81,0x11
+ ,0xA0,0xE1,0x00,0x10,0x81,0xE3,0x00,0x10,0x80,0xE5
+ ,0x0F,0x04,0xA0,0xE3,0x00,0x10,0xA0,0xE3,0x04,0x10
+ ,0x80,0xE5,0x0C,0x10,0x80,0xE5,0x00,0x10,0x90,0xE5
+ ,0x08,0x10,0x90,0xE5,0x48,0xD1,0x9F,0xE5,0x46,0x13
+ ,0x00,0xEB,0x44,0x11,0x9F,0xE5,0xD0,0x20,0x9F,0xE5
+ ,0xD1,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1,0x02,0x10
+ ,0x81,0xE0,0x03,0x10,0xC1,0xE3,0x04,0x10,0x41,0xE2
+ ,0x01,0xD0,0xA0,0xE1,0x00,0xA0,0xA0,0xE3,0x00,0xB0
+ ,0xA0,0xE3,0xB0,0x20,0x9F,0xE5,0xD2,0x00,0xA0,0xE3
+ ,0x00,0xF0,0x21,0xE1,0x02,0x10,0x81,0xE0,0x03,0x10
+ ,0xC1,0xE3,0x04,0x10,0x41,0xE2,0x01,0xD0,0xA0,0xE1
+ ,0xD3,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1,0x84,0x30
+ ,0x9F,0xE5,0x00,0x10,0x83,0xE5,0x01,0xD0,0xA0,0xE1
+ ,0x74,0x00,0x9F,0xE5,0x01,0x00,0x80,0xE3,0x0F,0xE0
+ ,0xA0,0xE1,0x10,0xFF,0x2F,0xE1,0x00,0xA0,0x00,0x47
+ ,0x64,0x10,0x9F,0xE5,0x00,0x00,0x91,0xE5,0x04,0x00
+ ,0x80,0xE2,0x6C,0x10,0x9F,0xE5,0x6C,0x30,0x9F,0xE5
+ ,0x5C,0x20,0x9F,0xE5,0x00,0x00,0x81,0xE5,0x00,0x20
+ ,0x83,0xE5,0x02,0x00,0x80,0xE0,0x5C,0x10,0x9F,0xE5
+ ,0x00,0x20,0xA0,0xE3,0x00,0x20,0x81,0xE5,0x44,0x20
+ ,0x9F,0xE5,0x00,0x00,0x82,0xE5,0x1E,0xFF,0x2F,0xE1
+ ,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF
+ ,0xFF,0xEA,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF,0xFF,0xEA
+ ,0x65,0x0E,0x00,0xEA,0x02,0xF0,0x92,0xF8,0x22,0x48
+ ,0x87,0x46,0x7E,0x0E,0x00,0xEA,0x01,0xF0,0x9E,0xFE
+ ,0x20,0x48,0x87,0x46,0xB5,0x01,0x00,0x00,0xB4,0x03
+ ,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x00
+ ,0x00,0x01,0x00,0x00,0x38,0x04,0x00,0x02,0x58,0x04
+ ,0x00,0x02,0x5C,0x04,0x00,0x02,0x60,0x04,0x00,0x02
+ ,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF
+ ,0xFF,0xEA,0xFE,0xFF,0xFF,0xEA,0x00,0x00,0xA0,0xE3
+ ,0x0E,0xF0,0xA0,0xE1,0xFE,0xFF,0xFF,0xEA,0xFE,0xFF
+ ,0xFF,0xEA,0x00,0x00,0xA0,0xE3,0x0E,0xF0,0xA0,0xE1
+ ,0x00,0x00,0xA0,0xE3,0x0E,0xF0,0xA0,0xE1,0x20,0x00
+ ,0x00,0x00,0x04,0x01,0x00,0x00,0x08,0x01,0x00,0x00
+ ,0x0C,0x01,0x00,0x00,0x10,0x01,0x00,0x00,0x14,0x01
+ ,0x00,0x00,0x18,0x01,0x00,0x00,0x24,0x01,0x00,0x00
+ ,0x00,0x60,0x00,0x01,0xE0,0x59,0x00,0x01,0xA5,0x3B
+ ,0x00,0x00,0x95,0x3C,0x00,0x00,0x00,0xB5,0x03,0xF0
+ ,0x4F,0xFC,0x00,0x20,0x00,0xBD,0x80,0xB5,0x86,0xB0
+ ,0x07,0x1C,0x00,0x21,0x04,0x91,0xFF,0x21,0x01,0x22
+ ,0x91,0x31,0x01,0x20,0x03,0x90,0x01,0x91,0x05,0x92
+ ,0x02,0x92,0x17,0x4A,0x19,0xA1,0x17,0x48,0x01,0x23
+ ,0x00,0x97,0x03,0xF0,0x25,0xFE,0x00,0x21,0x04,0x91
+ ,0xFF,0x21,0x91,0x31,0x01,0x22,0x05,0x92,0xFB,0x1D
+ ,0xFF,0x33,0x03,0x22,0x03,0x20,0x8A,0x33,0x00,0x93
+ ,0x03,0x90,0x02,0x92,0x01,0x91,0x13,0xA1,0x11,0x4A
+ ,0x11,0x48,0x02,0x23,0x03,0xF0,0x10,0xFE,0x13,0x48
+ ,0x14,0xA1,0x03,0xF0,0x82,0xFE,0x16,0x48,0x17,0xA1
+ ,0x03,0xF0,0x7E,0xFE,0x1A,0x48,0x1B,0xA1,0x03,0xF0
+ ,0x7A,0xFE,0x1E,0x48,0x1F,0xA1,0x03,0xF0,0x76,0xFE
+ ,0x03,0xF0,0x5A,0xFA,0x06,0xB0,0x80,0xBD,0x05,0x13
+ ,0x00,0x00,0xB8,0x05,0x00,0x02,0x54,0x78,0x20,0x74
+ ,0x68,0x72,0x65,0x61,0x64,0x00,0x00,0x00,0x91,0x25
+ ,0x00,0x00,0x48,0x06,0x00,0x02,0x4D,0x67,0x6D,0x20
+ ,0x74,0x68,0x72,0x65,0x61,0x64,0x00,0x00,0xD8,0x06
+ ,0x00,0x02,0x54,0x78,0x20,0x73,0x74,0x61,0x74,0x75
+ ,0x73,0x20,0x66,0x6C,0x61,0x67,0x73,0x00,0xF8,0x06
+ ,0x00,0x02,0x4D,0x67,0x6D,0x20,0x73,0x74,0x61,0x74
+ ,0x75,0x73,0x20,0x66,0x6C,0x61,0x67,0x73,0x00,0x00
+ ,0x00,0x00,0x18,0x07,0x00,0x02,0x54,0x58,0x20,0x47
+ ,0x4F,0x20,0x73,0x74,0x61,0x74,0x75,0x73,0x20,0x66
+ ,0x6C,0x61,0x67,0x73,0x00,0x00,0x38,0x07,0x00,0x02
+ ,0x50,0x73,0x50,0x6F,0x6C,0x6C,0x20,0x73,0x74,0x61
+ ,0x74,0x75,0x73,0x20,0x66,0x6C,0x61,0x67,0x73,0x00
+ ,0xC3,0x00,0x18,0x18,0x80,0x00,0x80,0x08,0x01,0xD0
+ ,0x01,0x38,0xFD,0xD1,0xF7,0x46,0x03,0x49,0x0F,0x20
+ ,0x00,0x06,0x81,0x80,0x02,0x49,0x81,0x81,0xF7,0x46
+ ,0x00,0x00,0xE8,0xE8,0x00,0x00,0x13,0x13,0x00,0x00
+ ,0x01,0x20,0x80,0x06,0x40,0x6A,0xF7,0x46,0x01,0x1C
+ ,0x06,0x48,0x04,0xD0,0x41,0x68,0xC3,0x01,0x19,0x43
+ ,0x41,0x60,0xF7,0x46,0x41,0x68,0x01,0x23,0x5B,0x03
+ ,0x99,0x43,0x41,0x60,0xF7,0x46,0x40,0x00,0x00,0x04
+ ,0x80,0xB5,0x13,0x49,0x15,0x4F,0x08,0x78,0x42,0x01
+ ,0x12,0x48,0x42,0x70,0x12,0x4A,0x52,0x7A,0x00,0x2A
+ ,0x0B,0xD0,0x09,0x78,0x00,0x29,0x08,0xDD,0x41,0x78
+ ,0x10,0x23,0x19,0x43,0x41,0x70,0x48,0x21,0x79,0x81
+ ,0x18,0x21,0x39,0x81,0x03,0xE0,0x90,0x21,0x79,0x81
+ ,0x30,0x21,0x39,0x81,0x41,0x78,0x01,0x20,0x00,0xF0
+ ,0x5B,0xF8,0x78,0x89,0x39,0x89,0x40,0x18,0x06,0x49
+ ,0x08,0x80,0x01,0xF0,0xA8,0xFC,0x80,0xBD,0x00,0x00
+ ,0x93,0x01,0x00,0x02,0xCC,0x07,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0x00,0x00,0x00,0x02,0xAC,0x01,0x00,0x02
+ ,0x01,0x1C,0x06,0x48,0x04,0xD0,0x41,0x7C,0x01,0x23
+ ,0x19,0x43,0x41,0x74,0xF7,0x46,0x41,0x7C,0xFE,0x23
+ ,0x19,0x40,0x41,0x74,0xF7,0x46,0x00,0x00,0xCC,0x07
+ ,0x00,0x02,0xF0,0xB4,0x07,0x24,0x64,0x06,0xA2,0x69
+ ,0x04,0x23,0x9A,0x43,0xA2,0x61,0xF3,0x22,0x12,0x05
+ ,0x93,0x68,0x40,0x23,0xD3,0x60,0x17,0x69,0xBB,0x08
+ ,0xFC,0xD3,0x13,0x69,0x5B,0x08,0xFC,0xD3,0x93,0x68
+ ,0x80,0x23,0x03,0x43,0xD3,0x60,0x17,0x69,0xBB,0x08
+ ,0xFC,0xD3,0x13,0x69,0x5B,0x08,0xFC,0xD3,0x17,0x1C
+ ,0x92,0x68,0x00,0x22,0x00,0x29,0x0D,0xD9,0x0A,0x4D
+ ,0x83,0x18,0xEB,0x5C,0xFB,0x60,0x3E,0x69,0xB3,0x08
+ ,0xFC,0xD3,0x3B,0x69,0x5B,0x08,0xFC,0xD3,0x01,0x32
+ ,0x8A,0x42,0xBB,0x68,0xF2,0xD3,0xA0,0x69,0x04,0x23
+ ,0x18,0x43,0xA0,0x61,0xF0,0xBC,0xF7,0x46,0x00,0x00
+ ,0xCC,0x07,0x00,0x02,0x90,0xB4,0x07,0x27,0x7F,0x06
+ ,0xBA,0x69,0x04,0x23,0x9A,0x43,0xBA,0x61,0xF3,0x22
+ ,0x12,0x05,0x93,0x68,0x40,0x23,0xD3,0x60,0x14,0x69
+ ,0xA3,0x08,0xFC,0xD3,0x13,0x69,0x5B,0x08,0xFC,0xD3
+ ,0x93,0x68,0xD0,0x60,0x10,0x69,0x80,0x08,0xFC,0xD3
+ ,0x10,0x1C,0x02,0x69,0x52,0x08,0xFC,0xD3,0x82,0x68
+ ,0xC1,0x60,0x01,0x69,0x89,0x08,0xFC,0xD3,0x01,0x69
+ ,0x49,0x08,0xFC,0xD3,0x80,0x68,0x04,0x23,0xB8,0x69
+ ,0x18,0x43,0xB8,0x61,0x90,0xBC,0xF7,0x46,0x80,0xB4
+ ,0x07,0x22,0x52,0x06,0x91,0x69,0x04,0x23,0x99,0x43
+ ,0x91,0x61,0xF3,0x21,0x09,0x05,0x8B,0x68,0x40,0x23
+ ,0xCB,0x60,0x0F,0x69,0xBB,0x08,0xFC,0xD3,0x0B,0x69
+ ,0x5B,0x08,0xFC,0xD3,0x8B,0x68,0xC8,0x60,0x08,0x69
+ ,0x80,0x08,0xFC,0xD3,0x08,0x69,0x40,0x08,0xFC,0xD3
+ ,0x97,0x69,0x04,0x23,0x3B,0x43,0x88,0x68,0x93,0x61
+ ,0x97,0x69,0x04,0x23,0x9F,0x43,0x97,0x61,0x41,0x20
+ ,0xC8,0x60,0x08,0x69,0x80,0x08,0xFC,0xD3,0x08,0x1C
+ ,0x01,0x69,0x49,0x08,0xFC,0xD3,0x81,0x68,0xFF,0x21
+ ,0xC1,0x60,0x01,0x69,0x49,0x08,0xFC,0xD3,0x91,0x69
+ ,0x04,0x23,0x19,0x43,0x80,0x68,0x91,0x61,0x80,0xBC
+ ,0xF7,0x46,0x80,0xB5,0x0B,0x4F,0xF8,0x69,0xBB,0x01
+ ,0x18,0x43,0xF8,0x61,0x00,0x20,0xFF,0xF7,0x0A,0xFF
+ ,0x08,0x48,0xF9,0x69,0x00,0x68,0xC0,0x43,0x08,0x40
+ ,0xF8,0x61,0x07,0x20,0x40,0x06,0x81,0x69,0x01,0x23
+ ,0x19,0x43,0x81,0x61,0x03,0x49,0x01,0x20,0x08,0x70
+ ,0x80,0xBD,0x40,0x00,0x00,0x04,0xB4,0x02,0x00,0x02
+ ,0xB3,0x02,0x00,0x02,0xC1,0x0A,0x01,0xD3,0x00,0x20
+ ,0xF7,0x46,0xFF,0x22,0x01,0x32,0x02,0x40,0x01,0x21
+ ,0x00,0x2A,0x01,0xD0,0x08,0x1C,0xF7,0x46,0x80,0x0A
+ ,0x01,0xD3,0x08,0x1C,0xF7,0x46,0x02,0x20,0xF7,0x46
+ ,0xF0,0xB5,0x0F,0x1C,0x19,0x49,0x04,0x1C,0x19,0x4E
+ ,0x1A,0x48,0x31,0x60,0x05,0x6C,0x00,0x2D,0x16,0xD0
+ ,0x06,0x22,0x20,0x1C,0x31,0x68,0x04,0xF0,0x37,0xFA
+ ,0x00,0x28,0x08,0xD1,0x30,0x68,0xC1,0x88,0xB9,0x42
+ ,0x01,0xD1,0x01,0x20,0xF0,0xBD,0xC7,0x80,0x00,0x20
+ ,0xF0,0xBD,0x30,0x68,0x08,0x30,0x30,0x60,0x28,0x1C
+ ,0x01,0x3D,0x00,0x28,0xE8,0xD1,0x0C,0x48,0x01,0x6C
+ ,0x01,0x31,0x01,0x64,0x01,0x6C,0x07,0x29,0x03,0xD9
+ ,0x06,0x49,0x31,0x60,0x08,0x21,0x01,0x64,0x06,0x22
+ ,0x21,0x1C,0x30,0x68,0x04,0xF0,0x33,0xFA,0x30,0x68
+ ,0xC7,0x80,0x00,0x20,0xF0,0xBD,0x00,0x00,0x74,0x07
+ ,0x00,0x02,0x40,0x01,0x00,0x02,0x44,0x09,0x00,0x02
+ ,0x05,0x49,0x0A,0x68,0x12,0x01,0x02,0x70,0x0A,0x68
+ ,0x12,0x01,0x12,0x0A,0x42,0x70,0x08,0x68,0x01,0x30
+ ,0x08,0x60,0xF7,0x46,0x44,0x01,0x00,0x02,0x00,0x2A
+ ,0x0C,0xD1,0x08,0x4A,0x92,0x7A,0x8A,0x42,0x00,0xD8
+ ,0x11,0x1C,0x07,0x4A,0x49,0x00,0x51,0x5A,0x06,0x4A
+ ,0xD2,0x88,0x89,0x18,0xC9,0x18,0x00,0xE0,0x00,0x21
+ ,0x01,0x70,0x09,0x0A,0x41,0x70,0xF7,0x46,0x04,0x01
+ ,0x00,0x02,0xB0,0x01,0x00,0x02,0x00,0x00,0x00,0x02
+ ,0xF0,0xB5,0x49,0x48,0x00,0x68,0xFF,0xF7,0x85,0xFF
+ ,0x04,0x06,0x47,0x48,0x24,0x0E,0x00,0x68,0x47,0x68
+ ,0x38,0x78,0x06,0x07,0x36,0x0F,0x02,0x2C,0x73,0xD0
+ ,0x44,0x4D,0x28,0x79,0x02,0x28,0x07,0xD1,0xF8,0x1D
+ ,0x09,0x30,0x06,0x22,0x41,0x49,0x04,0xF0,0xC9,0xF9
+ ,0x00,0x28,0x67,0xD0,0x30,0x06,0x00,0x0E,0x08,0x28
+ ,0x64,0xD1,0x3E,0x48,0x80,0x79,0x05,0x28,0x61,0xD1
+ ,0x28,0x79,0x3C,0x4E,0x02,0x28,0x0C,0xD1,0xF8,0x1D
+ ,0x03,0x30,0x06,0x22,0x31,0x1C,0x04,0xF0,0xB5,0xF9
+ ,0x00,0x28,0x55,0xD1,0x78,0x78,0x81,0x08,0x5A,0xD3
+ ,0x40,0x08,0x58,0xD2,0x28,0x79,0x01,0x28,0x0C,0xD1
+ ,0xF8,0x1D,0x09,0x30,0x06,0x22,0x31,0x1C,0x04,0xF0
+ ,0xA5,0xF9,0x00,0x28,0x45,0xD1,0x78,0x78,0x81,0x08
+ ,0x4A,0xD2,0x40,0x08,0x48,0xD2,0x38,0x78,0x08,0x28
+ ,0x30,0xD1,0x2C,0x48,0x01,0x78,0x00,0x29,0x11,0xD0
+ ,0xC0,0x78,0x00,0x28,0x11,0xD0,0x78,0x78,0xC0,0x09
+ ,0x0E,0xD2,0xB9,0x7F,0xF8,0x1D,0x09,0x30,0x88,0x29
+ ,0x02,0xD1,0xC0,0x7B,0x8E,0x28,0x06,0xD0,0xB8,0x7D
+ ,0x00,0x07,0x26,0xD0,0x02,0xE0,0x78,0x78,0xC0,0x09
+ ,0x2C,0xD2,0x28,0x79,0x02,0x28,0x14,0xD1,0x78,0x78
+ ,0x04,0x21,0x01,0x40,0x20,0x23,0x18,0x40,0x22,0x1C
+ ,0x03,0xF0,0x09,0xF9,0x00,0x2C,0x0A,0xD1,0x1A,0x48
+ ,0x41,0x68,0x04,0x29,0x06,0xD1,0x01,0x26,0x46,0x60
+ ,0x01,0x20,0x01,0xF0,0xB8,0xFB,0x16,0x48,0x06,0x70
+ ,0x68,0x79,0x03,0x28,0x0D,0xD1,0x19,0x21,0xC9,0x02
+ ,0x02,0x20,0x01,0xF0,0x94,0xFB,0x12,0x48,0x81,0x78
+ ,0x02,0xE0,0x08,0xE0,0x08,0xE0,0x06,0xE0,0x08,0x23
+ ,0x99,0x43,0x81,0x70,0x39,0x78,0x20,0x1C,0x00,0xF0
+ ,0x21,0xFD,0xF0,0xBD,0x00,0x28,0xFC,0xD1,0x20,0x1C
+ ,0x00,0xF0,0xED,0xFB,0xF0,0xBD,0xE8,0x01,0x00,0x02
+ ,0x48,0x01,0x00,0x02,0xB0,0x00,0x00,0x02,0x5C,0x00
+ ,0x00,0x02,0x94,0x09,0x00,0x02,0x8E,0x00,0x00,0x02
+ ,0x18,0x00,0x00,0x02,0x44,0x09,0x00,0x02,0xDC,0x01
+ ,0x00,0x02,0xB4,0x09,0x00,0x02,0x08,0xB5,0x00,0x21
+ ,0x00,0x91,0x00,0x28,0x0C,0xD1,0x09,0x48,0x00,0x68
+ ,0x40,0x68,0x81,0x7D,0xC2,0x7D,0x12,0x02,0x11,0x43
+ ,0x09,0x04,0x09,0x0C,0x0A,0x30,0xFF,0xF7,0xE3,0xFE
+ ,0x00,0x90,0x00,0x98,0x01,0x28,0x01,0xD0,0x00,0xF0
+ ,0x03,0xF8,0x08,0xBD,0x48,0x01,0x00,0x02,0x80,0xB5
+ ,0x05,0x48,0x00,0x78,0x80,0x09,0x04,0xD3,0x04,0x4F
+ ,0x38,0x68,0x02,0xF0,0x9F,0xF8,0x38,0x60,0x80,0xBD
+ ,0x00,0x00,0x94,0x01,0x00,0x02,0x48,0x01,0x00,0x02
+ ,0xF0,0xB5,0x82,0xB0,0x00,0x25,0x7D,0x26,0x36,0x01
+ ,0x01,0x21,0x89,0x06,0x88,0x68,0x00,0x0B,0xFC,0x24
+ ,0x04,0x40,0xFA,0x48,0xC7,0x6A,0x00,0x2F,0x0F,0xD1
+ ,0x00,0x20,0xFF,0xF7,0x9A,0xFD,0xF6,0x48,0xC1,0x69
+ ,0x83,0x01,0x19,0x43,0xC1,0x61,0xC1,0x69,0xF4,0x4B
+ ,0x19,0x40,0xC1,0x61,0x01,0x05,0xC8,0x68,0x02,0xB0
+ ,0xF0,0xBD,0xF2,0x49,0xA0,0x08,0x08,0x5C,0x00,0x28
+ ,0x06,0xD0,0x00,0x20,0xFF,0xF7,0x85,0xFD,0x01,0x21
+ ,0x89,0x06,0xC8,0x68,0xF1,0xE7,0xED,0x49,0x04,0x20
+ ,0x20,0x40,0x01,0x91,0x61,0xD0,0x04,0x20,0xFF,0xF7
+ ,0x2D,0xFE,0xEA,0x49,0x08,0x71,0xA0,0x09,0x01,0xD3
+ ,0x14,0x21,0x00,0xE0,0x0E,0x21,0xE7,0x48,0x02,0x22
+ ,0x01,0xF0,0x9E,0xFE,0x00,0x28,0x03,0xD1,0x01,0x21
+ ,0x89,0x06,0xC8,0x68,0xD8,0xE7,0x01,0x21,0x89,0x06
+ ,0xC8,0x68,0x28,0x43,0x01,0xE0,0xCA,0x68,0x10,0x43
+ ,0x42,0x09,0x03,0xD2,0x32,0x1C,0x01,0x3E,0x00,0x2A
+ ,0xF7,0xD1,0x10,0x23,0x98,0x43,0x05,0x1C,0x00,0x2E
+ ,0x01,0xDC,0x28,0x1C,0xC4,0xE7,0xD7,0x49,0x08,0x79
+ ,0x0A,0x28,0x09,0xD0,0x14,0x28,0x0B,0xD0,0x37,0x28
+ ,0x0D,0xD0,0x6E,0x28,0x0F,0xD1,0xD4,0x4A,0x03,0x20
+ ,0x50,0x75,0x14,0xE0,0xD2,0x4A,0x00,0x20,0x50,0x75
+ ,0x10,0xE0,0xD0,0x4A,0x01,0x21,0x51,0x75,0x0C,0xE0
+ ,0xCE,0x4A,0x02,0x20,0x50,0x75,0x08,0xE0,0x14,0x2F
+ ,0x03,0xD2,0xCB,0x4A,0x03,0x20,0x50,0x75,0x02,0xE0
+ ,0xC9,0x4A,0x02,0x20,0x50,0x75,0xA8,0x09,0x06,0xD3
+ ,0xE8,0x08,0x04,0xD2,0x01,0x20,0xFF,0xF7,0x2A,0xFD
+ ,0x28,0x1C,0x98,0xE7,0xC3,0x4F,0x00,0x20,0x38,0x60
+ ,0xE8,0x0A,0x1D,0xD3,0xB4,0x2C,0x07,0xD0,0xC4,0x2C
+ ,0x16,0xD0,0xD4,0x2C,0x23,0xD1,0x00,0xF0,0xFF,0xF9
+ ,0x20,0xE0,0x3D,0xE0,0xB6,0x48,0x40,0x68,0x80,0x0B
+ ,0x1B,0xD3,0xB9,0x4C,0x02,0x20,0xE1,0x1D,0x03,0x31
+ ,0xB8,0x72,0x01,0x98,0x06,0x22,0xB7,0x4E,0x04,0xF0
+ ,0x8D,0xF8,0x60,0x88,0x70,0x80,0x0E,0xE0,0x00,0xF0
+ ,0xF8,0xFA,0x0B,0xE0,0xA4,0x2C,0x15,0xD0,0xB4,0x2C
+ ,0x13,0xD0,0xC4,0x2C,0x01,0xD0,0xD4,0x2C,0x03,0xD1
+ ,0xAD,0x48,0xAF,0x49,0x40,0x88,0x08,0x80,0x78,0x68
+ ,0x04,0x28,0x06,0xD1,0x00,0xF0,0xCE,0xF9,0x00,0x22
+ ,0x10,0x21,0xAB,0x48,0x03,0xF0,0x31,0xFB,0x28,0x1C
+ ,0x5D,0xE7,0x7A,0x7D,0xA9,0x48,0xAA,0x4B,0x52,0x00
+ ,0x9A,0x5A,0xC1,0x88,0xA5,0x4B,0x8A,0x18,0x1A,0x80
+ ,0xB4,0x2C,0xE8,0xD1,0x80,0x88,0x40,0x00,0x08,0x18
+ ,0x19,0x88,0x40,0x18,0x18,0x80,0xE1,0xE7,0xA3,0x49
+ ,0x08,0x68,0x00,0x7A,0x00,0x28,0x06,0xD0,0xC4,0x20
+ ,0x9A,0x4A,0x01,0x21,0x89,0x06,0x10,0x60,0xC8,0x68
+ ,0x3F,0xE7,0x01,0x20,0xFF,0xF7,0xCC,0xFC,0x29,0x2F
+ ,0x0D,0xD2,0x07,0x20,0xFF,0xF7,0x7B,0xFD,0x91,0x49
+ ,0xC8,0x71,0x0B,0x21,0x79,0x43,0xCF,0x08,0x03,0x21
+ ,0x00,0x91,0x00,0x0A,0x1D,0xD3,0x01,0x3F,0x1B,0xE0
+ ,0x04,0x20,0xFF,0xF7,0x6D,0xFD,0x00,0x06,0x00,0x0E
+ ,0x89,0x4E,0x0A,0x28,0x30,0x71,0x1F,0xD0,0x14,0x28
+ ,0x21,0xD0,0x37,0x28,0x23,0xD0,0x6E,0x28,0x03,0xD1
+ ,0x07,0x20,0xFF,0xF7,0x5E,0xFD,0xF0,0x71,0x0B,0x20
+ ,0x78,0x43,0xC7,0x08,0x03,0x21,0x00,0x91,0xF0,0x79
+ ,0x00,0x0A,0x00,0xD3,0x01,0x3F,0x80,0x2C,0x01,0xD0
+ ,0x50,0x2C,0x16,0xD1,0x03,0x20,0xFF,0xF7,0x4D,0xFD
+ ,0x82,0x49,0x80,0x06,0x09,0x68,0x80,0x0E,0x48,0x74
+ ,0x11,0xE0,0xFF,0x08,0x00,0x21,0x00,0x91,0xEE,0xE7
+ ,0xBF,0x08,0x01,0x21,0x00,0x91,0xEA,0xE7,0x0B,0x20
+ ,0x78,0x43,0x07,0x09,0x02,0x21,0x00,0x91,0xE4,0xE7
+ ,0x78,0x49,0x00,0x20,0x09,0x68,0x48,0x74,0x74,0x48
+ ,0x80,0x89,0x04,0x30,0xB8,0x42,0x01,0xD3,0x18,0x2F
+ ,0x0E,0xD8,0x6C,0x4A,0xC3,0x20,0x10,0x60,0x65,0x48
+ ,0xC1,0x69,0x83,0x01,0x19,0x43,0xC1,0x61,0xC1,0x69
+ ,0x63,0x4B,0x19,0x40,0xC1,0x61,0x01,0x05,0xC8,0x68
+ ,0xDB,0xE6,0x6B,0x4E,0x02,0x22,0x30,0x68,0x18,0x21
+ ,0x40,0x68,0x01,0xF0,0x94,0xFD,0x00,0x28,0x03,0xD1
+ ,0x01,0x21,0x89,0x06,0xC8,0x68,0xCE,0xE6,0x7D,0x20
+ ,0xC0,0x00,0x01,0x22,0x92,0x06,0xD1,0x68,0x29,0x43
+ ,0x03,0xE0,0x01,0x22,0x92,0x06,0xD2,0x68,0x11,0x43
+ ,0x4A,0x09,0x03,0xD2,0x02,0x1C,0x01,0x38,0x00,0x2A
+ ,0xF5,0xD1,0x10,0x23,0x99,0x43,0x0D,0x1C,0x00,0x28
+ ,0x01,0xDC,0x28,0x1C,0xB6,0xE6,0x58,0x48,0x54,0x49
+ ,0x00,0x68,0x00,0x22,0x46,0x68,0x0A,0x80,0x2A,0x0A
+ ,0x52,0x07,0x08,0xD1,0x70,0x88,0x4D,0x4A,0x00,0x27
+ ,0x08,0x80,0x01,0x21,0x11,0x73,0xD7,0x72,0x28,0x1C
+ ,0xA4,0xE6,0x50,0x49,0x0D,0x60,0xE9,0x0A,0x13,0xD3
+ ,0x47,0x4A,0x01,0x21,0x91,0x72,0x71,0x78,0xC9,0x08
+ ,0x03,0xD3,0x71,0x88,0x45,0x4A,0x51,0x80,0x02,0xE0
+ ,0x43,0x49,0x00,0x22,0x4A,0x80,0x40,0x68,0xC1,0x1D
+ ,0x03,0x31,0x06,0x22,0x01,0x98,0x03,0xF0,0x9E,0xFF
+ ,0x00,0x98,0x3D,0x49,0x48,0x75,0x42,0x48,0x02,0x68
+ ,0x97,0x81,0x4A,0x7D,0x03,0x68,0x00,0x27,0x9A,0x73
+ ,0x0F,0x60,0x31,0x78,0x48,0x29,0x03,0xD1,0x71,0x78
+ ,0x40,0x23,0x99,0x43,0x71,0x70,0x71,0x78,0xC9,0x09
+ ,0x2E,0xD2,0x00,0x68,0x02,0x22,0x81,0x89,0x40,0x68
+ ,0x18,0x30,0x18,0x39,0x01,0xF0,0x2F,0xFD,0x00,0x28
+ ,0x05,0xD1,0x2E,0x48,0x01,0x21,0x01,0x73,0xC7,0x72
+ ,0x28,0x1C,0x67,0xE6,0x2B,0x4F,0x03,0x20,0xF8,0x72
+ ,0x02,0x20,0x38,0x73,0x80,0x2C,0x15,0xD1,0x2F,0x48
+ ,0xC1,0x1D,0x29,0x31,0x09,0x79,0x01,0x29,0x0F,0xD1
+ ,0xF9,0x1D,0x49,0x31,0x89,0x79,0x05,0x29,0x0A,0xD1
+ ,0xC1,0x1D,0x07,0x31,0xF0,0x1D,0x06,0x22,0x09,0x30
+ ,0x03,0xF0,0x42,0xFF,0x00,0x28,0x01,0xD1,0x01,0x21
+ ,0xB9,0x76,0x28,0x1C,0x48,0xE6,0x24,0x4E,0x31,0x78
+ ,0x00,0x29,0x05,0xD1,0x19,0x48,0x01,0x21,0x01,0x73
+ ,0xC7,0x72,0x28,0x1C,0x3E,0xE6,0x04,0x1C,0x00,0x68
+ ,0x02,0x22,0x40,0x68,0x04,0x21,0x18,0x30,0x01,0xF0
+ ,0xF6,0xFC,0x00,0x28,0x01,0xD1,0x28,0x1C,0x32,0xE6
+ ,0x7D,0x20,0xC0,0x00,0x01,0x22,0x92,0x06,0xD1,0x68
+ ,0x29,0x43,0x01,0xE0,0xD3,0x68,0x19,0x43,0x4B,0x09
+ ,0x03,0xD2,0x03,0x1C,0x01,0x38,0x00,0x2B,0xF7,0xD1
+ ,0x10,0x23,0x99,0x43,0x0D,0x1C,0x00,0x28,0x23,0xDC
+ ,0x20,0xE0,0x00,0x00,0x40,0x00,0x00,0x04,0xFF,0xEF
+ ,0x00,0x00,0x4C,0x01,0x00,0x02,0x30,0x09,0x00,0x02
+ ,0xCC,0x07,0x00,0x02,0xB4,0x07,0x00,0x02,0x44,0x09
+ ,0x00,0x02,0x2C,0x09,0x00,0x02,0xE2,0x01,0x00,0x02
+ ,0x38,0x07,0x00,0x02,0x00,0x00,0x00,0x02,0xB0,0x01
+ ,0x00,0x02,0x48,0x01,0x00,0x02,0xE4,0x01,0x00,0x02
+ ,0x80,0x00,0x00,0x02,0x18,0x00,0x00,0x02,0x28,0x1C
+ ,0xFA,0xE5,0x20,0x68,0x40,0x68,0xC1,0x1D,0x11,0x31
+ ,0x40,0x7E,0x0A,0x78,0x00,0x02,0x10,0x43,0x8A,0x78
+ ,0xC9,0x78,0x12,0x04,0x10,0x43,0x89,0x09,0x09,0x06
+ ,0x09,0x0E,0x0D,0x23,0x59,0x43,0x89,0x19,0x0B,0x7B
+ ,0x1B,0x06,0x18,0x43,0x32,0x1C,0x03,0x26,0x76,0x06
+ ,0x30,0x60,0x8B,0x7B,0x48,0x7B,0x1B,0x02,0x18,0x43
+ ,0xCB,0x7B,0x1B,0x04,0x18,0x43,0x0B,0x7C,0x1B,0x06
+ ,0x18,0x43,0x70,0x60,0xD0,0x1D,0x39,0x30,0x00,0x78
+ ,0x01,0x28,0x02,0xD1,0x01,0x21,0xB1,0x60,0x19,0xE0
+ ,0x02,0x28,0x17,0xD1,0x8A,0x7C,0x48,0x7C,0x12,0x02
+ ,0x10,0x43,0xCA,0x7C,0x12,0x04,0x10,0x43,0x0A,0x7D
+ ,0x12,0x06,0x10,0x43,0x70,0x61,0x8A,0x7D,0x48,0x7D
+ ,0x12,0x02,0x10,0x43,0xCA,0x7D,0x09,0x7E,0x12,0x04
+ ,0x10,0x43,0x09,0x06,0x08,0x43,0xB0,0x61,0x81,0x20
+ ,0xB0,0x60,0x20,0x68,0x0E,0x22,0x81,0x89,0x40,0x68
+ ,0x18,0x30,0x20,0x39,0x01,0xF0,0x6C,0xFC,0x00,0x28
+ ,0x06,0xD1,0x08,0x48,0x01,0x21,0x01,0x73,0xC7,0x72
+ ,0xB7,0x60,0x28,0x1C,0xA3,0xE5,0x20,0x68,0x81,0x89
+ ,0x08,0x39,0x81,0x81,0x03,0x49,0x03,0x20,0xC8,0x72
+ ,0x02,0x20,0x08,0x73,0x28,0x1C,0x98,0xE5,0x44,0x09
+ ,0x00,0x02,0x00,0xB5,0x03,0x49,0x01,0x20,0x48,0x60
+ ,0x01,0xF0,0xD0,0xF8,0x00,0xBD,0x00,0x00,0x44,0x09
+ ,0x00,0x02,0xF0,0xB5,0x3D,0x4F,0x01,0x24,0x78,0x68
+ ,0x04,0x28,0x0C,0xD1,0x01,0x20,0x01,0xF0,0xC3,0xF8
+ ,0x7C,0x60,0x01,0x20,0xFF,0xF7,0x0F,0xFB,0x00,0x22
+ ,0x01,0x21,0x37,0x48,0x03,0xF0,0x4C,0xF9,0xF0,0xBD
+ ,0x78,0x68,0x02,0x28,0xFB,0xD1,0x01,0x20,0x01,0xF0
+ ,0xB3,0xF8,0x7C,0x60,0x78,0x6E,0x08,0x23,0x41,0x78
+ ,0x32,0x4C,0x99,0x43,0x41,0x70,0x2F,0x49,0x89,0x89
+ ,0xB9,0x87,0x22,0x78,0x2F,0x49,0x01,0x2A,0x45,0xD1
+ ,0x2F,0x4B,0x1A,0x78,0x00,0x2A,0x01,0xD0,0x18,0x25
+ ,0x00,0xE0,0x1E,0x25,0x2C,0x4E,0x36,0x88,0x75,0x1B
+ ,0x2C,0x4E,0x36,0x68,0xAD,0x19,0x2A,0x4E,0x01,0x32
+ ,0x35,0x60,0x1A,0x70,0x1A,0x78,0x86,0x7D,0x12,0x07
+ ,0x12,0x0F,0x1D,0x1C,0xF0,0x23,0x33,0x40,0x1A,0x43
+ ,0x82,0x75,0x42,0x78,0xD2,0x09,0x03,0xD3,0x22,0x4A
+ ,0x13,0x68,0x08,0x3B,0x13,0x60,0x21,0x4B,0x2A,0x78
+ ,0x1B,0x88,0x9A,0x42,0x0F,0xD1,0x20,0x4A,0x1C,0x4E
+ ,0x12,0x88,0x04,0x23,0x32,0x80,0x42,0x78,0x9A,0x43
+ ,0x42,0x70,0x02,0x20,0x20,0x70,0x08,0x68,0x80,0x7D
+ ,0x31,0x88,0x00,0xF0,0x68,0xFF,0xF8,0x66,0x15,0x4E
+ ,0x30,0x88,0xB8,0x66,0x20,0x78,0x02,0x28,0x04,0xD0
+ ,0x01,0x21,0x01,0x20,0x00,0xF0,0x2D,0xF8,0xF0,0xBD
+ ,0x01,0x21,0x00,0x20,0x00,0xF0,0x28,0xF8,0xF0,0xBD
+ ,0x09,0x68,0x00,0x20,0x48,0x73,0x0F,0x49,0x09,0x68
+ ,0x48,0x70,0x01,0x20,0xFF,0xF7,0xA6,0xFA,0x00,0x22
+ ,0x10,0x21,0x0C,0x48,0x03,0xF0,0xE3,0xF8,0xF0,0xBD
+ ,0x44,0x09,0x00,0x02,0x38,0x07,0x00,0x02,0xC0,0x00
+ ,0x00,0x02,0x95,0x01,0x00,0x02,0xC4,0x01,0x00,0x02
+ ,0x96,0x01,0x00,0x02,0x98,0x01,0x00,0x02,0xA0,0x01
+ ,0x00,0x02,0x9C,0x01,0x00,0x02,0x9A,0x01,0x00,0x02
+ ,0xD0,0x01,0x00,0x02,0xF8,0x06,0x00,0x02,0xF0,0xB5
+ ,0x30,0x4D,0x04,0x1C,0x28,0x68,0x0F,0x1C,0x80,0x7D
+ ,0x2E,0x49,0x08,0x70,0x00,0xF0,0x86,0xFF,0x2C,0x49
+ ,0x08,0x78,0x03,0x28,0x04,0xD1,0x2B,0x48,0x40,0x6B
+ ,0xFF,0xF7,0xB8,0xFA,0x02,0xE0,0x00,0x20,0xFF,0xF7
+ ,0xB4,0xFA,0x28,0x68,0x85,0x7D,0x27,0x48,0x80,0x7A
+ ,0x85,0x42,0x00,0xDB,0x05,0x1C,0x23,0x48,0x00,0x78
+ ,0x01,0xF0,0xAF,0xFB,0x24,0x4A,0x24,0x49,0x10,0x60
+ ,0xCB,0x88,0x69,0x00,0x23,0x4D,0x69,0x5A,0x59,0x18
+ ,0x00,0x2C,0x12,0xD0,0x00,0x2F,0x11,0xD0,0x21,0x4C
+ ,0x21,0x4D,0x24,0x88,0x2D,0x78,0x5B,0x18,0x1B,0x18
+ ,0x01,0x3C,0xAC,0x42,0x03,0xD1,0x1E,0x4C,0x24,0x68
+ ,0x1E,0x19,0x04,0xE0,0x15,0x4C,0xE4,0x6E,0xE6,0x18
+ ,0x00,0xE0,0x00,0x26,0x13,0x4C,0x14,0x4A,0xE3,0x6E
+ ,0x18,0x18,0x10,0x60,0x18,0x4A,0x12,0x88,0x10,0x18
+ ,0x45,0x18,0x00,0x2F,0x07,0xD0,0x60,0x6E,0x0C,0x49
+ ,0x02,0x30,0x33,0x1C,0x00,0x22,0x09,0x78,0xFF,0xF7
+ ,0x9E,0xFB,0x01,0x20,0x29,0x1C,0x00,0xF0,0xC8,0xFF
+ ,0x02,0x20,0x60,0x60,0x01,0x20,0x0F,0x49,0xE0,0x75
+ ,0x09,0x88,0xE0,0x6E,0x06,0x4A,0x40,0x18,0x10,0x60
+ ,0xF0,0xBD,0x00,0x00,0xC4,0x01,0x00,0x02,0x93,0x01
+ ,0x00,0x02,0x44,0x09,0x00,0x02,0x04,0x01,0x00,0x02
+ ,0x8C,0x01,0x00,0x02,0x00,0x00,0x00,0x02,0xB0,0x01
+ ,0x00,0x02,0x9C,0x01,0x00,0x02,0x96,0x01,0x00,0x02
+ ,0xA4,0x01,0x00,0x02,0xAE,0x01,0x00,0x02,0xAC,0x01
+ ,0x00,0x02,0x00,0xB5,0x06,0x48,0x40,0x68,0x03,0x28
+ ,0x06,0xD1,0x01,0x20,0x00,0xF0,0xB6,0xFF,0x00,0x21
+ ,0x01,0x20,0xFF,0xF7,0x7A,0xFF,0x00,0xBD,0x00,0x00
+ ,0x44,0x09,0x00,0x02,0x00,0xB5,0x11,0x49,0x09,0x68
+ ,0x49,0x68,0x0A,0x78,0x13,0x07,0x10,0xD1,0x12,0x11
+ ,0x0D,0x2A,0x0D,0xD2,0x01,0xA3,0x9B,0x5C,0x5B,0x00
+ ,0x9F,0x44,0x09,0x0A,0x09,0x0A,0x0D,0x06,0x09,0x09
+ ,0x06,0x09,0x0A,0x0A,0x0A,0x00,0x08,0x1C,0x00,0xF0
+ ,0x10,0xF8,0x00,0xBD,0xFF,0xF7,0x0D,0xFC,0x00,0xBD
+ ,0x04,0x48,0x40,0x78,0x00,0x28,0xF7,0xD0,0x07,0xF0
+ ,0x12,0xFE,0x00,0xBD,0x00,0x00,0x48,0x01,0x00,0x02
+ ,0x94,0x09,0x00,0x02,0xB0,0xB5,0x28,0x4C,0x07,0x1C
+ ,0xA0,0x79,0x01,0x28,0x02,0xD1,0x38,0x1C,0x07,0xF0
+ ,0xF5,0xFD,0x38,0x78,0x50,0x28,0x0E,0xD0,0xA0,0x79
+ ,0x03,0x28,0x03,0xD1,0x07,0xF0,0xD1,0xF9,0x00,0x28
+ ,0x3D,0xD0,0xA0,0x79,0x04,0x28,0x04,0xD1,0x01,0x20
+ ,0x07,0xF0,0xC7,0xF8,0x00,0x28,0x35,0xD0,0xA0,0x79
+ ,0x05,0x28,0x30,0xD1,0x1A,0x4D,0xF8,0x1D,0x09,0x30
+ ,0x06,0x22,0xE9,0x1D,0x07,0x31,0x03,0xF0,0x14,0xFD
+ ,0x17,0x4C,0x00,0x28,0x20,0xD1,0x20,0x79,0x20,0x37
+ ,0x02,0x28,0x0A,0xD1,0xB8,0x78,0x40,0x08,0x20,0xD3
+ ,0x06,0x20,0x00,0xF0,0x53,0xFF,0x00,0x20,0x00,0xF0
+ ,0x22,0xF8,0x00,0xF0,0xD4,0xF8,0x20,0x79,0x01,0x28
+ ,0x13,0xD1,0xB8,0x78,0x80,0x08,0x12,0xD3,0x00,0x20
+ ,0x00,0xF0,0x17,0xF8,0x00,0xF0,0x05,0xFF,0x29,0x88
+ ,0x89,0x02,0x09,0x1A,0x06,0x20,0x00,0xF0,0x23,0xFF
+ ,0x04,0xE0,0x20,0x79,0x01,0x28,0x01,0xD1,0x07,0xF0
+ ,0x45,0xFE,0xFF,0xF7,0xC9,0xFB,0xB0,0xBD,0x94,0x09
+ ,0x00,0x02,0x80,0x00,0x00,0x02,0xB0,0x00,0x00,0x02
+ ,0xF1,0xB5,0x83,0xB0,0x3E,0x49,0x00,0x25,0x0B,0x68
+ ,0x02,0x93,0x59,0x68,0x4A,0x7E,0x0F,0x7E,0x12,0x02
+ ,0x3A,0x43,0x8F,0x7E,0x3F,0x04,0x3A,0x43,0xCF,0x7E
+ ,0x3F,0x06,0x3A,0x43,0x16,0x1C,0x4F,0x7F,0x0A,0x7F
+ ,0x3F,0x02,0x3A,0x43,0x8F,0x7F,0xC9,0x7F,0x3F,0x04
+ ,0x3A,0x43,0x09,0x06,0x0A,0x43,0x99,0x89,0x18,0x39
+ ,0xCC,0x00,0x99,0x7B,0x17,0x1C,0x00,0x29,0x26,0xD0
+ ,0x01,0x29,0x26,0xD0,0x02,0x29,0x26,0xD0,0x03,0x29
+ ,0x0C,0xD1,0x0B,0x20,0x21,0x1C,0x03,0xF0,0x17,0xFD
+ ,0x00,0x91,0x61,0x1A,0x0B,0x20,0x03,0xF0,0x12,0xFD
+ ,0x00,0x99,0x00,0x29,0x00,0xD9,0x01,0x30,0x01,0x24
+ ,0xA4,0x06,0xA2,0x6A,0x61,0x6A,0x02,0x9B,0x30,0x18
+ ,0x5B,0x69,0xCB,0x1A,0xC0,0x18,0xB0,0x42,0x00,0xD2
+ ,0x01,0x37,0x06,0x1C,0x1F,0x48,0x03,0x79,0x00,0x20
+ ,0x02,0x2B,0x14,0xD1,0x01,0x25,0x1F,0xE0,0x20,0x1C
+ ,0xE9,0xE7,0x60,0x08,0xE7,0xE7,0x61,0x00,0x01,0x91
+ ,0x0B,0x20,0x03,0xF0,0xF1,0xFC,0x0C,0x1C,0x01,0x99
+ ,0x09,0x1B,0x0B,0x20,0x03,0xF0,0xEB,0xFC,0x00,0x2C
+ ,0xDA,0xD9,0x01,0x30,0xD8,0xE7,0x01,0x2B,0x0A,0xD1
+ ,0x12,0x4B,0x97,0x42,0x58,0x70,0x01,0xD9,0x01,0x25
+ ,0x04,0xE0,0x97,0x42,0x02,0xD1,0x8E,0x42,0x00,0xD9
+ ,0x01,0x25,0x03,0x9A,0x00,0x2A,0x03,0xD0,0x00,0x2D
+ ,0x03,0xD1,0x04,0xB0,0xF0,0xBD,0x00,0x2D,0x09,0xD0
+ ,0x70,0x1A,0x00,0xF0,0x10,0xF8,0x01,0x23,0xDE,0x42
+ ,0x01,0xD1,0x00,0x26,0x01,0x37,0xA7,0x62,0x66,0x62
+ ,0x01,0x20,0xEF,0xE7,0x00,0x00,0x48,0x01,0x00,0x02
+ ,0xB0,0x00,0x00,0x02,0x94,0x09,0x00,0x02,0x90,0xB4
+ ,0x10,0x4A,0x00,0x21,0x97,0x69,0x91,0x61,0x01,0x21
+ ,0x0E,0x4B,0x8C,0x00,0xE3,0x18,0xDC,0x6A,0x01,0x31
+ ,0x24,0x18,0xDC,0x62,0x08,0x29,0xF6,0xD9,0x0B,0x49
+ ,0x0B,0x6B,0x1B,0x18,0x0B,0x63,0x0B,0x6B,0x5B,0x00
+ ,0x5B,0x08,0x0B,0x63,0xCB,0x6A,0x18,0x18,0xC8,0x62
+ ,0xC8,0x6A,0x40,0x00,0x40,0x08,0xC8,0x62,0x97,0x61
+ ,0x90,0xBC,0xF7,0x46,0x00,0x00,0x80,0x00,0x00,0x04
+ ,0x40,0x00,0x00,0x04,0x44,0x09,0x00,0x02,0x00,0xB5
+ ,0x08,0x29,0x01,0xD1,0xFF,0xF7,0xF5,0xFA,0x00,0xBD
+ ,0xB0,0xB5,0x1D,0x48,0x00,0x25,0x02,0x68,0x24,0x20
+ ,0x51,0x68,0x92,0x89,0x00,0x24,0x04,0x3A,0x24,0x2A
+ ,0x26,0xD9,0x0F,0x5C,0x06,0x2F,0x1C,0xD2,0x01,0xA3
+ ,0xDB,0x5D,0x5B,0x00,0x9F,0x44,0x02,0x02,0x18,0x02
+ ,0x07,0x20,0x0B,0x18,0x5B,0x78,0x02,0x33,0x18,0x18
+ ,0x0E,0xE0,0x0B,0x18,0x5F,0x79,0x1C,0x79,0x3F,0x02
+ ,0x27,0x43,0x3D,0x1C,0xDF,0x79,0x9C,0x79,0x5B,0x78
+ ,0x3F,0x02,0x27,0x43,0x3C,0x04,0x24,0x0C,0x02,0x33
+ ,0x18,0x18,0x82,0x42,0xDF,0xD8,0x00,0x2C,0x04,0xD9
+ ,0xAC,0x42,0x02,0xD2,0xA0,0x02,0x00,0xF0,0x0E,0xF8
+ ,0xB0,0xBD,0x05,0x4A,0x52,0x79,0x01,0x2A,0xF3,0xDD
+ ,0x08,0x18,0x00,0xF0,0x24,0xF8,0xEF,0xE7,0x00,0x00
+ ,0x48,0x01,0x00,0x02,0xB0,0x00,0x00,0x02,0x0B,0x49
+ ,0x09,0x68,0x49,0x69,0x08,0x18,0x0A,0x49,0x4A,0x7A
+ ,0x05,0x2A,0x02,0xD1,0x8A,0x6B,0x82,0x42,0x0A,0xD2
+ ,0x05,0x22,0x4A,0x72,0x02,0x1C,0x06,0x48,0x80,0x23
+ ,0xC2,0x60,0x82,0x69,0x1A,0x43,0x82,0x61,0xC0,0x68
+ ,0x88,0x63,0xF7,0x46,0x00,0x00,0x48,0x01,0x00,0x02
+ ,0x44,0x09,0x00,0x02,0x80,0x00,0x00,0x04,0xF0,0xB5
+ ,0x02,0x79,0x35,0x4C,0x87,0x78,0xFE,0x21,0x11,0x40
+ ,0xE5,0x88,0x03,0x23,0x9B,0x03,0x9D,0x43,0x2B,0x1C
+ ,0x00,0x29,0x03,0xD0,0xCD,0x00,0x01,0x3D,0x9D,0x42
+ ,0x05,0xD2,0x45,0x78,0x6D,0x18,0xED,0x00,0x18,0x3D
+ ,0x9D,0x42,0x01,0xD8,0x00,0x25,0x08,0xE0,0xC9,0x00
+ ,0x59,0x1A,0x89,0x09,0x5E,0x07,0x76,0x0F,0x41,0x18
+ ,0x49,0x79,0xF1,0x40,0x0D,0x1C,0x00,0x23,0x26,0x49
+ ,0x52,0x08,0x8B,0x70,0x05,0xD3,0x00,0x2F,0x03,0xD1
+ ,0x8A,0x78,0x02,0x23,0x1A,0x43,0x8A,0x70,0xEA,0x07
+ ,0xD2,0x0F,0x03,0xD0,0x8D,0x78,0x04,0x23,0x2B,0x43
+ ,0x8B,0x70,0xE3,0x1D,0x29,0x33,0x5B,0x79,0x01,0x25
+ ,0x02,0x2B,0x1D,0xD1,0x8E,0x78,0x08,0x23,0x33,0x43
+ ,0x8B,0x70,0x00,0x2A,0x03,0xD0,0x0A,0x78,0x00,0x2A
+ ,0x00,0xD1,0x4D,0x70,0x00,0x2F,0x00,0xD1,0xC7,0x78
+ ,0x15,0x48,0x40,0x8B,0xB8,0x42,0x00,0xD8,0x07,0x1C
+ ,0x00,0xF0,0x90,0xFD,0x21,0x88,0x12,0x4B,0x4F,0x43
+ ,0xB9,0x02,0x08,0x1A,0xC1,0x18,0x06,0x20,0x00,0xF0
+ ,0xAB,0xFD,0xF0,0xBD,0x88,0x78,0xC0,0x08,0x00,0xD3
+ ,0x8D,0x71,0x88,0x78,0x40,0x08,0x80,0x07,0x07,0xD1
+ ,0x0A,0x48,0x80,0x69,0x80,0x08,0x03,0xD2,0x88,0x78
+ ,0x08,0x23,0x18,0x43,0x88,0x70,0x88,0x78,0x04,0x23
+ ,0x98,0x43,0x88,0x70,0xF0,0xBD,0x00,0x00,0x80,0x00
+ ,0x00,0x02,0xB4,0x09,0x00,0x02,0xC0,0x00,0x00,0x02
+ ,0x48,0xF4,0xFF,0xFF,0x80,0x00,0x00,0x04,0xF0,0xB5
+ ,0x82,0xB0,0x36,0x48,0x34,0x4E,0xC5,0x1D,0x09,0x35
+ ,0x33,0x4C,0xC7,0x1D,0x69,0x37,0x00,0x22,0xD2,0x43
+ ,0x00,0x92,0x01,0x22,0x01,0xAB,0x31,0x48,0x32,0x49
+ ,0x02,0xF0,0x1E,0xFF,0x01,0x98,0x41,0x0A,0x0C,0xD3
+ ,0x80,0x20,0x38,0x71,0x00,0x20,0x78,0x71,0x38,0x79
+ ,0x00,0x0A,0x4C,0xD3,0x07,0xF0,0x9E,0xFD,0x38,0x79
+ ,0x00,0x0A,0xFA,0xD2,0x46,0xE0,0x41,0x08,0x0F,0xD3
+ ,0x30,0x1C,0xFF,0xF7,0x27,0xF9,0x27,0x48,0x41,0x6C
+ ,0x09,0x78,0x40,0x29,0x3C,0xD0,0x07,0xF0,0x78,0xFA
+ ,0x23,0x48,0x40,0x6C,0x00,0x78,0x40,0x28,0xF8,0xD1
+ ,0x34,0xE0,0x41,0x0D,0x03,0xD3,0x40,0x20,0x07,0xF0
+ ,0x3B,0xF9,0x2E,0xE0,0x41,0x09,0x03,0xD3,0x50,0x20
+ ,0x07,0xF0,0x35,0xF9,0x28,0xE0,0x40,0x0F,0x03,0xD3
+ ,0x80,0x20,0x07,0xF0,0x2F,0xF9,0x22,0xE0,0x00,0x21
+ ,0x79,0x22,0x52,0x05,0x17,0x48,0x91,0x82,0x10,0x82
+ ,0x91,0x80,0x64,0x20,0x10,0x80,0x02,0x20,0x90,0x82
+ ,0x12,0x48,0x21,0x72,0x81,0x6B,0x09,0x7B,0x09,0x0A
+ ,0x06,0xD3,0x00,0xF0,0x21,0xF8,0x0E,0x48,0x80,0x6B
+ ,0x00,0x7B,0x00,0x0A,0xF8,0xD2,0xC0,0x20,0x02,0xF0
+ ,0x31,0xFF,0x00,0x21,0x79,0x22,0x52,0x05,0x91,0x82
+ ,0x11,0x83,0x21,0x72,0x02,0xF0,0x29,0xFF,0x00,0x20
+ ,0xA8,0x73,0x9C,0xE7,0x1A,0x08,0x00,0x02,0xCC,0x01
+ ,0x00,0x02,0x44,0x09,0x00,0x02,0x18,0x07,0x00,0x02
+ ,0x11,0x11,0x10,0x10,0x8C,0x01,0x00,0x02,0xA0,0x8C
+ ,0x00,0x00,0xF0,0xB5,0x83,0xB0,0x87,0x4D,0x00,0x24
+ ,0xA8,0x6B,0x47,0x68,0x39,0x79,0x49,0x08,0x01,0xD3
+ ,0x01,0x26,0x00,0xE0,0x00,0x26,0x82,0x4D,0x69,0x7A
+ ,0x00,0x29,0x73,0xD1,0x81,0x4A,0xD1,0x78,0x00,0x29
+ ,0x0C,0xD0,0x39,0x78,0x08,0x29,0x09,0xD1,0x7F,0x4A
+ ,0x91,0x78,0x00,0x29,0x05,0xD0,0x81,0x7D,0xD3,0x78
+ ,0x99,0x42,0x01,0xDD,0xD1,0x78,0x81,0x75,0x78,0x4B
+ ,0x7A,0x49,0x9D,0x6B,0x00,0x22,0x68,0x68,0x00,0x2E
+ ,0x48,0x66,0x9A,0x72,0x65,0xD1,0x77,0x48,0xA9,0x8A
+ ,0x00,0x89,0x04,0x38,0x81,0x42,0x60,0xDD,0x70,0x4A
+ ,0x01,0x21,0x51,0x72,0xF9,0x1D,0x17,0x31,0x51,0x61
+ ,0x6D,0x49,0x04,0x04,0x24,0x0C,0x8C,0x81,0xA8,0x8A
+ ,0x01,0x1B,0xE0,0x1F,0x11,0x38,0x02,0x90,0x03,0xF0
+ ,0x17,0xFB,0x68,0x49,0x01,0x30,0x08,0x82,0xA8,0x8A
+ ,0x01,0x1B,0x02,0x98,0x03,0xF0,0x0F,0xFB,0xC8,0x1D
+ ,0x63,0x49,0x11,0x30,0xC8,0x81,0xC8,0x89,0x18,0x28
+ ,0x04,0xD1,0x60,0x4B,0xDC,0x81,0x18,0x8A,0x01,0x38
+ ,0x18,0x82,0x78,0x78,0xC0,0x09,0x06,0xD3,0x5C,0x4B
+ ,0xE0,0x1D,0x01,0x30,0x98,0x81,0xD8,0x89,0x08,0x30
+ ,0xD8,0x81,0x59,0x4C,0xA8,0x7D,0xE1,0x89,0x00,0xF0
+ ,0xBE,0xFB,0xA0,0x61,0xA0,0x6B,0x80,0x7D,0xA1,0x89
+ ,0x00,0xF0,0xB8,0xFB,0x56,0x49,0x54,0x4A,0xC8,0x66
+ ,0xA0,0x89,0x88,0x66,0xA0,0x6B,0x80,0x7D,0x92,0x7A
+ ,0x90,0x42,0x00,0xDA,0x02,0x1C,0x53,0x4B,0x52,0x00
+ ,0x9A,0x5A,0x52,0x4B,0xDB,0x88,0x5B,0x00,0xD2,0x18
+ ,0x23,0x8A,0xA5,0x7A,0x01,0x3B,0xAB,0x42,0x04,0xD1
+ ,0xA1,0x69,0x54,0x18,0x00,0xE0,0x25,0xE0,0x01,0xE0
+ ,0xC9,0x6E,0x8C,0x18,0x01,0xF0,0x38,0xF8,0x04,0x19
+ ,0x78,0x78,0x04,0x23,0x18,0x43,0x78,0x70,0x12,0xE0
+ ,0xFF,0xE7,0x40,0x48,0x42,0x49,0x42,0x72,0xA8,0x8A
+ ,0x88,0x66,0x78,0x78,0xC0,0x09,0x02,0xD3,0x88,0x6E
+ ,0x08,0x30,0x88,0x66,0x3D,0x49,0x89,0x6E,0xA8,0x7D
+ ,0x00,0xF0,0x81,0xFB,0x3B,0x49,0xC8,0x66,0x37,0x48
+ ,0x32,0x1C,0x80,0x6B,0x81,0x7D,0xB8,0x1C,0x23,0x1C
+ ,0xFF,0xF7,0x37,0xF8,0x30,0x1C,0x00,0xF0,0xF0,0xFA
+ ,0x00,0x28,0x0A,0xD0,0x02,0x20,0x33,0x49,0xC2,0x1E
+ ,0x48,0x74,0x00,0x92,0x01,0x22,0x11,0x21,0x34,0x48
+ ,0x01,0xAB,0x02,0xF0,0xFB,0xFD,0x2E,0x48,0x00,0x24
+ ,0x2A,0x4D,0x44,0x74,0xA8,0x6B,0x41,0x7B,0x00,0x29
+ ,0x0C,0xD1,0x38,0x1C,0x00,0xF0,0x70,0xF8,0x27,0x4A
+ ,0x54,0x70,0x10,0x78,0x01,0x30,0x10,0x70,0x00,0xF0
+ ,0xD9,0xFB,0x00,0xF0,0x55,0xF8,0x3E,0xE0,0xE9,0x1D
+ ,0x39,0x31,0x0A,0x7A,0x01,0x2A,0x05,0xD1,0x08,0x22
+ ,0x42,0x73,0x0C,0x72,0x00,0xF0,0x4A,0xF8,0x33,0xE0
+ ,0x40,0x7B,0x04,0x28,0x1F,0xD0,0x00,0xF0,0xB6,0xFB
+ ,0xA8,0x6B,0x81,0x7B,0x01,0x31,0x81,0x73,0x78,0x78
+ ,0x08,0x23,0x18,0x43,0x78,0x70,0x38,0x78,0x08,0x28
+ ,0x12,0xD1,0x14,0x48,0xC0,0x78,0x00,0x28,0x0E,0xD0
+ ,0x13,0x4A,0x18,0x4B,0x50,0x78,0x01,0x30,0x00,0x06
+ ,0x00,0x0E,0x50,0x70,0xA9,0x6B,0x89,0x7D,0x59,0x5C
+ ,0x88,0x42,0x00,0xDD,0x14,0x70,0x00,0xF0,0xA8,0xFB
+ ,0xA8,0x6B,0x0D,0x4A,0x81,0x7B,0x12,0x7C,0x91,0x42
+ ,0x04,0xDA,0x44,0x73,0xA9,0x6B,0x82,0x20,0x08,0x73
+ ,0x05,0xE0,0x01,0x21,0x38,0x1C,0x00,0xF0,0x29,0xF8
+ ,0x00,0xF0,0x15,0xF8,0x03,0xB0,0xF0,0xBD,0x00,0x00
+ ,0x8C,0x01,0x00,0x02,0x04,0x01,0x00,0x02,0xC8,0x01
+ ,0x00,0x02,0x44,0x09,0x00,0x02,0xC0,0x00,0x00,0x02
+ ,0xB0,0x01,0x00,0x02,0x00,0x00,0x00,0x02,0xF8,0x06
+ ,0x00,0x02,0xD6,0x01,0x00,0x02,0x05,0x48,0x00,0x21
+ ,0x41,0x72,0x81,0x72,0x04,0x49,0x05,0x4A,0x89,0x89
+ ,0x91,0x87,0x80,0x6B,0x10,0x21,0x01,0x73,0xF7,0x46
+ ,0x8C,0x01,0x00,0x02,0xC0,0x00,0x00,0x02,0x44,0x09
+ ,0x00,0x02,0x80,0xB4,0x09,0x4A,0x01,0x27,0x53,0x79
+ ,0x08,0x4A,0x03,0x2B,0x02,0xD1,0xD7,0x70,0x80,0xBC
+ ,0xF7,0x46,0x40,0x78,0x40,0x09,0xFA,0xD3,0x00,0x29
+ ,0x02,0xD1,0x00,0x20,0xD0,0x70,0xF5,0xE7,0xD7,0x70
+ ,0xF3,0xE7,0xB0,0x00,0x00,0x02,0xB4,0x09,0x00,0x02
+ ,0x90,0xB5,0xC0,0x20,0x02,0xF0,0xC6,0xFD,0x0A,0x4C
+ ,0x03,0x21,0xA1,0x73,0x02,0xF0,0xC1,0xFD,0x60,0x7F
+ ,0x01,0x28,0x0C,0xD0,0xC0,0x20,0x02,0xF0,0xBB,0xFD
+ ,0x07,0x1C,0xA0,0x7B,0x03,0x28,0x02,0xD1,0x00,0x20
+ ,0x00,0xF0,0x86,0xF9,0x38,0x1C,0x02,0xF0,0xB1,0xFD
+ ,0x90,0xBD,0x44,0x09,0x00,0x02,0x90,0xB5,0xFE,0xF7
+ ,0x09,0xFE,0x1E,0x4F,0xF9,0x6A,0x40,0x1A,0x41,0x00
+ ,0x78,0x7F,0x49,0x08,0x01,0x28,0x01,0xD1,0xB8,0x6A
+ ,0x00,0xE0,0x78,0x6A,0x3B,0x68,0x19,0x4A,0x00,0x2B
+ ,0x1C,0xD1,0x84,0x00,0x93,0x8B,0x24,0x18,0xA4,0x00
+ ,0xE2,0x18,0x51,0x1A,0x8A,0x42,0x00,0xD2,0x11,0x1C
+ ,0x00,0x28,0x0F,0xD1,0x01,0x20,0x78,0x72,0xB8,0x7B
+ ,0x03,0x28,0x05,0xD1,0x0D,0x29,0x04,0xD9,0xC8,0x1F
+ ,0x01,0x38,0x00,0xF0,0x58,0xF9,0x90,0xBD,0x00,0x20
+ ,0x00,0xF0,0x54,0xF9,0x90,0xBD,0x3B,0x62,0x09,0xE0
+ ,0x83,0x00,0xD2,0x8B,0x18,0x18,0x80,0x00,0x80,0x18
+ ,0x41,0x1A,0x88,0x42,0x00,0xD2,0x01,0x1C,0x3A,0x62
+ ,0x08,0x20,0x00,0xF0,0x6A,0xFB,0x04,0x20,0x78,0x72
+ ,0x90,0xBD,0x00,0x00,0x44,0x09,0x00,0x02,0x8C,0x01
+ ,0x00,0x02,0x00,0xB5,0x04,0x49,0x02,0x0A,0x8A,0x74
+ ,0xC8,0x74,0x03,0x21,0x11,0x20,0xFE,0xF7,0x15,0xFE
+ ,0x00,0xBD,0xCC,0x07,0x00,0x02,0xB0,0xB5,0x82,0xB0
+ ,0x11,0x4D,0x01,0x20,0x68,0x74,0x11,0x4F,0x11,0x48
+ ,0x00,0x24,0xBC,0x82,0x38,0x82,0xBC,0x80,0x1E,0x20
+ ,0x38,0x80,0x02,0x20,0xB8,0x82,0xC2,0x1E,0x00,0x92
+ ,0x01,0x22,0x1A,0x21,0x0C,0x48,0x01,0xAB,0x02,0xF0
+ ,0xE5,0xFC,0x6C,0x74,0x3C,0x83,0xBC,0x82,0x01,0x98
+ ,0x81,0x08,0x06,0xD3,0x00,0x09,0x02,0xD3,0x82,0x20
+ ,0x02,0xB0,0xB0,0xBD,0x20,0x1C,0xFB,0xE7,0x42,0x20
+ ,0xF9,0xE7,0x44,0x09,0x00,0x02,0x20,0x00,0x20,0x0F
+ ,0xA0,0x8C,0x00,0x00,0xD8,0x06,0x00,0x02,0xF0,0xB5
+ ,0xFF,0x20,0x01,0x25,0xAD,0x06,0xF5,0x30,0x29,0x69
+ ,0x89,0x08,0x03,0xD3,0x01,0x1C,0x01,0x38,0x00,0x29
+ ,0xF8,0xD8,0x6A,0x4E,0x00,0x27,0xB0,0x7D,0x6A,0x4C
+ ,0x00,0x28,0x11,0xD0,0x30,0x6E,0xFF,0xF7,0xB1,0xFF
+ ,0x60,0x79,0x11,0x23,0x9B,0x02,0x03,0x43,0x03,0x22
+ ,0xF1,0x6D,0xB0,0x6D,0x12,0x03,0x00,0xF0,0xD3,0xF8
+ ,0xB7,0x75,0x01,0x20,0xFE,0xF7,0x6F,0xFD,0xF0,0xBD
+ ,0xF0,0x7B,0x00,0x28,0x1A,0xD0,0xA0,0x6B,0x5E,0x49
+ ,0x80,0x7D,0x89,0x7A,0x88,0x42,0x00,0xDB,0x08,0x1C
+ ,0x5C,0x49,0x40,0x00,0x08,0x5A,0xFF,0xF7,0x93,0xFF
+ ,0x60,0x79,0x11,0x23,0x9B,0x02,0x03,0x43,0x03,0x22
+ ,0x12,0x03,0x10,0x21,0x57,0x48,0x00,0xF0,0xB5,0xF8
+ ,0x01,0x20,0xFE,0xF7,0x52,0xFD,0xF7,0x73,0xF0,0xBD
+ ,0xF0,0x7D,0x00,0x28,0xDD,0xD0,0x4E,0x4E,0xF0,0x6E
+ ,0xFF,0xF7,0x7D,0xFF,0x76,0x6E,0x70,0x78,0xC0,0x09
+ ,0x4E,0xD3,0x4A,0x4A,0xD0,0x7A,0x00,0x28,0x00,0xD0
+ ,0xD7,0x72,0x07,0x20,0x40,0x06,0x81,0x69,0x08,0x23
+ ,0x19,0x43,0x81,0x61,0x81,0x69,0x99,0x43,0x81,0x61
+ ,0xE8,0x68,0x00,0xF0,0x8C,0xFF,0x01,0x23,0x9B,0x03
+ ,0x9A,0x08,0x1C,0x21,0x44,0x48,0x00,0xF0,0x8D,0xF8
+ ,0xFF,0x20,0x43,0x49,0xF5,0x30,0x4A,0x68,0xD2,0x0B
+ ,0x03,0xD3,0x02,0x1C,0x01,0x38,0x00,0x2A,0xF8,0xD1
+ ,0x40,0x48,0x03,0x21,0x00,0x78,0x49,0x06,0x02,0x28
+ ,0x02,0xD1,0x81,0x20,0x88,0x60,0x01,0xE0,0x01,0x20
+ ,0x88,0x60,0x62,0x7A,0x00,0x2A,0x0F,0xD0,0xA0,0x7A
+ ,0x00,0x28,0x03,0xD0,0x00,0x28,0x01,0xDD,0x60,0x69
+ ,0x01,0xE0,0x60,0x69,0x06,0x38,0xA1,0x89,0x20,0x39
+ ,0x02,0x2A,0x08,0xD1,0x2B,0x4A,0xD7,0x75,0x05,0xE0
+ ,0x2A,0x4A,0x50,0x6E,0x91,0x6E,0x18,0x30,0x20,0x39
+ ,0xD7,0x75,0x62,0x79,0x17,0x23,0x9B,0x02,0x13,0x43
+ ,0x01,0x22,0x52,0x03,0x00,0xF0,0x57,0xF8,0x33,0xE0
+ ,0x60,0x7A,0x00,0x28,0x23,0xD0,0xA0,0x7A,0x00,0x28
+ ,0x01,0xD0,0x18,0x25,0x00,0xE0,0x1E,0x25,0x01,0x23
+ ,0x9B,0x03,0x1D,0x48,0x9A,0x08,0x29,0x1C,0x40,0x6E
+ ,0x00,0xF0,0x45,0xF8,0xFF,0x20,0x1F,0x49,0xF5,0x30
+ ,0x4A,0x68,0xD2,0x0B,0x03,0xD3,0x02,0x1C,0x01,0x38
+ ,0x00,0x2A,0xF8,0xD1,0x60,0x79,0x11,0x23,0x9B,0x02
+ ,0x03,0x43,0xA0,0x89,0x41,0x1B,0x01,0x22,0x52,0x03
+ ,0x60,0x69,0x00,0xF0,0x30,0xF8,0x0A,0xE0,0x60,0x79
+ ,0x11,0x23,0x9B,0x02,0x03,0x43,0x0D,0x48,0x03,0x22
+ ,0x81,0x6E,0x40,0x6E,0x12,0x03,0x00,0xF0,0x24,0xF8
+ ,0x09,0x48,0xC7,0x75,0x08,0x48,0x47,0x77,0x50,0x30
+ ,0x07,0x71,0x30,0x79,0x40,0x08,0x02,0xD2,0x60,0x7A
+ ,0x01,0x28,0x03,0xD1,0x01,0x20,0xFE,0xF7,0xB5,0xFC
+ ,0xF0,0xBD,0x00,0x20,0xFE,0xF7,0xB1,0xFC,0xF0,0xBD
+ ,0x44,0x09,0x00,0x02,0x8C,0x01,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0xB8,0x01,0x00,0x02,0xEC,0x07,0x00,0x02
+ ,0x58,0x07,0x00,0x02,0x40,0x00,0x00,0x04,0x58,0x00
+ ,0x00,0x02,0xB0,0xB4,0x06,0x4C,0x1F,0x1C,0x65,0x68
+ ,0xEB,0x0B,0x04,0xD2,0x0A,0x43,0x21,0x05,0x4A,0x63
+ ,0x88,0x63,0x67,0x60,0xB0,0xBC,0xF7,0x46,0x00,0x00
+ ,0x40,0x00,0x00,0x04,0xF0,0xB5,0x52,0x49,0x07,0x1C
+ ,0x8A,0x7A,0x00,0x20,0x00,0x2A,0x61,0xD1,0x0A,0x7A
+ ,0x00,0x2A,0x6B,0xD0,0x4A,0x7A,0x01,0x2A,0x5B,0xD1
+ ,0x0A,0x7B,0x01,0x2A,0x58,0xD1,0xCA,0x7A,0x00,0x2A
+ ,0x55,0xD1,0xCE,0x1D,0x49,0x36,0xF1,0x78,0xF5,0x1F
+ ,0x39,0x3D,0x00,0x29,0x0F,0xD1,0x45,0x49,0xCA,0x1D
+ ,0x69,0x32,0x12,0x78,0x00,0x2A,0x09,0xD1,0x6A,0x7B
+ ,0x01,0x2A,0x06,0xD0,0x32,0x79,0x00,0x2A,0x03,0xD1
+ ,0x0C,0x1C,0x89,0x7C,0x00,0x29,0x09,0xD0,0x3E,0x4A
+ ,0x3F,0x4B,0xD1,0x79,0xD9,0x71,0x3B,0x49,0x88,0x75
+ ,0x01,0x20,0xC8,0x75,0xCC,0x6E,0x21,0xE0,0x21,0x7F
+ ,0x00,0x29,0x12,0xD0,0x39,0x4B,0x37,0x4A,0x99,0x6B
+ ,0x89,0x7D,0x92,0x7A,0x91,0x42,0x01,0xDA,0xD9,0x71
+ ,0x00,0xE0,0xDA,0x71,0xA0,0x75,0x01,0x21,0xE1,0x73
+ ,0xE0,0x75,0xD8,0x79,0x32,0x49,0x40,0x00,0x0C,0x5A
+ ,0x0B,0xE0,0xE2,0x7E,0x21,0x1C,0x00,0x2A,0x27,0xD0
+ ,0xCC,0x6E,0x88,0x75,0x01,0x20,0x2C,0x4B,0xC8,0x75
+ ,0x98,0x6B,0x80,0x7D,0xD8,0x71,0x00,0xF0,0x40,0xF9
+ ,0x26,0x4B,0xD8,0x7B,0x00,0x28,0x03,0xD0,0x00,0x20
+ ,0xFE,0xF7,0x73,0xFC,0x0C,0xE0,0x24,0x4B,0xD8,0x79
+ ,0x03,0x28,0x05,0xD1,0x20,0x4B,0x58,0x6B,0xFE,0xF7
+ ,0x6A,0xFC,0x03,0xE0,0x3A,0xE0,0x00,0x20,0xFE,0xF7
+ ,0x65,0xFC,0x01,0x21,0x89,0x06,0x00,0x2F,0x05,0xD0
+ ,0x05,0x2F,0x03,0xD9,0x48,0x6A,0x38,0x18,0x02,0xE0
+ ,0x2D,0xE0,0x48,0x6A,0x0A,0x30,0x16,0x4B,0x02,0x22
+ ,0x9A,0x73,0x18,0x4B,0x92,0x03,0x5A,0x60,0x08,0x62
+ ,0x6A,0x7B,0x01,0x2A,0x02,0xD0,0x32,0x79,0x00,0x2A
+ ,0x15,0xD0,0x10,0x4A,0x8D,0x6A,0x4E,0x6A,0xD1,0x79
+ ,0x13,0x4A,0x12,0x4F,0x89,0x00,0x51,0x58,0x0D,0x4B
+ ,0x08,0x18,0x38,0x60,0xD8,0x79,0x00,0xF0,0x44,0xFD
+ ,0x39,0x68,0x40,0x18,0x38,0x60,0xB0,0x42,0x00,0xD2
+ ,0x01,0x35,0x7D,0x60,0x38,0x1D,0x06,0x4F,0x3C,0x60
+ ,0xF8,0x79,0x00,0xF0,0x37,0xFD,0x39,0x68,0x40,0x18
+ ,0x38,0x60,0x01,0x20,0xF0,0xBD,0x44,0x09,0x00,0x02
+ ,0x04,0x01,0x00,0x02,0x8C,0x01,0x00,0x02,0xB8,0x01
+ ,0x00,0x02,0x40,0x00,0x00,0x04,0x1C,0x08,0x00,0x02
+ ,0x1C,0x09,0x00,0x02,0xF8,0xB5,0x38,0x49,0x04,0x1C
+ ,0x88,0x6B,0x37,0x4A,0x85,0x7D,0x46,0x68,0x92,0x7A
+ ,0x00,0x27,0x95,0x42,0x00,0xDB,0x15,0x1C,0x34,0x49
+ ,0x80,0x8A,0x49,0x89,0x88,0x42,0x2E,0xDD,0x00,0x2C
+ ,0x2C,0xD1,0x2F,0x49,0x88,0x7A,0x00,0x28,0x28,0xD1
+ ,0x30,0x49,0xB4,0x20,0x08,0x70,0x2F,0x48,0x30,0x4A
+ ,0xC0,0x88,0x41,0x00,0x09,0x18,0x68,0x00,0x10,0x5A
+ ,0x40,0x00,0x08,0x18,0x2D,0x49,0xC9,0x6E,0x40,0x18
+ ,0x28,0x49,0x48,0x80,0x28,0x1C,0x00,0xF0,0xF9,0xFC
+ ,0x26,0x49,0x49,0x88,0x40,0x18,0x24,0x49,0x48,0x80
+ ,0x31,0x1D,0x06,0x22,0x26,0x48,0x02,0xF0,0x29,0xFF
+ ,0xF1,0x1D,0x03,0x31,0x06,0x22,0x24,0x48,0x02,0xF0
+ ,0x23,0xFF,0x01,0x20,0x20,0x49,0x01,0x26,0x08,0x77
+ ,0x03,0xE0,0x01,0x20,0x1E,0x49,0x00,0x26,0xC8,0x76
+ ,0xFF,0xF7,0x6A,0xFD,0xFF,0xF7,0xD4,0xFD,0x00,0x90
+ ,0x00,0x98,0x00,0x28,0x1E,0xD1,0x12,0x49,0x00,0x2E
+ ,0x8A,0x6B,0x50,0x73,0x01,0xD1,0x00,0x2C,0x01,0xD0
+ ,0x01,0x2E,0x19,0xD1,0x13,0x4A,0x68,0x00,0x10,0x5A
+ ,0x10,0x4A,0xD2,0x88,0x49,0x8C,0x80,0x18,0x41,0x18
+ ,0x01,0x20,0x00,0xF0,0x12,0xF9,0x01,0x2E,0x03,0xD1
+ ,0x0D,0x49,0x03,0x20,0x48,0x60,0x02,0xE0,0x0B,0x49
+ ,0x02,0x20,0x48,0x60,0x01,0x27,0x03,0xE0,0x03,0x49
+ ,0x04,0x20,0x89,0x6B,0x48,0x73,0x38,0x1C,0xF8,0xBD
+ ,0x00,0x00,0x8C,0x01,0x00,0x02,0x04,0x01,0x00,0x02
+ ,0xC0,0x00,0x00,0x02,0xEC,0x07,0x00,0x02,0x00,0x00
+ ,0x00,0x02,0xB0,0x01,0x00,0x02,0x44,0x09,0x00,0x02
+ ,0xF0,0x07,0x00,0x02,0xF6,0x07,0x00,0x02,0x90,0xB5
+ ,0x04,0x31,0xCF,0x00,0x01,0x28,0x17,0xD0,0x02,0x28
+ ,0x17,0xD0,0x03,0x28,0x27,0xD1,0x0B,0x20,0x39,0x1C
+ ,0x02,0xF0,0x11,0xFF,0x0C,0x1C,0x79,0x1A,0x0B,0x20
+ ,0x02,0xF0,0x0C,0xFF,0x07,0x1C,0x00,0x21,0x00,0x2C
+ ,0x0F,0x48,0x18,0xD9,0x01,0x37,0x04,0x2C,0x13,0xD2
+ ,0x01,0x21,0x41,0x63,0x13,0xE0,0x7F,0x08,0x11,0xE0
+ ,0x79,0x00,0x0B,0x20,0x0F,0x1C,0x02,0xF0,0xFA,0xFE
+ ,0x0C,0x1C,0x79,0x1A,0x0B,0x20,0x02,0xF0,0xF5,0xFE
+ ,0x07,0x1C,0x00,0x2C,0x04,0xD9,0x01,0x37,0x02,0xE0
+ ,0x41,0x63,0x00,0xE0,0x41,0x63,0x38,0x1C,0x90,0xBD
+ ,0x00,0x00,0x44,0x09,0x00,0x02,0xFF,0x21,0x10,0x48
+ ,0x31,0x31,0x01,0x80,0x0F,0x49,0x09,0x8C,0xCA,0x1D
+ ,0x31,0x32,0x42,0x80,0xCA,0x1D,0x0E,0x32,0x82,0x80
+ ,0x0B,0x31,0xC1,0x80,0x0B,0x48,0xA0,0x21,0x01,0x80
+ ,0x50,0x21,0x41,0x80,0x1E,0x21,0x81,0x80,0x0F,0x21
+ ,0xC1,0x80,0x08,0x48,0xC0,0x21,0x01,0x60,0x60,0x21
+ ,0x41,0x60,0x23,0x21,0x81,0x60,0x12,0x21,0xC1,0x60
+ ,0xF7,0x46,0x00,0x00,0xB0,0x01,0x00,0x02,0x8C,0x01
+ ,0x00,0x02,0xB8,0x01,0x00,0x02,0x1C,0x09,0x00,0x02
+ ,0x00,0xB5,0x07,0x48,0xC1,0x79,0x82,0x79,0x91,0x42
+ ,0x07,0xD0,0xC1,0x79,0x81,0x71,0x82,0x79,0x04,0x49
+ ,0x89,0x5C,0x41,0x71,0xFE,0xF7,0xFA,0xFA,0x00,0xBD
+ ,0x00,0x00,0x8C,0x01,0x00,0x02,0xC0,0x01,0x00,0x02
+ ,0x05,0x48,0x81,0x8F,0x49,0x00,0x01,0x31,0x81,0x87
+ ,0x04,0x49,0x82,0x8F,0xC9,0x89,0x8A,0x42,0x00,0xDD
+ ,0x81,0x87,0xF7,0x46,0x44,0x09,0x00,0x02,0xC0,0x00
+ ,0x00,0x02,0x1A,0x49,0x19,0x48,0x89,0x6B,0x1A,0x4B
+ ,0x89,0x7D,0x42,0x78,0x5B,0x5C,0x00,0x21,0x9A,0x42
+ ,0x15,0xDD,0x41,0x70,0x01,0x70,0xC2,0x78,0x01,0x21
+ ,0x00,0x2A,0x0D,0xDD,0xC2,0x78,0x04,0x2A,0x0A,0xDA
+ ,0xC2,0x78,0x01,0x3A,0xC2,0x70,0xC2,0x78,0x00,0x2A
+ ,0x04,0xD1,0x10,0x4A,0x52,0x7A,0x01,0x2A,0x00,0xD1
+ ,0xC1,0x70,0x81,0x70,0xF7,0x46,0x82,0x78,0x00,0x2A
+ ,0xFB,0xD0,0x02,0x78,0x02,0x2A,0xF8,0xDD,0x41,0x70
+ ,0x01,0x70,0xC2,0x78,0x01,0x32,0x12,0x06,0x12,0x0E
+ ,0xC2,0x70,0x03,0x2A,0xEF,0xDD,0x81,0x70,0x03,0x21
+ ,0xC1,0x70,0xF7,0x46,0x00,0x00,0xC8,0x01,0x00,0x02
+ ,0x8C,0x01,0x00,0x02,0xD6,0x01,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0x00,0xB5,0x02,0xF0,0x97,0xFE,0x02,0x49
+ ,0x8A,0x8F,0x10,0x40,0x48,0x62,0x00,0xBD,0x44,0x09
+ ,0x00,0x02,0xB0,0xB5,0x01,0x20,0x80,0x06,0x85,0x6A
+ ,0x41,0x6A,0x0E,0x48,0x00,0x88,0x84,0x02,0x20,0x1C
+ ,0x02,0xF0,0x49,0xFE,0x0F,0x1C,0x00,0x2D,0x10,0xD9
+ ,0x20,0x1C,0x29,0x1C,0x02,0xF0,0x42,0xFE,0x0D,0x1C
+ ,0x00,0x21,0xC9,0x43,0x20,0x1C,0x02,0xF0,0x3C,0xFE
+ ,0x48,0x1C,0x45,0x43,0xE9,0x19,0x20,0x1C,0x02,0xF0
+ ,0x36,0xFE,0x0F,0x1C,0x38,0x1C,0xB0,0xBD,0x00,0x00
+ ,0x80,0x00,0x00,0x02,0x90,0xB5,0x0C,0x1C,0x07,0x1C
+ ,0x00,0xF0,0x15,0xF8,0x01,0x20,0x80,0x06,0x40,0x6A
+ ,0x06,0x4B,0x20,0x18,0xB9,0x00,0xC9,0x18,0xC8,0x62
+ ,0x01,0x21,0x78,0x1E,0x81,0x40,0x03,0x48,0x82,0x69
+ ,0x11,0x43,0x81,0x61,0x90,0xBD,0x00,0x00,0x40,0x00
+ ,0x00,0x04,0x80,0x00,0x00,0x04,0x80,0xB4,0x47,0x1E
+ ,0x01,0x20,0x04,0x49,0xB8,0x40,0x8A,0x69,0xC0,0x43
+ ,0x10,0x40,0x88,0x61,0x80,0xBC,0xF7,0x46,0x00,0x00
+ ,0x80,0x00,0x00,0x04,0xF0,0xB5,0x84,0xB0,0x0F,0x20
+ ,0x00,0x06,0x00,0x88,0xE5,0x4C,0x00,0x27,0x03,0x90
+ ,0xE0,0x7C,0x00,0x28,0x04,0xD0,0x03,0x98,0x06,0xF0
+ ,0x12,0xF8,0x00,0x28,0x60,0xD1,0x03,0x98,0xE0,0x4B
+ ,0x18,0x40,0x1C,0xD0,0xDF,0x48,0x00,0x68,0x02,0x90
+ ,0x02,0x98,0x80,0x08,0x02,0xD2,0x02,0x98,0x40,0x08
+ ,0x13,0xD3,0x01,0x20,0x80,0x06,0x00,0x6B,0x02,0x99
+ ,0x40,0x00,0x40,0x08,0xC9,0x08,0x05,0xD3,0xE0,0x62
+ ,0x02,0x27,0x07,0x20,0xFF,0xF7,0xC8,0xFF,0x05,0xE0
+ ,0x20,0x63,0x01,0x27,0xFA,0x21,0x07,0x20,0xFF,0xF7
+ ,0xA7,0xFF,0x03,0x98,0xD1,0x4B,0xCE,0x49,0x18,0x40
+ ,0xCD,0x1D,0xCE,0x1D,0x49,0x36,0x09,0x35,0x00,0x28
+ ,0x58,0xD0,0xD8,0x04,0xC1,0x6B,0x01,0x91,0x01,0x99
+ ,0x89,0x09,0x0D,0xD3,0x00,0x6A,0x40,0x00,0x40,0x08
+ ,0x20,0x63,0xA0,0x7A,0x00,0x28,0x01,0xD0,0x00,0xF0
+ ,0xDA,0xFA,0xFF,0xF7,0x64,0xFC,0x01,0x27,0x01,0x22
+ ,0x62,0x73,0x01,0x98,0x12,0x23,0x18,0x40,0x40,0xD0
+ ,0x00,0x20,0x60,0x73,0xA0,0x7A,0x00,0x28,0x19,0xD0
+ ,0x01,0x98,0x80,0x08,0x0E,0xD3,0x20,0x6B,0x21,0x6E
+ ,0x40,0x18,0xE0,0x62,0xBC,0x48,0x00,0x78,0x00,0xF0
+ ,0x27,0xFB,0xE1,0x6A,0x40,0x18,0xE0,0x62,0xE0,0x6A
+ ,0x40,0x00,0x40,0x08,0xE0,0x62,0x01,0x20,0xFE,0xF7
+ ,0xD5,0xF9,0x00,0x20,0xA0,0x72,0xA0,0x75,0x0C,0xE0
+ ,0x55,0xE1,0xFF,0xF7,0x36,0xFF,0x01,0x98,0x80,0x08
+ ,0x06,0xD3,0xB1,0x49,0x20,0x6B,0x09,0x68,0x40,0x18
+ ,0x40,0x00,0x40,0x08,0xE0,0x62,0x00,0x2F,0x00,0xD1
+ ,0x02,0x27,0x01,0x98,0x40,0x09,0x02,0xD3,0x01,0x20
+ ,0xFE,0xF7,0xBB,0xF9,0xA0,0x7B,0x02,0x28,0x09,0xD1
+ ,0x00,0x20,0x68,0x73,0x30,0x71,0x00,0xF0,0x41,0xFA
+ ,0x01,0x99,0xA5,0x48,0x00,0x22,0x01,0xF0,0xF0,0xFF
+ ,0x03,0x98,0xA4,0x4B,0x18,0x40,0x73,0xD0,0x19,0x05
+ ,0xC8,0x68,0x00,0x90,0x00,0x98,0x40,0x09,0x14,0xD3
+ ,0xE0,0x7A,0x03,0x28,0x11,0xD1,0x04,0x20,0xE0,0x72
+ ,0x00,0x98,0xC9,0x68,0x08,0x43,0x9C,0x49,0x00,0x90
+ ,0x08,0x68,0x40,0x68,0x40,0x78,0xC0,0x09,0x05,0xD3
+ ,0x00,0x98,0x40,0x08,0x02,0xD2,0x98,0x49,0x00,0x20
+ ,0x48,0x71,0x00,0x98,0x80,0x08,0x3F,0xD3,0x07,0x20
+ ,0xFF,0xF7,0x39,0xFF,0xB0,0x79,0x01,0x28,0x0E,0xD1
+ ,0xE0,0x1D,0x69,0x30,0x81,0x7A,0x01,0x29,0x09,0xD1
+ ,0x02,0x21,0x81,0x72,0x90,0x48,0x01,0x8B,0xC0,0x8A
+ ,0x08,0x1A,0x81,0x02,0x04,0x20,0xFF,0xF7,0x0D,0xFF
+ ,0x60,0x7A,0x06,0x28,0x04,0xD1,0x02,0x21,0x61,0x72
+ ,0x08,0x20,0xFF,0xF7,0x1F,0xFF,0x00,0x20,0x86,0x49
+ ,0x01,0x22,0xC8,0x80,0x22,0x73,0xE0,0x72,0xA0,0x72
+ ,0xA0,0x75,0x20,0x74,0x08,0x71,0x4A,0x71,0xFE,0xF7
+ ,0xB6,0xFB,0x00,0x99,0x08,0x43,0x00,0x90,0x60,0x68
+ ,0x04,0x28,0x0F,0xD1,0x01,0x20,0xFF,0xF7,0x09,0xFF
+ ,0x20,0x7B,0x01,0x28,0x09,0xD1,0xE0,0x7A,0x00,0x28
+ ,0x06,0xD1,0xFE,0xF7,0x2B,0xFE,0x00,0x22,0x10,0x21
+ ,0x79,0x48,0x01,0xF0,0x8E,0xFF,0x00,0x98,0x80,0x09
+ ,0x60,0xD3,0x01,0x20,0x20,0x73,0x20,0x74,0x71,0x49
+ ,0x87,0x06,0xF8,0x6A,0x09,0x68,0x48,0x61,0xF8,0x6A
+ ,0x40,0x00,0x40,0x08,0xE0,0x62,0x60,0x7A,0x05,0x28
+ ,0x0C,0xD1,0xA0,0x6B,0x79,0x6A,0x88,0x42,0x00,0xE0
+ ,0xB1,0xE0,0x06,0xD2,0x02,0x21,0x6C,0x48,0x61,0x72
+ ,0x81,0x69,0x80,0x23,0x99,0x43,0x81,0x61,0x00,0x98
+ ,0xC0,0x08,0x0E,0xD3,0x64,0x48,0x01,0x21,0x01,0x71
+ ,0xC1,0x88,0x00,0x29,0x33,0xDD,0xC1,0x88,0x01,0x23
+ ,0xDB,0x03,0x99,0x42,0x2E,0xDA,0xC0,0x88,0xFF,0xF7
+ ,0x92,0xF8,0x2A,0xE0,0x5D,0x49,0x00,0x20,0x08,0x71
+ ,0xA0,0x72,0xC1,0x20,0x20,0x60,0x01,0x20,0xFE,0xF7
+ ,0x12,0xF9,0x20,0x7E,0x01,0x28,0x14,0xD1,0x61,0x7E
+ ,0x00,0x29,0x00,0xD0,0x00,0x20,0x60,0x76,0x58,0x48
+ ,0xC1,0x78,0x89,0x06,0x89,0x0E,0xC1,0x70,0x61,0x7E
+ ,0x01,0x29,0x03,0xD1,0xC1,0x78,0x40,0x23,0x19,0x43
+ ,0xC1,0x70,0xC1,0x78,0x03,0x20,0xFE,0xF7,0x84,0xF9
+ ,0x60,0x68,0x04,0x28,0x06,0xD1,0xFE,0xF7,0xCF,0xFD
+ ,0x00,0x22,0x10,0x21,0x4B,0x48,0x01,0xF0,0x32,0xFF
+ ,0x40,0x48,0x00,0x68,0x02,0x90,0x02,0x98,0xC0,0x08
+ ,0x02,0xD3,0x02,0x27,0x09,0xE0,0x30,0xE0,0x38,0x6B
+ ,0x40,0x00,0x40,0x08,0x20,0x63,0x01,0x27,0xFA,0x21
+ ,0x07,0x20,0xFF,0xF7,0x74,0xFE,0xA0,0x7E,0x00,0x28
+ ,0x22,0xD0,0x3D,0x48,0x00,0x79,0x00,0x28,0x1E,0xD0
+ ,0x20,0x7C,0x00,0x28,0x1B,0xD0,0x20,0x68,0x00,0x28
+ ,0x18,0xD1,0x06,0x20,0xFF,0xF7,0x7E,0xFE,0x00,0x20
+ ,0xE8,0x73,0xA0,0x76,0x70,0x70,0x69,0x7B,0x01,0x29
+ ,0x02,0xD0,0x69,0x7B,0x03,0x29,0x0B,0xD1,0x69,0x7B
+ ,0x01,0x29,0x07,0xD1,0xA1,0x73,0x68,0x73,0x00,0x22
+ ,0x10,0x21,0x2B,0x48,0x01,0xF0,0xFC,0xFE,0x00,0xE0
+ ,0x68,0x73,0x00,0x20,0xA0,0x76,0xE0,0x7A,0x04,0x28
+ ,0x2F,0xD1,0x20,0x7C,0x00,0x28,0x2C,0xD0,0x60,0x7B
+ ,0x00,0x28,0x02,0xD1,0x00,0x2F,0x00,0xD1,0x02,0x27
+ ,0x00,0x20,0xE0,0x72,0x23,0x4D,0x20,0x74,0x29,0x79
+ ,0x01,0x29,0x15,0xD1,0x21,0x68,0x00,0x29,0x12,0xD1
+ ,0x69,0x79,0x00,0x29,0x0F,0xD0,0x1D,0x49,0x09,0x68
+ ,0x48,0x72,0xA9,0x68,0xE9,0x60,0x28,0x70,0xFE,0xF7
+ ,0x17,0xFA,0x28,0x78,0x01,0x28,0x04,0xD1,0x00,0x22
+ ,0x01,0x21,0x19,0x48,0x01,0xF0,0xCF,0xFE,0x60,0x68
+ ,0x04,0x28,0x06,0xD1,0xFE,0xF7,0x62,0xFD,0x00,0x22
+ ,0x10,0x21,0x14,0x48,0x01,0xF0,0xC5,0xFE,0x01,0x2F
+ ,0x02,0xD1,0x00,0xF0,0x19,0xF9,0x03,0xE0,0x02,0x2F
+ ,0x01,0xD1,0x00,0xF0,0x44,0xF9,0x03,0x98,0x11,0x4B
+ ,0x18,0x40,0x01,0xD0,0x01,0xF0,0xE0,0xF8,0x04,0xB0
+ ,0xF0,0xBD,0x44,0x09,0x00,0x02,0x20,0x20,0x00,0x00
+ ,0x40,0x00,0x00,0x04,0x80,0x80,0x00,0x00,0x93,0x01
+ ,0x00,0x02,0x8C,0x01,0x00,0x02,0xD8,0x06,0x00,0x02
+ ,0x40,0x40,0x00,0x00,0x48,0x01,0x00,0x02,0xDC,0x01
+ ,0x00,0x02,0xC0,0x00,0x00,0x02,0x38,0x07,0x00,0x02
+ ,0x80,0x00,0x00,0x04,0xCC,0x07,0x00,0x02,0x08,0x08
+ ,0x00,0x00,0xF0,0xB5,0x0F,0x20,0x00,0x06,0x05,0x89
+ ,0x63,0x48,0x64,0x4E,0x28,0x40,0x01,0x24,0x00,0x28
+ ,0x6E,0xD0,0x62,0x49,0xCF,0x69,0x78,0x08,0x3E,0xD3
+ ,0x88,0x69,0x40,0x08,0x3B,0xD3,0x88,0x69,0xA0,0x43
+ ,0x88,0x61,0x5E,0x48,0x41,0x68,0x04,0x29,0x0A,0xD1
+ ,0xFE,0xF7,0x14,0xFD,0x01,0x20,0xFE,0xF7,0x37,0xF8
+ ,0x00,0x22,0x10,0x21,0x5A,0x48,0x01,0xF0,0x74,0xFE
+ ,0x29,0xE0,0x42,0x68,0x58,0x49,0x02,0x2A,0x05,0xD1
+ ,0x09,0x68,0x4C,0x73,0x57,0x49,0x09,0x68,0x4C,0x70
+ ,0x05,0xE0,0x42,0x68,0x03,0x2A,0x02,0xD1,0x09,0x68
+ ,0x02,0x22,0x4A,0x73,0x4F,0x48,0x44,0x60,0x00,0xF0
+ ,0xAB,0xF8,0x01,0x20,0xFE,0xF7,0x1A,0xF8,0x4B,0x48
+ ,0x40,0x7C,0x01,0x28,0x05,0xD1,0x00,0x22,0x10,0x21
+ ,0x30,0x1C,0x01,0xF0,0x53,0xFE,0x08,0xE0,0x46,0x48
+ ,0x40,0x7C,0x02,0x28,0x04,0xD1,0x00,0x22,0x10,0x21
+ ,0x47,0x48,0x01,0xF0,0x49,0xFE,0x41,0x48,0x80,0x69
+ ,0xC0,0x09,0x03,0xD3,0xF8,0x09,0x01,0xD3,0x07,0xF0
+ ,0x0F,0xFB,0x3D,0x48,0x80,0x69,0x00,0x0A,0x32,0xD3
+ ,0x38,0x0A,0x30,0xD3,0x3A,0x48,0x80,0x23,0x81,0x69
+ ,0x99,0x43,0x81,0x61,0x38,0x48,0x41,0x7A,0x05,0x29
+ ,0x02,0xD0,0x41,0x7A,0x06,0x29,0x15,0xD1,0x00,0x21
+ ,0x81,0x63,0x01,0x7A,0x01,0x29,0x0D,0xD1,0x44,0x72
+ ,0x81,0x7A,0x00,0x29,0x1B,0xD1,0x01,0x7B,0x01,0x29
+ ,0x18,0xD1,0xC0,0x7A,0x00,0x28,0x15,0xD1,0xFF,0xF7
+ ,0xCC,0xF9,0x12,0xE0,0x3A,0xE0,0x02,0x22,0x42,0x72
+ ,0x0E,0xE0,0x44,0x72,0x41,0x7F,0x01,0x29,0x02,0xD1
+ ,0x00,0x21,0x81,0x62,0x01,0xE0,0x00,0x21,0x41,0x62
+ ,0x80,0x7B,0x03,0x28,0x02,0xD1,0x00,0x20,0xFF,0xF7
+ ,0x38,0xFB,0x38,0x09,0x05,0xD3,0x20,0x48,0x80,0x69
+ ,0x00,0x09,0x01,0xD3,0x04,0xF0,0x4E,0xFA,0xB8,0x08
+ ,0x16,0xD3,0x1C,0x48,0x81,0x69,0x89,0x08,0x12,0xD3
+ ,0x81,0x69,0x02,0x23,0x99,0x43,0x81,0x61,0x19,0x48
+ ,0xC1,0x1D,0x49,0x31,0x89,0x79,0x05,0x29,0x08,0xD1
+ ,0x1B,0x49,0x49,0x79,0x03,0x29,0x04,0xD1,0x70,0x30
+ ,0x81,0x78,0x08,0x23,0x19,0x43,0x81,0x70,0xB8,0x09
+ ,0x05,0xD3,0x10,0x48,0x80,0x69,0x80,0x09,0x01,0xD3
+ ,0x07,0xF0,0x57,0xFA,0x14,0x48,0x28,0x40,0x06,0xD0
+ ,0x13,0x48,0x00,0x21,0x04,0x70,0x79,0x20,0x40,0x05
+ ,0x01,0x83,0x81,0x82,0xFF,0x20,0x02,0x30,0x28,0x40
+ ,0x06,0xD0,0x07,0xF0,0x8B,0xFA,0x00,0x22,0x10,0x21
+ ,0x30,0x1C,0x01,0xF0,0xCC,0xFD,0xF0,0xBD,0x00,0x00
+ ,0x10,0x10,0x00,0x00,0xD8,0x06,0x00,0x02,0x80,0x00
+ ,0x00,0x04,0x44,0x09,0x00,0x02,0x38,0x07,0x00,0x02
+ ,0xC4,0x01,0x00,0x02,0xD0,0x01,0x00,0x02,0xF8,0x06
+ ,0x00,0x02,0xB0,0x00,0x00,0x02,0x02,0x02,0x00,0x00
+ ,0xD4,0x01,0x00,0x02,0x04,0x48,0x01,0x21,0x81,0x73
+ ,0x00,0x21,0xC1,0x75,0xC1,0x73,0xC1,0x76,0x01,0x77
+ ,0xF7,0x46,0x00,0x00,0x44,0x09,0x00,0x02,0x80,0xB5
+ ,0x16,0x4F,0x00,0x20,0x38,0x72,0x79,0x7A,0x02,0x20
+ ,0x01,0x29,0x1C,0xD0,0x04,0x29,0x19,0xD1,0x78,0x72
+ ,0x08,0x20,0xFF,0xF7,0x08,0xFD,0x38,0x6B,0xF9,0x6A
+ ,0x40,0x1A,0x40,0x00,0x39,0x6A,0x40,0x08,0x81,0x42
+ ,0x0D,0xD2,0x39,0x6A,0x41,0x1A,0x14,0x20,0x02,0xF0
+ ,0x11,0xFB,0x79,0x7F,0x01,0x29,0x08,0xD1,0xB9,0x6A
+ ,0x81,0x42,0x02,0xD3,0xB9,0x6A,0x08,0x1A,0xB8,0x62
+ ,0x80,0xBD,0x78,0x72,0x80,0xBD,0x79,0x6A,0x81,0x42
+ ,0xF9,0xD3,0x79,0x6A,0x08,0x1A,0x78,0x62,0x80,0xBD
+ ,0x44,0x09,0x00,0x02,0x00,0xB5,0x0A,0x48,0x01,0x21
+ ,0x01,0x72,0x01,0x7B,0x01,0x29,0x0D,0xD1,0xC1,0x7A
+ ,0x00,0x29,0x0A,0xD1,0x81,0x7A,0x00,0x29,0x07,0xD1
+ ,0x41,0x7A,0x06,0x29,0x04,0xD0,0x40,0x7A,0x05,0x28
+ ,0x01,0xD0,0xFF,0xF7,0x11,0xF9,0x00,0xBD,0x44,0x09
+ ,0x00,0x02,0xB0,0xB5,0x20,0x4F,0x20,0x48,0x79,0x7D
+ ,0x80,0x7A,0x20,0x4C,0x81,0x42,0x02,0xDA,0x78,0x7D
+ ,0x20,0x70,0x00,0xE0,0x20,0x70,0xFF,0xF7,0x18,0xFC
+ ,0x20,0x78,0x03,0x28,0x03,0xD1,0x01,0x20,0xFD,0xF7
+ ,0x4C,0xFF,0x02,0xE0,0x00,0x20,0xFD,0xF7,0x48,0xFF
+ ,0xB8,0x7A,0x17,0x4D,0x02,0x28,0x02,0xD1,0xC4,0x20
+ ,0x28,0x70,0x04,0xE0,0xB8,0x7A,0x01,0x28,0x01,0xD1
+ ,0xD4,0x20,0x28,0x70,0x00,0x20,0x68,0x70,0x69,0x88
+ ,0x11,0x48,0x00,0x29,0x07,0xD0,0x23,0x78,0x10,0x4A
+ ,0x5B,0x00,0xC3,0x5A,0xD2,0x88,0xD2,0x18,0x89,0x1A
+ ,0x69,0x80,0x0A,0x21,0xF9,0x65,0x21,0x78,0x49,0x00
+ ,0x40,0x5A,0x38,0x66,0x20,0x78,0x00,0xF0,0x2B,0xF8
+ ,0x39,0x6E,0x08,0x1A,0x38,0x66,0xBD,0x65,0x01,0x20
+ ,0xB8,0x75,0xB0,0xBD,0x44,0x09,0x00,0x02,0x04,0x01
+ ,0x00,0x02,0x93,0x01,0x00,0x02,0x2C,0x09,0x00,0x02
+ ,0xB0,0x01,0x00,0x02,0x00,0x00,0x00,0x02,0xB0,0xB4
+ ,0x0A,0x4B,0x00,0x24,0x99,0x42,0x01,0xD8,0x00,0x29
+ ,0x02,0xD1,0x20,0x1C,0xB0,0xBC,0xF7,0x46,0x01,0x27
+ ,0xBF,0x06,0x3D,0x69,0xAB,0x08,0x01,0xD3,0x20,0x1C
+ ,0xF6,0xE7,0x03,0xC7,0x08,0x3F,0x3A,0x61,0x01,0x20
+ ,0xF1,0xE7,0x0E,0x06,0x00,0x00,0x00,0x28,0x01,0xD1
+ ,0xC0,0x20,0xF7,0x46,0x01,0x48,0x00,0x88,0xF7,0x46
+ ,0x00,0x00,0xAC,0x01,0x00,0x02,0xF8,0xB5,0x3D,0x48
+ ,0x00,0x90,0x3D,0x48,0xC4,0x1D,0x49,0x34,0xC7,0x1D
+ ,0x09,0x37,0x3B,0x4D,0x3C,0x4E,0x00,0xF0,0xFA,0xFC
+ ,0x00,0xF0,0xEA,0xF8,0x30,0x78,0x00,0x28,0x04,0xD1
+ ,0xA0,0x79,0x05,0x28,0x01,0xD0,0x06,0xF0,0xEE,0xFC
+ ,0x28,0x78,0x00,0x28,0xF0,0xD0,0xB8,0x7B,0x00,0x28
+ ,0xED,0xD1,0x33,0x48,0x01,0x78,0x01,0x29,0x03,0xD1
+ ,0x00,0x21,0x01,0x70,0x04,0xF0,0xE0,0xF9,0x30,0x48
+ ,0x00,0x78,0x02,0x28,0x46,0xD0,0x2F,0x48,0x00,0x78
+ ,0x02,0x28,0x01,0xD1,0x06,0xF0,0x0C,0xFD,0x06,0xF0
+ ,0x2E,0xFE,0x28,0x4E,0x05,0x1C,0x30,0x78,0x01,0x28
+ ,0x09,0xD1,0x03,0x03,0x9D,0x42,0x03,0xD1,0x28,0x49
+ ,0x10,0x20,0x09,0x68,0x08,0x73,0x00,0x21,0xB9,0x73
+ ,0xC8,0xE7,0x00,0x2D,0x23,0xD0,0x01,0x23,0x1B,0x03
+ ,0x9D,0x42,0x08,0xD0,0x23,0x48,0x80,0x21,0x02,0x68
+ ,0x11,0x70,0x02,0x68,0x00,0x21,0x51,0x70,0x00,0x68
+ ,0x81,0x70,0xA0,0x79,0x05,0x28,0x0D,0xD1,0x00,0x98
+ ,0x40,0x79,0x01,0x28,0x09,0xDD,0xC0,0x20,0x01,0xF0
+ ,0xF4,0xFD,0x06,0x1C,0x28,0x1C,0x06,0xF0,0x0A,0xFD
+ ,0x30,0x1C,0x01,0xF0,0xED,0xFD,0x29,0x1C,0x00,0x22
+ ,0x16,0x48,0x01,0xF0,0x8C,0xFC,0xA2,0xE7,0x00,0x98
+ ,0x40,0x79,0x01,0x28,0x9E,0xDD,0xA0,0x79,0x05,0x28
+ ,0x9B,0xD1,0x00,0xF0,0x22,0xF8,0x98,0xE7,0x06,0xF0
+ ,0xED,0xFD,0x01,0x23,0x1B,0x03,0x98,0x42,0x03,0xD1
+ ,0x0A,0x49,0x10,0x20,0x09,0x68,0x08,0x73,0x00,0x21
+ ,0xB9,0x73,0x8B,0xE7,0xB0,0x00,0x00,0x02,0x44,0x09
+ ,0x00,0x02,0x5E,0x02,0x00,0x02,0xB3,0x02,0x00,0x02
+ ,0xD5,0x01,0x00,0x02,0x53,0x02,0x00,0x02,0x3C,0x01
+ ,0x00,0x02,0xC4,0x01,0x00,0x02,0xD0,0x01,0x00,0x02
+ ,0x18,0x07,0x00,0x02,0x80,0xB5,0xC0,0x20,0x01,0xF0
+ ,0xB8,0xFD,0x07,0x1C,0x0D,0x48,0x81,0x78,0x49,0x08
+ ,0x89,0x07,0x11,0xD1,0x81,0x78,0x09,0x09,0x0E,0xD3
+ ,0x0A,0x49,0x09,0x68,0x09,0x7B,0x09,0x0A,0x09,0xD2
+ ,0xC1,0x78,0x00,0x29,0x04,0xD0,0x00,0x21,0xC1,0x70
+ ,0x01,0x21,0x81,0x71,0x01,0xE0,0x06,0xF0,0xE8,0xFC
+ ,0x38,0x1C,0x01,0xF0,0x9D,0xFD,0x80,0xBD,0xB4,0x09
+ ,0x00,0x02,0xC4,0x01,0x00,0x02,0xB0,0xB5,0x1C,0x4C
+ ,0x01,0x20,0x1C,0x4D,0xA0,0x77,0x28,0x68,0x00,0xF0
+ ,0xBE,0xFE,0x29,0x68,0x00,0x20,0x4F,0x68,0x88,0x73
+ ,0x18,0x49,0x8A,0x78,0x00,0x2A,0x00,0xD1,0x48,0x70
+ ,0x38,0x78,0x08,0x28,0x19,0xD1,0x20,0x7D,0x01,0x28
+ ,0x06,0xD1,0x06,0x22,0xF8,0x1D,0x09,0x30,0x12,0x49
+ ,0x02,0xF0,0x5F,0xF9,0x0F,0xE0,0x20,0x7D,0x02,0x28
+ ,0x0C,0xD1,0x10,0x48,0x40,0x79,0x02,0x28,0x08,0xD1
+ ,0xE0,0x1D,0x49,0x30,0x80,0x79,0x05,0x28,0x03,0xD1
+ ,0x78,0x78,0x10,0x23,0x18,0x43,0x78,0x70,0xF8,0x1D
+ ,0x0F,0x30,0xFD,0xF7,0x22,0xFF,0x38,0x1C,0x06,0xF0
+ ,0x27,0xFA,0x29,0x68,0x80,0x20,0x08,0x73,0x40,0x01
+ ,0xB0,0xBD,0x44,0x09,0x00,0x02,0xC4,0x01,0x00,0x02
+ ,0xC8,0x01,0x00,0x02,0xFC,0x00,0x00,0x02,0xB0,0x00
+ ,0x00,0x02,0x00,0xB5,0x05,0x48,0x01,0x78,0x00,0x29
+ ,0x04,0xD0,0x40,0x78,0x00,0x28,0x01,0xD1,0x04,0xF0
+ ,0xD6,0xF8,0x00,0xBD,0x00,0x00,0xC4,0x09,0x00,0x02
+ ,0xF0,0xB5,0x2E,0x48,0x47,0x6E,0xFD,0xF7,0x9F,0xFD
+ ,0x01,0x02,0x2C,0x4C,0x09,0x0A,0x2C,0x48,0x21,0x60
+ ,0x43,0x78,0x2C,0x4A,0x13,0x70,0x15,0x78,0x0D,0x23
+ ,0x6B,0x43,0x1B,0x18,0x1B,0x7B,0x1B,0x06,0x0B,0x43
+ ,0x03,0x21,0x49,0x06,0x0B,0x60,0x15,0x78,0x0D,0x23
+ ,0x6B,0x43,0x1B,0x18,0x9E,0x7B,0x5D,0x7B,0x36,0x02
+ ,0x35,0x43,0xDE,0x7B,0x1B,0x7C,0x36,0x04,0x35,0x43
+ ,0x1B,0x06,0x2B,0x43,0x4B,0x60,0xC3,0x1D,0x39,0x33
+ ,0x1B,0x78,0x02,0x2B,0x1D,0xD1,0x15,0x78,0x0D,0x23
+ ,0x6B,0x43,0x1B,0x18,0x9E,0x7C,0x5D,0x7C,0x36,0x02
+ ,0x35,0x43,0xDE,0x7C,0x1B,0x7D,0x36,0x04,0x35,0x43
+ ,0x1B,0x06,0x2B,0x43,0x4B,0x61,0x15,0x78,0x0D,0x23
+ ,0x6B,0x43,0x18,0x18,0x85,0x7D,0x43,0x7D,0x2D,0x02
+ ,0x2B,0x43,0xC5,0x7D,0x00,0x7E,0x2D,0x04,0x2B,0x43
+ ,0x00,0x06,0x18,0x43,0x88,0x61,0x10,0x78,0x21,0x68
+ ,0x0D,0x4A,0x80,0x07,0x01,0x43,0x21,0x60,0x00,0x20
+ ,0x3B,0x5C,0x13,0x54,0x01,0x30,0x18,0x28,0xFA,0xD3
+ ,0x11,0x76,0x08,0x0A,0x50,0x76,0x08,0x0C,0x90,0x76
+ ,0x08,0x0E,0xD0,0x76,0xF0,0xBD,0x00,0x00,0x44,0x09
+ ,0x00,0x02,0xEC,0x01,0x00,0x02,0x18,0x00,0x00,0x02
+ ,0x90,0x01,0x00,0x02,0x58,0x07,0x00,0x02,0x80,0xB4
+ ,0x11,0x4A,0x11,0x88,0x01,0x31,0x09,0x04,0x09,0x0C
+ ,0x1E,0x29,0x00,0xD1,0x00,0x21,0x0E,0x4F,0x0E,0x4B
+ ,0x4F,0x43,0xFB,0x18,0x1F,0x7B,0x00,0x2F,0x11,0xD1
+ ,0x11,0x80,0x0C,0x49,0x03,0x22,0x19,0x60,0xD9,0x1D
+ ,0x15,0x31,0x59,0x60,0x08,0x39,0x99,0x60,0x00,0x21
+ ,0x19,0x73,0x99,0x73,0x9A,0x75,0x99,0x82,0x03,0x60
+ ,0x40,0x21,0x01,0x73,0x18,0x1C,0x80,0xBC,0xF7,0x46
+ ,0xF0,0x01,0x00,0x02,0xA4,0x06,0x00,0x00,0x00,0x11
+ ,0x00,0x02,0x00,0x00,0x00,0x80,0x80,0xB4,0x13,0x4A
+ ,0x51,0x88,0x01,0x31,0x09,0x04,0x09,0x0C,0x14,0x29
+ ,0x00,0xD1,0x00,0x21,0x10,0x4F,0x10,0x4B,0x4F,0x43
+ ,0xFB,0x18,0x1F,0x7A,0x00,0x2F,0x15,0xD1,0x51,0x80
+ ,0x0E,0x49,0x01,0x22,0x19,0x60,0xD9,0x1D,0x11,0x31
+ ,0x59,0x60,0x9A,0x81,0x00,0x21,0x19,0x72,0x0A,0x4F
+ ,0xD9,0x73,0xBF,0x79,0x01,0x2F,0x01,0xD1,0xC2,0x73
+ ,0x00,0xE0,0xC1,0x73,0x80,0x21,0x03,0x60,0x01,0x72
+ ,0x18,0x1C,0x80,0xBC,0xF7,0x46,0xF0,0x01,0x00,0x02
+ ,0xA4,0x06,0x00,0x00,0x00,0xDA,0x00,0x02,0x00,0x00
+ ,0x00,0x80,0xB0,0x00,0x00,0x02,0x01,0x1C,0x00,0x68
+ ,0x02,0x08,0x01,0xD3,0x08,0x1C,0xF7,0x46,0x00,0x22
+ ,0x0A,0x73,0xF7,0x46,0x01,0x68,0x09,0x08,0x02,0xD3
+ ,0x40,0x21,0x01,0x72,0xF7,0x46,0x04,0x4A,0x01,0x68
+ ,0x12,0x78,0x00,0x2A,0xF9,0xD1,0x02,0x72,0x08,0x1C
+ ,0xF7,0x46,0x00,0x00,0x4B,0x02,0x00,0x02,0x0A,0x49
+ ,0x01,0x20,0x48,0x63,0x00,0x20,0xCA,0x1D,0x39,0x32
+ ,0x88,0x63,0x50,0x83,0x10,0x83,0x08,0x65,0xCB,0x1D
+ ,0x49,0x33,0x90,0x82,0x18,0x73,0x98,0x71,0x58,0x73
+ ,0x90,0x81,0xD0,0x81,0x60,0x31,0xC8,0x72,0xF7,0x46
+ ,0x00,0x00,0xF4,0x01,0x00,0x02,0x80,0xB5,0x07,0x27
+ ,0x7F,0x06,0xF8,0x69,0x40,0x23,0x18,0x43,0xF8,0x61
+ ,0x14,0x48,0xFD,0xF7,0x8E,0xFC,0xF8,0x69,0x20,0x23
+ ,0x18,0x43,0xF8,0x61,0xF8,0x69,0x1B,0x01,0x18,0x43
+ ,0xF8,0x61,0x00,0x20,0xFF,0x21,0x91,0x31,0x01,0x30
+ ,0x88,0x42,0xFC,0xD3,0xF8,0x69,0x0C,0x4B,0x18,0x40
+ ,0xF8,0x61,0x00,0x20,0x7D,0x21,0x49,0x01,0x01,0x30
+ ,0x88,0x42,0xFC,0xD3,0xFF,0xF7,0xC4,0xFF,0xFD,0xF7
+ ,0x7A,0xFC,0x00,0xF0,0x0E,0xF8,0x05,0x49,0x0D,0x20
+ ,0x00,0x06,0x01,0x81,0xFF,0x21,0x41,0x31,0x81,0x80
+ ,0x80,0xBD,0x50,0xC3,0x00,0x00,0xFF,0xFD,0x00,0x00
+ ,0xFF,0x0F,0x00,0x00,0x90,0xB4,0x0E,0x48,0x00,0x21
+ ,0x01,0x70,0x0D,0x48,0x80,0x27,0x07,0x73,0x01,0x23
+ ,0x03,0x72,0x82,0x22,0x02,0x71,0x07,0x22,0x02,0x70
+ ,0x0A,0x48,0x05,0x24,0x04,0x73,0x86,0x24,0x04,0x72
+ ,0x02,0x71,0x08,0x48,0x24,0x22,0x02,0x71,0x07,0x72
+ ,0x03,0x73,0x06,0x48,0x01,0x71,0x01,0x73,0x90,0xBC
+ ,0xF7,0x46,0x00,0x00,0x10,0x00,0x00,0x0D,0xB0,0x03
+ ,0x00,0x0D,0xA0,0x03,0x00,0x0D,0xC0,0x03,0x00,0x0D
+ ,0xE0,0x03,0x00,0x0D,0xF0,0xB5,0x25,0x48,0x01,0x27
+ ,0x00,0x7B,0x24,0x4C,0x0A,0x28,0x1F,0xD1,0x24,0x49
+ ,0x24,0x4E,0x00,0x20,0x0B,0x7B,0x02,0x1C,0x01,0x30
+ ,0x08,0x28,0xB3,0x54,0xF9,0xD1,0xF1,0x78,0xB0,0x78
+ ,0xF2,0x79,0x09,0x02,0x08,0x43,0x05,0x1C,0x71,0x79
+ ,0x30,0x79,0x09,0x02,0x01,0x43,0xB0,0x79,0x12,0x02
+ ,0x02,0x43,0x30,0x78,0x73,0x78,0x00,0x02,0x18,0x43
+ ,0x05,0x28,0x08,0xD1,0x28,0x1C,0x00,0xF0,0x7E,0xFB
+ ,0x21,0xE0,0x16,0x49,0x00,0x20,0x08,0x73,0x27,0x71
+ ,0xF0,0xBD,0x09,0x28,0x03,0xD1,0x28,0x1C,0x00,0xF0
+ ,0x97,0xFB,0x16,0xE0,0x11,0x4B,0x98,0x42,0x04,0xD1
+ ,0xF1,0x78,0x10,0x1C,0x00,0xF0,0xC7,0xFB,0x0E,0xE0
+ ,0x0E,0x4B,0x9B,0x7A,0x00,0x2B,0x05,0xD1,0x13,0x1C
+ ,0x0A,0x1C,0x29,0x1C,0x00,0xF0,0x17,0xF8,0x04,0xE0
+ ,0x13,0x1C,0x0A,0x1C,0x29,0x1C,0x04,0xF0,0x89,0xFC
+ ,0x27,0x71,0xF0,0xBD,0x00,0x00,0xF0,0x02,0x00,0x0D
+ ,0xD0,0x03,0x00,0x0D,0x30,0x03,0x00,0x0D,0x30,0x02
+ ,0x00,0x02,0x70,0x03,0x00,0x0D,0x06,0x80,0x00,0x00
+ ,0x54,0x02,0x00,0x02,0x80,0xB5,0x0F,0x1C,0x11,0x1C
+ ,0x1A,0x1C,0x08,0x4B,0x98,0x42,0x03,0xD1,0x38,0x1C
+ ,0x00,0xF0,0x12,0xF8,0x80,0xBD,0x06,0x4B,0x98,0x42
+ ,0x03,0xD1,0x38,0x1C,0x00,0xF0,0x2B,0xF8,0x80,0xBD
+ ,0x03,0x49,0x20,0x20,0x08,0x73,0x80,0xBD,0x33,0xC1
+ ,0x00,0x00,0x0E,0x40,0x00,0x00,0x70,0x03,0x00,0x0D
+ ,0x0B,0x49,0x0C,0x48,0x4A,0x6B,0x03,0x2A,0x03,0xD1
+ ,0x0B,0x4A,0x92,0x78,0x01,0x2A,0x02,0xD0,0x20,0x21
+ ,0x01,0x73,0xF7,0x46,0x80,0x22,0x02,0x73,0x50,0x31
+ ,0xC9,0x7B,0x06,0x4A,0x10,0x23,0x11,0x73,0x01,0x7B
+ ,0x19,0x43,0x01,0x73,0xF7,0x46,0x00,0x00,0xF4,0x01
+ ,0x00,0x02,0x70,0x03,0x00,0x0D,0x30,0x02,0x00,0x02
+ ,0x30,0x03,0x00,0x0D,0xF0,0xB5,0x13,0x4D,0x17,0x1C
+ ,0xA8,0x78,0x12,0x4A,0x02,0x28,0x06,0xD1,0xE8,0x78
+ ,0x08,0x28,0x03,0xD1,0x10,0x48,0x43,0x6B,0x03,0x2B
+ ,0x02,0xD0,0x20,0x20,0x10,0x73,0xF0,0xBD,0x00,0x26
+ ,0x00,0x2F,0x0D,0x4C,0x04,0xD1,0x00,0xF0,0x03,0xFC
+ ,0x01,0x20,0xA0,0x72,0x04,0xE0,0x00,0x29,0x01,0xD1
+ ,0x09,0x49,0x41,0x66,0x16,0x73,0x27,0x80,0x29,0x1C
+ ,0x08,0x22,0x66,0x80,0x07,0x48,0x01,0xF0,0x18,0xFF
+ ,0x26,0x73,0xF0,0xBD,0x30,0x02,0x00,0x02,0x70,0x03
+ ,0x00,0x0D,0xF4,0x01,0x00,0x02,0x54,0x02,0x00,0x02
+ ,0x00,0x60,0x00,0x01,0x38,0x02,0x00,0x02,0x90,0xB5
+ ,0x17,0x49,0x08,0x78,0x4A,0x78,0x00,0x02,0x10,0x43
+ ,0x05,0x28,0x15,0x4A,0x04,0xD1,0x89,0x78,0x50,0x6B
+ ,0x00,0xF0,0x59,0xFB,0x90,0xBD,0x13,0x4B,0x01,0x27
+ ,0x98,0x42,0x11,0x4C,0x04,0xD1,0xC8,0x78,0x00,0xF0
+ ,0x28,0xFA,0x27,0x71,0x90,0xBD,0x09,0x28,0x0A,0xD1
+ ,0x0E,0x49,0x20,0x20,0x08,0x73,0x27,0x71,0x50,0x6B
+ ,0x03,0x28,0xEB,0xD1,0xD0,0x1D,0x49,0x30,0x47,0x73
+ ,0x90,0xBD,0xD1,0x1D,0x59,0x31,0x89,0x7A,0x00,0x29
+ ,0x02,0xD1,0x00,0xF0,0x0E,0xF8,0x90,0xBD,0x04,0xF0
+ ,0x19,0xFC,0x90,0xBD,0x30,0x02,0x00,0x02,0xF4,0x01
+ ,0x00,0x02,0xD0,0x03,0x00,0x0D,0x06,0x80,0x00,0x00
+ ,0x70,0x03,0x00,0x0D,0x08,0x4B,0x07,0x49,0x98,0x42
+ ,0x02,0xD1,0xE0,0x20,0x08,0x73,0x04,0xE0,0x06,0x4B
+ ,0x98,0x42,0x01,0xD1,0x20,0x20,0x08,0x73,0x04,0x49
+ ,0x01,0x20,0x08,0x71,0xF7,0x46,0x70,0x03,0x00,0x0D
+ ,0x33,0xC1,0x00,0x00,0x0E,0x40,0x00,0x00,0xD0,0x03
+ ,0x00,0x0D,0x80,0xB5,0x11,0x48,0x11,0x4B,0x01,0x78
+ ,0x42,0x78,0x09,0x02,0x11,0x43,0x0F,0x1C,0x9F,0x42
+ ,0x03,0xD1,0x80,0x78,0x00,0xF0,0x2D,0xFA,0x05,0xE0
+ ,0x0C,0x49,0xE0,0x20,0x08,0x73,0x0C,0x49,0x01,0x20
+ ,0x08,0x71,0x0B,0x4B,0x9F,0x42,0x0B,0xD1,0x0B,0x48
+ ,0x01,0x7B,0x02,0x29,0x07,0xD1,0x03,0x21,0x01,0x73
+ ,0x09,0x48,0x00,0x22,0xC1,0x78,0x80,0x78,0x04,0xF0
+ ,0xF5,0xF8,0x80,0xBD,0x30,0x02,0x00,0x02,0x0E,0x40
+ ,0x00,0x00,0x70,0x03,0x00,0x0D,0xD0,0x03,0x00,0x0D
+ ,0x22,0xC1,0x00,0x00,0x54,0x02,0x00,0x02,0x38,0x02
+ ,0x00,0x02,0x00,0xB5,0x0C,0x49,0x08,0x7B,0x02,0x09
+ ,0x05,0xD3,0x00,0x20,0x08,0x73,0x0A,0x49,0x01,0x20
+ ,0x08,0x71,0x00,0xBD,0xC1,0x08,0x02,0xD3,0xFF,0xF7
+ ,0xA3,0xFE,0x00,0xBD,0x41,0x08,0x02,0xD3,0xFF,0xF7
+ ,0x68,0xFF,0x00,0xBD,0x80,0x08,0xF2,0xD3,0xFF,0xF7
+ ,0xB5,0xFF,0x00,0xBD,0x70,0x03,0x00,0x0D,0xD0,0x03
+ ,0x00,0x0D,0xF0,0xB5,0x47,0x4E,0x30,0x79,0x80,0x08
+ ,0x4A,0xD3,0x46,0x4D,0x68,0x79,0x01,0x28,0x01,0xDD
+ ,0x00,0xF0,0x57,0xFE,0x44,0x48,0x04,0x79,0xC0,0x20
+ ,0x01,0xF0,0x74,0xFA,0x01,0x1C,0x42,0x48,0x04,0x22
+ ,0x02,0x71,0x00,0x22,0x02,0x71,0x08,0x1C,0x01,0xF0
+ ,0x6B,0xFA,0x3F,0x48,0xC7,0x1D,0x39,0x37,0x39,0x8B
+ ,0x40,0x29,0x07,0xDA,0x39,0x8B,0x00,0x29,0x04,0xD0
+ ,0x39,0x8B,0x02,0x31,0x09,0x04,0x09,0x0C,0x07,0xE0
+ ,0x40,0x2C,0x04,0xDA,0x39,0x8B,0x00,0x29,0x01,0xD1
+ ,0x21,0x1C,0x00,0xE0,0x40,0x21,0x7A,0x8B,0x34,0x4C
+ ,0x52,0x18,0x19,0x23,0x9B,0x01,0x9A,0x42,0x04,0xD9
+ ,0x00,0x22,0x7A,0x83,0x3A,0x83,0x01,0x22,0xA2,0x73
+ ,0x2E,0x48,0x40,0x6F,0x80,0x68,0x7A,0x8B,0x80,0x18
+ ,0xCD,0x22,0x00,0xF0,0xA7,0xFA,0x00,0x20,0x30,0x71
+ ,0x68,0x79,0x01,0x28,0x01,0xDD,0x00,0xF0,0x04,0xFE
+ ,0xA1,0x7B,0x26,0x48,0x01,0x29,0x02,0xD1,0x00,0x20
+ ,0xA0,0x73,0xF0,0xBD,0x04,0x1C,0x78,0x8B,0x00,0x28
+ ,0x28,0xD1,0x60,0x6F,0x81,0x8A,0xC0,0x7D,0x08,0x31
+ ,0x08,0x18,0x38,0x83,0x60,0x6F,0x81,0x7D,0x45,0x68
+ ,0x03,0x29,0x01,0xDD,0x03,0x21,0x81,0x75,0x38,0x8B
+ ,0x1C,0x4B,0x98,0x42,0x13,0xD8,0x38,0x8B,0x00,0x28
+ ,0x10,0xD0,0xE8,0x1D,0x03,0x30,0x06,0x22,0x18,0x49
+ ,0x01,0xF0,0xDB,0xFD,0x00,0x28,0x08,0xD1,0x28,0x78
+ ,0x08,0x28,0x09,0xD0,0x00,0x28,0x07,0xD0,0x20,0x28
+ ,0x05,0xD0,0xB0,0x28,0x03,0xD0,0x00,0x20,0x78,0x83
+ ,0x38,0x83,0xF0,0xBD,0x38,0x8B,0x40,0x28,0x06,0xDD
+ ,0x38,0x8B,0x40,0x38,0x38,0x83,0x78,0x8B,0x40,0x30
+ ,0x78,0x83,0xF0,0xBD,0x00,0x20,0x38,0x83,0x78,0x83
+ ,0x60,0x6F,0xFF,0xF7,0x18,0xFD,0x60,0x67,0xF0,0xBD
+ ,0x70,0x03,0x00,0x0D,0xB0,0x00,0x00,0x02,0xF0,0x02
+ ,0x00,0x0D,0x60,0x02,0x00,0x0D,0xF4,0x01,0x00,0x02
+ ,0x54,0x02,0x00,0x02,0x32,0x06,0x00,0x00,0x5C,0x00
+ ,0x00,0x02,0x90,0xB5,0x1C,0x4F,0x38,0x7A,0x40,0x08
+ ,0x1D,0xD3,0x1B,0x48,0x40,0x79,0x01,0x28,0x01,0xDD
+ ,0x00,0xF0,0xB7,0xFD,0x00,0x20,0x18,0x4B,0x38,0x72
+ ,0x3A,0x1C,0xDF,0x1D,0x49,0x37,0xBC,0x79,0xD9,0x1D
+ ,0x39,0x31,0x01,0x2C,0x15,0xD1,0xB8,0x71,0xFB,0x79
+ ,0x00,0x2B,0x01,0xD1,0x10,0x23,0x13,0x72,0x89,0x8A
+ ,0x01,0x24,0x00,0x29,0x03,0xD0,0x00,0xF0,0x1E,0xF8
+ ,0xBC,0x71,0x90,0xBD,0x39,0x7B,0x01,0x29,0x02,0xD1
+ ,0x38,0x73,0xBC,0x71,0x90,0xBD,0xB8,0x71,0x90,0xBD
+ ,0x18,0x65,0x88,0x82,0x38,0x73,0xB8,0x71,0x18,0x6F
+ ,0x01,0x7A,0x10,0x29,0xEE,0xD1,0x1F,0x1C,0xFF,0xF7
+ ,0x36,0xFD,0x38,0x67,0x90,0xBD,0x00,0x00,0x60,0x03
+ ,0x00,0x0D,0xB0,0x00,0x00,0x02,0xF4,0x01,0x00,0x02
+ ,0xF0,0xB4,0x10,0x49,0xCA,0x1D,0x39,0x32,0x90,0x8A
+ ,0x40,0x28,0x01,0xDB,0x40,0x20,0x00,0xE0,0x90,0x8A
+ ,0x00,0x23,0x00,0x28,0x0F,0x6D,0x0B,0xDD,0xCC,0x1D
+ ,0x0A,0x4D,0x49,0x34,0xE6,0x79,0x00,0x2E,0x05,0xD1
+ ,0x3E,0x78,0x01,0x37,0x01,0x33,0x83,0x42,0x2E,0x72
+ ,0xF6,0xDB,0x93,0x8A,0x1B,0x1A,0x93,0x82,0x0A,0x6D
+ ,0x10,0x18,0x08,0x65,0xF0,0xBC,0xF7,0x46,0xF4,0x01
+ ,0x00,0x02,0x20,0x03,0x00,0x0D,0xF0,0xB5,0x04,0x1C
+ ,0x17,0x48,0x0F,0x1C,0x40,0x79,0x01,0x28,0x01,0xDD
+ ,0x00,0xF0,0x53,0xFD,0x15,0x48,0x00,0x25,0xC6,0x1D
+ ,0x39,0x36,0x04,0x65,0xB7,0x82,0xC7,0x1D,0x49,0x37
+ ,0xBD,0x71,0x3D,0x73,0xB0,0x8A,0x80,0x06,0x80,0x0E
+ ,0x01,0x24,0x00,0x28,0x00,0xD1,0x3C,0x73,0xFF,0xF7
+ ,0xBE,0xFF,0xF8,0x79,0x00,0x28,0x02,0xD1,0x0B,0x49
+ ,0x10,0x20,0x08,0x72,0xB0,0x8A,0x00,0x28,0x03,0xD0
+ ,0xFF,0xF7,0xB3,0xFF,0xBC,0x71,0xF0,0xBD,0x38,0x7B
+ ,0x00,0x28,0x02,0xD0,0x3D,0x73,0xBC,0x71,0xF0,0xBD
+ ,0xBD,0x71,0xF0,0xBD,0x00,0x00,0xB0,0x00,0x00,0x02
+ ,0xF4,0x01,0x00,0x02,0x60,0x03,0x00,0x0D,0xB0,0xB5
+ ,0x29,0x4D,0xEF,0x1D,0x49,0x37,0x78,0x7B,0x00,0x28
+ ,0x39,0xD0,0x27,0x48,0x00,0x78,0x01,0x28,0x35,0xD1
+ ,0x26,0x48,0x00,0x24,0x01,0x78,0x01,0x29,0x02,0xD1
+ ,0x04,0x70,0x06,0xF0,0xB7,0xF8,0xF8,0x79,0x01,0x28
+ ,0x03,0xD1,0xFC,0x71,0xF8,0x7B,0x00,0xF0,0xA4,0xF9
+ ,0xE8,0x1D,0x59,0x30,0xC0,0x7A,0x01,0x28,0x02,0xD1
+ ,0xF8,0x7B,0x00,0xF0,0x9C,0xF9,0xF8,0x7B,0x02,0x28
+ ,0x1C,0xD0,0xFF,0xF7,0x9B,0xFE,0x28,0x6F,0x80,0x23
+ ,0x01,0x7A,0x17,0x4F,0x19,0x40,0x0C,0xD0,0x10,0x21
+ ,0x01,0x72,0x28,0x6F,0x81,0x89,0x0C,0x30,0x0C,0x31
+ ,0xFF,0xF7,0x93,0xFF,0x78,0x79,0x01,0x28,0x01,0xDD
+ ,0x00,0xF0,0xD6,0xFC,0xFF,0xF7,0x26,0xFF,0x78,0x79
+ ,0x01,0x28,0x01,0xDD,0x00,0xF0,0xCF,0xFC,0xB0,0xBD
+ ,0x0C,0x48,0x00,0x78,0x00,0x28,0xFA,0xD0,0x28,0x6F
+ ,0x01,0x7A,0x10,0x29,0x05,0xD0,0x01,0x7A,0x80,0x29
+ ,0x02,0xD0,0x01,0x7A,0x40,0x29,0xF0,0xD1,0xFF,0xF7
+ ,0x7D,0xFC,0x28,0x67,0xB0,0xBD,0xF4,0x01,0x00,0x02
+ ,0xDF,0x01,0x00,0x02,0xDD,0x01,0x00,0x02,0xB0,0x00
+ ,0x00,0x02,0xDE,0x01,0x00,0x02,0xB0,0xB4,0x21,0x4F
+ ,0x80,0x21,0x21,0x4A,0x39,0x73,0xD1,0x1D,0x59,0x31
+ ,0x4C,0x88,0x0D,0x88,0xAC,0x42,0x17,0xD1,0x38,0x7B
+ ,0x40,0x23,0x03,0x40,0xE0,0x20,0x00,0x2B,0x0F,0xD1
+ ,0x09,0x88,0x49,0x07,0x02,0xD0,0x38,0x73,0xB0,0xBC
+ ,0xF7,0x46,0xD1,0x1D,0x49,0x31,0x89,0x7B,0x01,0x29
+ ,0x02,0xD1,0xD0,0x20,0x38,0x73,0xF5,0xE7,0x38,0x73
+ ,0xF3,0xE7,0x38,0x73,0xF1,0xE7,0x4A,0x88,0x0C,0x88
+ ,0xA2,0x42,0xED,0xDA,0x0A,0x88,0x4C,0x88,0x12,0x1B
+ ,0x08,0x2A,0x00,0xD9,0x08,0x22,0x01,0x28,0x01,0xD1
+ ,0x0C,0x4B,0x02,0xE0,0x02,0x28,0x00,0xD1,0x0B,0x4B
+ ,0x00,0x2A,0x08,0xD0,0x0A,0x48,0x4C,0x88,0x4D,0x88
+ ,0x01,0x34,0x4C,0x80,0x5C,0x5D,0x01,0x3A,0x04,0x73
+ ,0xF7,0xD1,0x38,0x7B,0x10,0x23,0x18,0x43,0x38,0x73
+ ,0xD0,0xE7,0x70,0x03,0x00,0x0D,0xF4,0x01,0x00,0x02
+ ,0xF4,0x01,0x00,0x02,0x06,0x02,0x00,0x02,0x30,0x03
+ ,0x00,0x0D,0xF0,0xB5,0x00,0x24,0x01,0x28,0x1F,0x4D
+ ,0x1F,0x4E,0x20,0x4F,0x0A,0xD1,0xFD,0xF7,0xE0,0xF9
+ ,0x30,0x7B,0x1E,0x49,0xC8,0x73,0x00,0xF0,0x4C,0xF9
+ ,0x3C,0x73,0x01,0x20,0x28,0x71,0xF0,0xBD,0x79,0x88
+ ,0x3B,0x88,0x1A,0x4A,0x99,0x42,0x1D,0xDA,0x39,0x88
+ ,0x7B,0x88,0xC9,0x1A,0x08,0x29,0x00,0xD9,0x08,0x21
+ ,0x00,0x29,0x0A,0xD0,0x12,0x4E,0x53,0x6E,0x36,0x7B
+ ,0x1E,0x70,0x01,0x33,0x53,0x66,0x7B,0x88,0x01,0x33
+ ,0x7B,0x80,0x01,0x39,0xF4,0xD1,0x7A,0x88,0x3B,0x88
+ ,0x0F,0x49,0x9A,0x42,0x0D,0xD1,0x02,0x28,0x06,0xD1
+ ,0x00,0xF0,0x27,0xF9,0x3C,0x73,0x08,0xE0,0x01,0x20
+ ,0x28,0x71,0xF0,0xBD,0x60,0x20,0x08,0x73,0x01,0x20
+ ,0x38,0x73,0x00,0xE0,0x0C,0x73,0x01,0x20,0x28,0x71
+ ,0xF0,0xBD,0x00,0x00,0xD0,0x03,0x00,0x0D,0x30,0x03
+ ,0x00,0x0D,0x54,0x02,0x00,0x02,0x44,0x02,0x00,0x02
+ ,0xF4,0x01,0x00,0x02,0x70,0x03,0x00,0x0D,0x00,0xB5
+ ,0x7F,0x28,0x07,0xD8,0x00,0x29,0x05,0xD1,0x00,0x2A
+ ,0x03,0xD1,0x0C,0x4A,0x51,0x6B,0x03,0x29,0x03,0xD1
+ ,0x0B,0x49,0x20,0x20,0x08,0x73,0x00,0xBD,0x01,0x29
+ ,0x04,0xD1,0x00,0x28,0x08,0xD0,0x02,0x20,0x50,0x63
+ ,0x05,0xE0,0x02,0x29,0x03,0xD1,0x00,0x28,0x01,0xD1
+ ,0x01,0x20,0x50,0x63,0x00,0xF0,0xEE,0xF8,0x00,0xBD
+ ,0x00,0x00,0xF4,0x01,0x00,0x02,0x70,0x03,0x00,0x0D
+ ,0x80,0xB5,0x00,0x29,0x09,0xD1,0x00,0x2A,0x07,0xD1
+ ,0x00,0x28,0x01,0xD0,0x01,0x28,0x03,0xD1,0x14,0x49
+ ,0x4A,0x6B,0x01,0x2A,0x03,0xD1,0x13,0x49,0x20,0x20
+ ,0x08,0x73,0x80,0xBD,0x12,0x4B,0x02,0x2A,0x09,0xD1
+ ,0x00,0x28,0x12,0xD0,0x03,0x22,0x4A,0x63,0x1F,0x7B
+ ,0x1A,0x1C,0x02,0x23,0x3B,0x43,0x13,0x73,0x0A,0xE0
+ ,0x03,0x2A,0x08,0xD1,0x00,0x28,0x06,0xD1,0x02,0x22
+ ,0x4A,0x63,0x1F,0x7B,0x1A,0x1C,0xFD,0x23,0x3B,0x40
+ ,0x13,0x73,0x88,0x63,0x00,0x20,0x40,0x31,0x88,0x81
+ ,0xC8,0x81,0x00,0xF0,0xB8,0xF8,0x80,0xBD,0x00,0x00
+ ,0xF4,0x01,0x00,0x02,0x70,0x03,0x00,0x0D,0xE0,0x03
+ ,0x00,0x0D,0x90,0xB5,0x15,0x4F,0xFA,0x1D,0x59,0x32
+ ,0x01,0x29,0x02,0xD1,0x12,0x23,0x13,0x80,0x03,0xE0
+ ,0x20,0x23,0x02,0x29,0x09,0xD1,0x13,0x80,0x00,0x23
+ ,0x50,0x37,0xBB,0x73,0x14,0x88,0xA0,0x42,0x05,0xD8
+ ,0xBB,0x73,0x10,0x80,0x0F,0xE0,0x0B,0x48,0x03,0x73
+ ,0x90,0xBD,0x14,0x88,0xA0,0x42,0x09,0xD9,0x10,0x88
+ ,0x40,0x07,0x01,0xD0,0xBB,0x73,0x04,0xE0,0x10,0x88
+ ,0x40,0x07,0x01,0xD1,0x01,0x20,0xB8,0x73,0x53,0x80
+ ,0x08,0x1C,0xFF,0xF7,0xDE,0xFE,0x90,0xBD,0x00,0x00
+ ,0xF4,0x01,0x00,0x02,0x70,0x03,0x00,0x0D,0x80,0xB4
+ ,0x0E,0x4F,0x0E,0x4A,0x01,0x28,0x06,0xD1,0x80,0x20
+ ,0x10,0x72,0x38,0x7B,0xFE,0x23,0x18,0x40,0x38,0x73
+ ,0x08,0xE0,0x02,0x28,0x06,0xD1,0x80,0x20,0x08,0x43
+ ,0x10,0x72,0x38,0x7B,0x01,0x23,0x18,0x43,0x38,0x73
+ ,0x06,0x49,0x20,0x20,0x08,0x73,0x05,0x49,0x01,0x20
+ ,0x08,0x71,0x80,0xBC,0xF7,0x46,0x00,0x00,0xE0,0x03
+ ,0x00,0x0D,0xC0,0x03,0x00,0x0D,0x70,0x03,0x00,0x0D
+ ,0xD0,0x03,0x00,0x0D,0x0D,0x23,0x1B,0x06,0x99,0x83
+ ,0x05,0x49,0x0A,0x70,0x05,0x4A,0x10,0x60,0x02,0x20
+ ,0x08,0x72,0x08,0x7A,0x00,0x28,0xFC,0xD1,0xF7,0x46
+ ,0x00,0x00,0x20,0x00,0x00,0x0D,0x40,0x00,0x00,0x0D
+ ,0x90,0xB5,0x1B,0x4C,0x07,0x1C,0x60,0x79,0x01,0x28
+ ,0x01,0xDD,0x00,0xF0,0x5E,0xFB,0x00,0x21,0x02,0x2F
+ ,0x17,0x48,0x18,0x4A,0x0F,0xD0,0x43,0x7B,0x02,0x2B
+ ,0x03,0xD1,0x41,0x73,0x03,0xF0,0x49,0xFF,0x1A,0xE0
+ ,0x11,0x72,0x14,0x48,0x20,0x22,0x02,0x70,0x01,0x70
+ ,0x13,0x49,0x86,0x20,0x08,0x72,0x11,0xE0,0x12,0x4B
+ ,0x9B,0x7B,0x00,0x2B,0x0D,0xD1,0x17,0x7A,0x7B,0x09
+ ,0x0A,0xD2,0x10,0x23,0x13,0x72,0xC1,0x72,0x0E,0x4A
+ ,0x01,0x20,0x10,0x70,0x0F,0x20,0x00,0x06,0x81,0x81
+ ,0x0C,0x49,0x81,0x80,0x60,0x79,0x01,0x28,0x01,0xDD
+ ,0x00,0xF0,0x1E,0xFB,0x03,0xF0,0x80,0xFF,0x90,0xBD
+ ,0x00,0x00,0xB0,0x00,0x00,0x02,0x54,0x02,0x00,0x02
+ ,0x60,0x03,0x00,0x0D,0xC0,0x03,0x00,0x0D,0xA0,0x03
+ ,0x00,0x0D,0x54,0x09,0x00,0x02,0xDE,0x01,0x00,0x02
+ ,0x08,0x08,0x00,0x00,0x04,0x48,0x01,0x78,0x02,0x78
+ ,0x91,0x42,0xFC,0xD0,0x03,0x49,0x60,0x20,0x08,0x73
+ ,0xF7,0x46,0x00,0x00,0xF0,0x03,0x00,0x0D,0x70,0x03
+ ,0x00,0x0D,0xF0,0xB5,0x29,0x4E,0x30,0x78,0x00,0x28
+ ,0x01,0xD1,0x00,0xF0,0xB1,0xFA,0x0D,0x24,0x24,0x06
+ ,0x27,0x89,0x40,0x20,0x25,0x4D,0x38,0x40,0x08,0xD0
+ ,0x28,0x7A,0x00,0x28,0xFC,0xD1,0x23,0x48,0x00,0x7B
+ ,0x40,0x08,0x01,0xD3,0xFF,0xF7,0x79,0xFC,0x78,0x0A
+ ,0x1F,0xD3,0xF8,0x43,0xFF,0x23,0x01,0x33,0x18,0x43
+ ,0x20,0x81,0xFD,0xF7,0x61,0xF8,0x20,0x7B,0x00,0x09
+ ,0xFC,0xD2,0x28,0x7A,0x00,0x28,0xFC,0xD1,0xFF,0xF7
+ ,0xF2,0xFA,0x18,0x49,0xC8,0x1D,0x49,0x30,0xC2,0x79
+ ,0x02,0x2A,0x06,0xD0,0x01,0x22,0xC2,0x71,0xC8,0x1D
+ ,0x00,0x23,0x59,0x30,0x43,0x73,0x01,0xE0,0x00,0x23
+ ,0xC3,0x71,0xFF,0xF7,0x93,0xFA,0x11,0x49,0x08,0x78
+ ,0x01,0x28,0x10,0xD1,0xB8,0x08,0x0E,0xD3,0x0F,0x4A
+ ,0x00,0x23,0x10,0x7A,0x13,0x72,0xFA,0x43,0x02,0x23
+ ,0x1A,0x43,0x22,0x81,0x09,0x78,0x01,0x29,0x03,0xD1
+ ,0x00,0x04,0x00,0x0C,0x03,0xF0,0x90,0xFE,0x30,0x78
+ ,0x00,0x28,0x01,0xD1,0x00,0xF0,0x89,0xFA,0xF0,0xBD
+ ,0x3D,0x01,0x00,0x02,0x20,0x00,0x00,0x0D,0xD0,0x03
+ ,0x00,0x0D,0xF4,0x01,0x00,0x02,0x37,0x01,0x00,0x02
+ ,0xE0,0x03,0x00,0x0D,0x90,0xB5,0x41,0x68,0x0A,0x78
+ ,0x08,0x2A,0x12,0xD1,0x8A,0x7F,0xCB,0x7F,0x12,0x02
+ ,0x1A,0x43,0x15,0x4B,0x12,0x04,0x1F,0x88,0x12,0x0C
+ ,0xBA,0x42,0x02,0xD0,0x5B,0x88,0x93,0x42,0x06,0xD1
+ ,0xC8,0x1D,0x11,0x30,0x06,0x22,0x10,0x49,0x01,0xF0
+ ,0x9E,0xFA,0x90,0xBD,0x03,0x23,0x5B,0x02,0x9A,0x42
+ ,0x06,0xDD,0xC8,0x1D,0x11,0x30,0x06,0x22,0x0B,0x49
+ ,0x01,0xF0,0x93,0xFA,0x90,0xBD,0xCF,0x1D,0x01,0x37
+ ,0x47,0x60,0x18,0x32,0x82,0x82,0x08,0x4C,0x18,0x22
+ ,0x20,0x1C,0x01,0xF0,0x88,0xFA,0x18,0x22,0x38,0x1C
+ ,0x21,0x1C,0x01,0xF0,0x83,0xFA,0x90,0xBD,0x94,0x02
+ ,0x00,0x02,0x8E,0x02,0x00,0x02,0x88,0x02,0x00,0x02
+ ,0x40,0x0A,0x00,0x02,0xF0,0xB5,0x00,0xF0,0x55,0xF9
+ ,0x71,0x4E,0xFF,0x21,0xF0,0x1D,0x27,0x30,0x01,0x31
+ ,0x06,0x22,0x05,0x1C,0x00,0xF0,0xB3,0xF9,0x6D,0x4F
+ ,0x12,0x22,0x03,0x21,0x38,0x1C,0x00,0xF0,0xAD,0xF9
+ ,0x0E,0x22,0xFF,0x21,0x30,0x1C,0x41,0x31,0x00,0xF0
+ ,0xA7,0xF9,0xF0,0x1D,0x07,0x30,0x0E,0x22,0xFF,0x21
+ ,0x51,0x31,0x00,0xF0,0xA0,0xF9,0xF0,0x1D,0x2E,0x30
+ ,0x0E,0x22,0xFF,0x21,0x61,0x31,0x00,0xF0,0x99,0xF9
+ ,0xF0,0x1D,0x3C,0x30,0x0E,0x22,0xFF,0x21,0x71,0x31
+ ,0x00,0xF0,0x92,0xF9,0xF0,0x1D,0x15,0x30,0x0E,0x22
+ ,0xFF,0x21,0x11,0x31,0x00,0xF0,0x8B,0xF9,0xF0,0x1D
+ ,0x2D,0x30,0x01,0x22,0xFF,0x21,0x31,0x31,0x00,0xF0
+ ,0x84,0xF9,0xF0,0x1D,0x4A,0x30,0x07,0x22,0xFF,0x21
+ ,0x81,0x31,0x00,0xF0,0x7D,0xF9,0xF0,0x1D,0x51,0x30
+ ,0x03,0x22,0xFF,0x21,0x89,0x31,0x00,0xF0,0x76,0xF9
+ ,0xF0,0x1D,0x55,0x30,0x04,0x22,0xFF,0x21,0x8D,0x31
+ ,0x00,0xF0,0x6F,0xF9,0x00,0xF0,0x24,0xF9,0xF0,0x1D
+ ,0x23,0x30,0x04,0x22,0xF9,0x1D,0x01,0x31,0x01,0xF0
+ ,0x21,0xFA,0xF4,0x1D,0x19,0x34,0xA0,0x7B,0xC0,0x07
+ ,0xC0,0x0F,0x00,0x27,0x00,0x28,0x10,0xD1,0x44,0x4A
+ ,0x17,0x54,0x01,0x30,0x06,0x28,0xFB,0xD3,0x10,0x1C
+ ,0x06,0x22,0x29,0x1C,0x01,0xF0,0xF1,0xF9,0x00,0x28
+ ,0x04,0xD0,0x29,0x1C,0x06,0x22,0x3E,0x48,0x01,0xF0
+ ,0x08,0xFA,0xF0,0x1D,0x29,0x30,0x00,0x79,0x10,0x28
+ ,0x0D,0xD0,0x20,0x28,0x0B,0xD0,0x31,0x28,0x09,0xD0
+ ,0x30,0x28,0x07,0xD0,0x32,0x28,0x05,0xD0,0x40,0x28
+ ,0x03,0xD0,0x41,0x28,0x01,0xD0,0x50,0x28,0x01,0xD1
+ ,0x34,0x49,0xC8,0x75,0xF0,0x1D,0x49,0x30,0x43,0x78
+ ,0x01,0x22,0x32,0x49,0x55,0x2B,0x13,0xD1,0x83,0x78
+ ,0x53,0x2B,0x10,0xD1,0xC3,0x78,0x42,0x2B,0x0D,0xD1
+ ,0x03,0x79,0x53,0x2B,0x0A,0xD1,0x43,0x79,0x55,0x2B
+ ,0x07,0xD1,0x83,0x79,0x53,0x2B,0x04,0xD1,0xC3,0x79
+ ,0x50,0x2B,0x01,0xD1,0x0A,0x70,0x00,0xE0,0x0F,0x70
+ ,0xFF,0x25,0x01,0x23,0x06,0x7A,0x5B,0x02,0x01,0x35
+ ,0x53,0x2E,0x24,0x49,0x08,0xD1,0x46,0x7A,0x45,0x2E
+ ,0x05,0xD1,0x86,0x7A,0x4C,0x2E,0x02,0xD1,0xCD,0x61
+ ,0x0B,0x62,0x01,0xE0,0xCB,0x61,0x0D,0x62,0x05,0x7B
+ ,0x1E,0x4B,0x48,0x2D,0x12,0xD1,0x45,0x7B,0x57,0x2D
+ ,0x0F,0xD1,0x80,0x7B,0x31,0x28,0x02,0xD1,0x03,0x20
+ ,0x98,0x70,0x0C,0xE0,0x32,0x28,0x02,0xD1,0x04,0x20
+ ,0x98,0x70,0x07,0xE0,0x33,0x28,0x02,0xD1,0x05,0x20
+ ,0x98,0x70,0x12,0xE0,0x98,0x78,0x05,0x28,0x0F,0xDA
+ ,0x40,0x20,0xC8,0x60,0x4F,0x76,0x98,0x78,0x02,0x28
+ ,0x01,0xD1,0x0F,0x76,0x02,0xE0,0x0A,0x76,0x04,0x28
+ ,0x03,0xDA,0x20,0x79,0x00,0x28,0x00,0xD0,0x27,0x71
+ ,0xF0,0xBD,0x20,0x20,0xC8,0x60,0x4A,0x76,0x0A,0x76
+ ,0xF0,0xBD,0x00,0x00,0x58,0x0A,0x00,0x02,0xF4,0x01
+ ,0x00,0x02,0x00,0x72,0x01,0x02,0x5C,0x00,0x00,0x02
+ ,0x00,0x00,0x00,0x02,0x36,0x01,0x00,0x02,0x98,0x02
+ ,0x00,0x02,0x10,0x01,0x00,0x02,0xB0,0xB5,0x2A,0x48
+ ,0x04,0x25,0x05,0x70,0x29,0x49,0x00,0x20,0x08,0x70
+ ,0x29,0x49,0x02,0x24,0x0C,0x70,0x06,0x21,0x07,0x27
+ ,0x7F,0x06,0xB9,0x61,0x78,0x61,0xF8,0x69,0xFB,0x0B
+ ,0x98,0x43,0xF8,0x61,0xF8,0x69,0x10,0x23,0x98,0x43
+ ,0xF8,0x61,0xFF,0xF7,0xF1,0xFE,0x21,0x48,0x00,0x78
+ ,0x00,0x28,0x00,0xD1,0xBD,0x61,0x1F,0x48,0x01,0x21
+ ,0xC1,0x76,0x1F,0x49,0xCA,0x69,0x0B,0x0C,0x1A,0x43
+ ,0xCA,0x61,0xCA,0x69,0x1B,0x23,0x9A,0x43,0xCA,0x61
+ ,0xCA,0x69,0x04,0x23,0x9A,0x43,0xCA,0x61,0xC2,0x68
+ ,0xCB,0x69,0xD2,0x43,0x1A,0x40,0xCA,0x61,0xC2,0x69
+ ,0xCB,0x69,0xD2,0x43,0x1A,0x40,0xCA,0x61,0x02,0x6A
+ ,0xCB,0x69,0x1A,0x43,0xCA,0x61,0xCA,0x69,0x0B,0x0C
+ ,0x9A,0x43,0xCA,0x61,0xB9,0x69,0x01,0x23,0x19,0x43
+ ,0xB9,0x61,0x84,0x76,0x00,0xF0,0x39,0xF8,0x00,0xF0
+ ,0xA3,0xF8,0x0A,0x20,0xFC,0xF7,0x9E,0xFD,0x00,0xF0
+ ,0x96,0xF8,0xFF,0xF7,0x02,0xF9,0xF8,0x69,0x01,0x23
+ ,0xDB,0x03,0x18,0x43,0xF8,0x61,0xB0,0xBD,0x53,0x02
+ ,0x00,0x02,0x5E,0x02,0x00,0x02,0x3B,0x01,0x00,0x02
+ ,0x36,0x01,0x00,0x02,0x98,0x02,0x00,0x02,0x40,0x00
+ ,0x00,0x04,0x80,0x21,0xF3,0x20,0x00,0x05,0x01,0x60
+ ,0x00,0x21,0x01,0x60,0x01,0x21,0x41,0x60,0x01,0x60
+ ,0x07,0x21,0x49,0x06,0xCA,0x69,0x01,0x23,0x5B,0x03
+ ,0x1A,0x43,0xCA,0x61,0x04,0x49,0x01,0x63,0x04,0x49
+ ,0x41,0x63,0x81,0x63,0xC1,0x63,0x01,0x69,0x80,0x68
+ ,0xF7,0x46,0x00,0x00,0x01,0x0C,0x00,0x02,0x01,0x02
+ ,0x00,0x02,0x07,0x20,0x40,0x06,0xC1,0x69,0x02,0x4B
+ ,0x19,0x40,0xC1,0x61,0xF7,0x46,0x00,0x00,0xFF,0xDF
+ ,0x00,0x00,0xF0,0xB5,0x0F,0x1C,0x00,0x21,0xF3,0x24
+ ,0x24,0x05,0x00,0x28,0x08,0xD9,0x10,0x4D,0x6B,0x5C
+ ,0xE3,0x60,0x26,0x69,0xB3,0x08,0xFC,0xD3,0x01,0x31
+ ,0x81,0x42,0xF7,0xD3,0xFF,0x20,0xE0,0x60,0xA1,0x68
+ ,0x21,0x1C,0x0B,0x69,0x5B,0x08,0xFC,0xD3,0x8B,0x68
+ ,0x0C,0x69,0xA3,0x08,0xFC,0xD3,0xC8,0x60,0x0B,0x69
+ ,0x5B,0x08,0xFC,0xD3,0x8B,0x68,0x3B,0x70,0x01,0x37
+ ,0x01,0x3A,0xF3,0xD1,0x02,0x20,0xFC,0xF7,0x39,0xFD
+ ,0xF0,0xBD,0xA8,0x02,0x00,0x02,0xF3,0x20,0x00,0x05
+ ,0x81,0x68,0x05,0x21,0xC1,0x60,0x01,0x69,0x89,0x08
+ ,0xFC,0xD3,0xFF,0x21,0xC1,0x60,0x01,0x69,0x89,0x08
+ ,0xFC,0xD3,0x81,0x68,0x01,0x69,0x49,0x08,0xFC,0xD3
+ ,0x80,0x68,0x00,0x06,0x00,0x0E,0xF7,0x46,0x90,0xB5
+ ,0x04,0x1C,0x48,0x09,0x08,0x23,0x18,0x40,0x17,0x1C
+ ,0x03,0x22,0x02,0x43,0x08,0x48,0x02,0x70,0x41,0x70
+ ,0xFF,0xF7,0xDE,0xFF,0x40,0x08,0xFB,0xD2,0x02,0x20
+ ,0xFC,0xF7,0x0F,0xFD,0x02,0x20,0x21,0x1C,0x3A,0x1C
+ ,0xFF,0xF7,0xAA,0xFF,0x90,0xBD,0x00,0x00,0xA8,0x02
+ ,0x00,0x02,0x07,0x20,0x40,0x06,0xC1,0x69,0x01,0x23
+ ,0x5B,0x03,0x19,0x43,0xC1,0x61,0xF7,0x46,0xF3,0x20
+ ,0x00,0x05,0x41,0x68,0x0F,0x23,0x1B,0x04,0x99,0x43
+ ,0x41,0x60,0x41,0x68,0x19,0x43,0x41,0x60,0xF7,0x46
+ ,0x00,0x00,0x80,0xB4,0x14,0x4B,0x5B,0x79,0x01,0x2B
+ ,0x0E,0xDD,0x17,0x1C,0x12,0x4A,0x14,0xD1,0x02,0x2B
+ ,0x09,0xD1,0x00,0x29,0x07,0xD1,0x00,0x28,0x07,0xD1
+ ,0x90,0x78,0x4B,0x1F,0x18,0x40,0x90,0x70,0x00,0x20
+ ,0x50,0x70,0x80,0xBC,0xF7,0x46,0x90,0x78,0x04,0x23
+ ,0x18,0x43,0x90,0x70,0x01,0x20,0x50,0x70,0xF6,0xE7
+ ,0x00,0x28,0x04,0xD1,0x90,0x78,0x02,0x23,0x98,0x43
+ ,0x90,0x70,0xEF,0xE7,0x90,0x78,0x02,0x23,0x18,0x43
+ ,0x90,0x70,0xEA,0xE7,0x00,0x00,0xB0,0x00,0x00,0x02
+ ,0xB4,0x09,0x00,0x02,0x90,0xB5,0x07,0x21,0x49,0x06
+ ,0xCA,0x69,0x52,0x09,0x15,0xD3,0xCA,0x69,0x10,0x23
+ ,0x9A,0x43,0xCA,0x61,0x01,0x28,0x01,0xD1,0x08,0x49
+ ,0x08,0x70,0x08,0x4C,0x67,0x68,0xFC,0xF7,0xC6,0xFC
+ ,0x39,0x1A,0x49,0x01,0x09,0x18,0x06,0x4A,0x61,0x60
+ ,0x51,0x6B,0x09,0x1A,0x49,0x01,0x08,0x18,0x50,0x63
+ ,0x90,0xBD,0x00,0x00,0x3D,0x01,0x00,0x02,0x80,0x00
+ ,0x00,0x04,0x40,0x00,0x00,0x04,0x90,0xB5,0x0C,0x48
+ ,0x80,0x78,0x01,0x28,0x13,0xD1,0x0B,0x4F,0x7C,0x68
+ ,0xFC,0xF7,0xAB,0xFC,0x21,0x1A,0x49,0x09,0x09,0x18
+ ,0x79,0x60,0x08,0x49,0x4A,0x6B,0x12,0x1A,0x52,0x09
+ ,0x10,0x18,0x48,0x63,0x07,0x20,0x40,0x06,0xC1,0x69
+ ,0x10,0x23,0x19,0x43,0xC1,0x61,0x90,0xBD,0xB4,0x09
+ ,0x00,0x02,0x80,0x00,0x00,0x04,0x40,0x00,0x00,0x04
+ ,0x80,0xB5,0xC0,0x20,0x00,0xF0,0x32,0xFC,0x07,0x1C
+ ,0x06,0x48,0x01,0x78,0x00,0x29,0x03,0xD0,0x00,0x21
+ ,0x01,0x70,0xFF,0xF7,0xD3,0xFF,0x38,0x1C,0x00,0xF0
+ ,0x26,0xFC,0x80,0xBD,0x00,0x00,0x3D,0x01,0x00,0x02
+ ,0x80,0xB5,0xC0,0x20,0x00,0xF0,0x1E,0xFC,0x07,0x1C
+ ,0x01,0x20,0xFF,0xF7,0xA0,0xFF,0x38,0x1C,0x00,0xF0
+ ,0x17,0xFC,0x80,0xBD,0xF0,0xB4,0x13,0x4A,0x00,0x27
+ ,0xD7,0x65,0x17,0x66,0x17,0x67,0x57,0x67,0x20,0x20
+ ,0x90,0x67,0x10,0x48,0x07,0x70,0x41,0x1C,0x01,0x20
+ ,0x04,0x02,0x00,0x25,0x03,0x1C,0x46,0x08,0x05,0xD2
+ ,0x5B,0x08,0x01,0x35,0x2D,0x06,0x2D,0x0E,0x5E,0x08
+ ,0xF9,0xD3,0x0D,0x70,0x01,0x31,0x01,0x30,0xA0,0x42
+ ,0xF0,0xD3,0x07,0x49,0x00,0x20,0x80,0xC1,0x01,0x30
+ ,0x20,0x28,0xFB,0xD3,0x57,0x66,0x97,0x66,0xD7,0x67
+ ,0xF0,0xBC,0xF7,0x46,0x5C,0x03,0x00,0x02,0xE0,0x0A
+ ,0x00,0x02,0xE0,0x0B,0x00,0x02,0x90,0xB5,0x0A,0x4F
+ ,0x0A,0x4C,0x38,0x68,0x63,0x1C,0x98,0x42,0x04,0xD0
+ ,0x3C,0x60,0xFC,0xF7,0x2C,0xFB,0x00,0xF0,0xEC,0xFB
+ ,0x06,0x48,0x3C,0x60,0x00,0x68,0xFC,0xF7,0xA2,0xFB
+ ,0x00,0x20,0x38,0x60,0x00,0xF0,0xF3,0xFB,0x90,0xBD
+ ,0xC8,0x03,0x00,0x02,0xF0,0xF0,0xF0,0xF0,0x38,0x04
+ ,0x00,0x02,0x80,0xB5,0x05,0x48,0x05,0x4F,0x38,0x60
+ ,0xFC,0xF7,0x14,0xFB,0x00,0xF0,0xD4,0xFB,0x03,0x48
+ ,0x38,0x60,0x80,0xBD,0x00,0x00,0xF0,0xF0,0xF0,0xF0
+ ,0xC8,0x03,0x00,0x02,0xF1,0xF0,0xF0,0xF0,0x0F,0x00
+ ,0x2D,0xE9,0xD2,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1
+ ,0xCC,0x30,0x9F,0xE5,0x00,0x20,0x93,0xE5,0x00,0x00
+ ,0x52,0xE3,0x06,0x00,0x00,0x0A,0x01,0x20,0x82,0xE2
+ ,0x00,0x20,0x83,0xE5,0x00,0x00,0x4F,0xE1,0x04,0xE0
+ ,0x4E,0xE2,0x01,0x40,0x2D,0xE9,0xB0,0x00,0x9F,0xE5
+ ,0x10,0xFF,0x2F,0xE1,0x01,0x20,0x82,0xE2,0x00,0x20
+ ,0x83,0xE5,0x9C,0x10,0x9F,0xE5,0x00,0x00,0x91,0xE5
+ ,0x00,0x00,0x50,0xE3,0x04,0x00,0x00,0x0A,0x00,0x20
+ ,0x4F,0xE1,0x04,0xE0,0x4E,0xE2,0x04,0x40,0x2D,0xE9
+ ,0x84,0x00,0x9F,0xE5,0x10,0xFF,0x2F,0xE1,0x10,0xD0
+ ,0x8D,0xE2,0x78,0x00,0x9F,0xE5,0x10,0xFF,0x2F,0xE1
+ ,0x0F,0x00,0x2D,0xE9,0x64,0x30,0x9F,0xE5,0x00,0x20
+ ,0x93,0xE5,0x00,0x00,0x52,0xE3,0x06,0x00,0x00,0x0A
+ ,0x01,0x20,0x82,0xE2,0x00,0x20,0x83,0xE5,0x00,0x00
+ ,0x4F,0xE1,0x04,0xE0,0x4E,0xE2,0x01,0x40,0x2D,0xE9
+ ,0x4C,0x00,0x9F,0xE5,0x10,0xFF,0x2F,0xE1,0x01,0x20
+ ,0x82,0xE2,0x00,0x20,0x83,0xE5,0x34,0x10,0x9F,0xE5
+ ,0x00,0x00,0x91,0xE5,0x00,0x00,0x50,0xE3,0x04,0x00
+ ,0x00,0x0A,0x00,0x20,0x4F,0xE1,0x04,0xE0,0x4E,0xE2
+ ,0x04,0x40,0x2D,0xE9,0x20,0x00,0x9F,0xE5,0x10,0xFF
+ ,0x2F,0xE1,0x00,0x00,0x4F,0xE1,0x04,0xE0,0x4E,0xE2
+ ,0x01,0x40,0x2D,0xE9,0x0C,0x00,0x9F,0xE5,0x10,0xFF
+ ,0x2F,0xE1,0xC8,0x03,0x00,0x02,0xB8,0x03,0x00,0x02
+ ,0x1D,0x01,0x00,0x00,0x29,0x01,0x00,0x00,0x00,0xA0
+ ,0x00,0x47,0xD2,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1
+ ,0xE4,0x31,0x9F,0xE5,0x00,0x20,0x93,0xE5,0x01,0x20
+ ,0x42,0xE2,0x00,0x20,0x83,0xE5,0x00,0x00,0x52,0xE3
+ ,0x03,0x00,0x00,0x0A,0x01,0x40,0xBD,0xE8,0x00,0xF0
+ ,0x6F,0xE1,0x0F,0x00,0xBD,0xE8,0x0E,0xF0,0xB0,0xE1
+ ,0xC0,0x11,0x9F,0xE5,0x00,0x00,0x91,0xE5,0x00,0x00
+ ,0x50,0xE3,0x27,0x00,0x00,0x0A,0xC0,0x31,0x9F,0xE5
+ ,0x00,0x20,0x93,0xE5,0x00,0x00,0x52,0xE3,0x03,0x00
+ ,0x00,0x1A,0xA8,0x31,0x9F,0xE5,0x00,0x20,0x93,0xE5
+ ,0x02,0x00,0x50,0xE1,0x03,0x00,0x00,0x1A,0x01,0x40
+ ,0xBD,0xE8,0x00,0xF0,0x6F,0xE1,0x0F,0x00,0xBD,0xE8
+ ,0x0E,0xF0,0xB0,0xE1,0x08,0x40,0xBD,0xE8,0x0E,0x10
+ ,0xA0,0xE1,0xD3,0x20,0xA0,0xE3,0x02,0xF0,0x21,0xE1
+ ,0x04,0x10,0x2D,0xE5,0xF0,0x5F,0x2D,0xE9,0x03,0x40
+ ,0xA0,0xE1,0xD2,0x20,0xA0,0xE3,0x02,0xF0,0x21,0xE1
+ ,0x0F,0x00,0xBD,0xE8,0xD3,0x50,0xA0,0xE3,0x05,0xF0
+ ,0x21,0xE1,0x0F,0x00,0x2D,0xE9,0x01,0x30,0xA0,0xE3
+ ,0x18,0x00,0x2D,0xE9,0x44,0x11,0x9F,0xE5,0x00,0x00
+ ,0x91,0xE5,0x08,0xD0,0x80,0xE5,0x44,0x31,0x9F,0xE5
+ ,0x00,0x20,0x93,0xE5,0x00,0x00,0x52,0xE3,0x02,0x00
+ ,0x00,0x0A,0x18,0x20,0x80,0xE5,0x00,0x20,0xA0,0xE3
+ ,0x00,0x20,0x83,0xE5,0x00,0x00,0xA0,0xE3,0x00,0x00
+ ,0x81,0xE5,0x78,0x01,0x00,0xEA,0xD3,0x00,0xA0,0xE3
+ ,0x00,0xF0,0x21,0xE1,0x75,0x01,0x00,0xEA,0x00,0xA0
+ ,0x00,0x47,0xD1,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1
+ ,0xF4,0x30,0x9F,0xE5,0x00,0x20,0x93,0xE5,0x01,0x20
+ ,0x42,0xE2,0x00,0x20,0x83,0xE5,0x00,0x00,0x52,0xE3
+ ,0x03,0x00,0x00,0x0A,0x01,0x40,0xBD,0xE8,0x00,0xF0
+ ,0x6F,0xE1,0x0F,0x00,0xBD,0xE8,0x0E,0xF0,0xB0,0xE1
+ ,0x00,0x10,0x9D,0xE5,0x1F,0x20,0xA0,0xE3,0x02,0x10
+ ,0x01,0xE0,0x12,0x00,0x51,0xE3,0x0B,0x00,0x00,0x0A
+ ,0xBC,0x10,0x9F,0xE5,0x00,0x00,0x91,0xE5,0x00,0x00
+ ,0x50,0xE3,0x27,0x00,0x00,0x0A,0xBC,0x30,0x9F,0xE5
+ ,0x00,0x20,0x93,0xE5,0x00,0x00,0x52,0xE3,0x03,0x00
+ ,0x00,0x1A,0xA4,0x30,0x9F,0xE5,0x00,0x20,0x93,0xE5
+ ,0x02,0x00,0x50,0xE1,0x03,0x00,0x00,0x1A,0x01,0x40
+ ,0xBD,0xE8,0x00,0xF0,0x6F,0xE1,0x0F,0x00,0xBD,0xE8
+ ,0x0E,0xF0,0xB0,0xE1,0x08,0x40,0xBD,0xE8,0x0E,0x10
+ ,0xA0,0xE1,0xD3,0x20,0xA0,0xE3,0x02,0xF0,0x21,0xE1
+ ,0x04,0x10,0x2D,0xE5,0xF0,0x5F,0x2D,0xE9,0x03,0x40
+ ,0xA0,0xE1,0xD1,0x20,0xA0,0xE3,0x02,0xF0,0x21,0xE1
+ ,0x0F,0x00,0xBD,0xE8,0xD3,0x50,0xA0,0xE3,0x05,0xF0
+ ,0x21,0xE1,0x0F,0x00,0x2D,0xE9,0x01,0x30,0xA0,0xE3
+ ,0x18,0x00,0x2D,0xE9,0x40,0x10,0x9F,0xE5,0x00,0x00
+ ,0x91,0xE5,0x08,0xD0,0x80,0xE5,0x40,0x30,0x9F,0xE5
+ ,0x00,0x20,0x93,0xE5,0x00,0x00,0x52,0xE3,0x02,0x00
+ ,0x00,0x0A,0x18,0x20,0x80,0xE5,0x00,0x20,0xA0,0xE3
+ ,0x00,0x20,0x83,0xE5,0x00,0x00,0xA0,0xE3,0x00,0x00
+ ,0x81,0xE5,0x37,0x01,0x00,0xEA,0x18,0xD0,0x8D,0xE2
+ ,0xD3,0x00,0xA0,0xE3,0x00,0xF0,0x21,0xE1,0x33,0x01
+ ,0x00,0xEA,0xC8,0x03,0x00,0x02,0xB8,0x03,0x00,0x02
+ ,0xB4,0x03,0x00,0x02,0xBC,0x03,0x00,0x02,0x40,0x04
+ ,0x00,0x02,0xD8,0x03,0x00,0x02,0x90,0xB5,0x86,0xB0
+ ,0x00,0x24,0x13,0x4F,0x13,0x4A,0x3C,0x60,0x7C,0x60
+ ,0xBC,0x60,0x00,0x21,0x10,0x1C,0xBC,0x61,0x10,0xC0
+ ,0x01,0x31,0x20,0x29,0xFB,0xD3,0xD0,0x1D,0x79,0x30
+ ,0xFA,0x60,0x38,0x61,0x7A,0x61,0x78,0x6A,0x00,0x22
+ ,0x00,0x21,0x05,0x92,0x02,0x1C,0x04,0x91,0x03,0x90
+ ,0xF8,0x69,0x39,0x6A,0x02,0x92,0x00,0x90,0x01,0x91
+ ,0x08,0xA1,0x07,0x48,0x05,0x4A,0x0C,0x4B,0x00,0xF0
+ ,0x18,0xF8,0xBC,0x62,0xFC,0x62,0x06,0xB0,0x90,0xBD
+ ,0x3C,0x04,0x00,0x02,0x60,0x0C,0x00,0x02,0xD1,0x42
+ ,0x00,0x00,0xE0,0x0C,0x00,0x02,0x53,0x79,0x73,0x74
+ ,0x65,0x6D,0x20,0x54,0x69,0x6D,0x65,0x72,0x20,0x54
+ ,0x68,0x72,0x65,0x61,0x64,0x00,0x4D,0x49,0x54,0x41
+ ,0xFF,0xB5,0x07,0x1C,0x0D,0x98,0x0E,0x9C,0x0A,0xAE
+ ,0x4C,0xCE,0x09,0x9D,0xB9,0x62,0x02,0x99,0x79,0x64
+ ,0x03,0x99,0xB9,0x64,0x00,0x21,0xB9,0x60,0x7A,0x61
+ ,0xAA,0x18,0x01,0x3A,0xFD,0x60,0x3A,0x61,0xDA,0x06
+ ,0xD2,0x0E,0xF3,0x06,0xB8,0x61,0xFA,0x62,0xDB,0x0E
+ ,0xFB,0x63,0xF8,0x61,0x79,0x60,0x03,0x20,0x38,0x63
+ ,0x79,0x63,0x25,0x48,0xB9,0x63,0x78,0x65,0x01,0x20
+ ,0x90,0x40,0xBF,0x65,0x39,0x65,0x64,0x37,0x00,0x22
+ ,0x00,0x23,0x0E,0xC7,0x0C,0xC7,0x78,0x3F,0x38,0x64
+ ,0x38,0x1C,0x1E,0x49,0x00,0xF0,0x0B,0xFB,0xC0,0x20
+ ,0x00,0xF0,0xC8,0xF9,0x1C,0x49,0x1D,0x4D,0x39,0x60
+ ,0x2A,0x68,0xF9,0x1D,0x79,0x31,0x00,0x2A,0x0A,0xD0
+ ,0xD3,0x1D,0x79,0x33,0xDA,0x68,0xDF,0x60,0xD3,0x1D
+ ,0x79,0x33,0x9F,0x60,0xCA,0x60,0x2A,0x68,0x8A,0x60
+ ,0x02,0xE0,0x2F,0x60,0x8F,0x60,0xCF,0x60,0x13,0x49
+ ,0x14,0x4D,0x0A,0x68,0x01,0x32,0x0A,0x60,0x29,0x68
+ ,0x01,0x31,0x29,0x60,0x00,0xF0,0xA8,0xF9,0x00,0x2C
+ ,0x07,0xD0,0x38,0x1C,0x00,0xF0,0x1D,0xFB,0x00,0x28
+ ,0x0A,0xD0,0x00,0xF0,0x83,0xFB,0x07,0xE0,0xC0,0x20
+ ,0x00,0xF0,0x9B,0xF9,0x29,0x68,0x01,0x39,0x29,0x60
+ ,0x00,0xF0,0x96,0xF9,0x00,0x20,0x04,0xB0,0xF0,0xBD
+ ,0x00,0x00,0x2D,0x44,0x00,0x00,0x6D,0x44,0x00,0x00
+ ,0x44,0x52,0x48,0x54,0xC0,0x03,0x00,0x02,0xC4,0x03
+ ,0x00,0x02,0xD8,0x03,0x00,0x02,0x90,0xB5,0x41,0x60
+ ,0x07,0x1C,0x08,0x30,0x00,0x21,0x00,0x24,0x12,0xC0
+ ,0x12,0xC0,0xC0,0x20,0x00,0xF0,0x7B,0xF9,0x0C,0x49
+ ,0x0C,0x4B,0x39,0x60,0x19,0x68,0x00,0x29,0x06,0xD0
+ ,0xCA,0x69,0xCF,0x61,0x97,0x61,0xFA,0x61,0x19,0x68
+ ,0xB9,0x61,0x02,0xE0,0x1F,0x60,0xBF,0x61,0xFF,0x61
+ ,0x06,0x49,0x0A,0x68,0x01,0x32,0x0A,0x60,0x00,0xF0
+ ,0x65,0xF9,0x20,0x1C,0x90,0xBD,0x00,0x00,0x4E,0x44
+ ,0x56,0x44,0x6C,0x04,0x00,0x02,0x70,0x04,0x00,0x02
+ ,0xF0,0xB5,0x85,0xB0,0x07,0x1C,0xC0,0x20,0x0C,0x1C
+ ,0x15,0x1C,0x00,0xF0,0x54,0xF9,0xA9,0x08,0x03,0xD3
+ ,0xB9,0x68,0x21,0x40,0xB9,0x60,0x3D,0xE0,0xB9,0x68
+ ,0x21,0x43,0xB9,0x60,0x3C,0x69,0x0A,0x1C,0x00,0x2C
+ ,0x63,0xD0,0x7B,0x69,0x6D,0x49,0x01,0x2B,0x35,0xD1
+ ,0xE5,0x1D,0x79,0x35,0x2E,0x68,0xB3,0x08,0x05,0xD3
+ ,0xA3,0x6F,0x16,0x1C,0x1E,0x40,0x9E,0x42,0x28,0xD1
+ ,0x02,0xE0,0xA3,0x6F,0x13,0x40,0x24,0xD0,0xE3,0x6F
+ ,0x1A,0x60,0x2A,0x68,0x52,0x08,0x03,0xD3,0xBA,0x68
+ ,0xA3,0x6F,0x9A,0x43,0xBA,0x60,0x00,0x26,0x3E,0x61
+ ,0x7E,0x61,0xA6,0x66,0x0A,0x68,0x01,0x32,0x0A,0x60
+ ,0x00,0xF0,0x23,0xF9,0x60,0x6E,0x00,0x28,0x04,0xD0
+ ,0xE0,0x1D,0x45,0x30,0x00,0xF0,0x34,0xFB,0x00,0xE0
+ ,0xE6,0x64,0x6E,0x60,0x20,0x1C,0x00,0xF0,0x90,0xFA
+ ,0x00,0x28,0x01,0xD0,0x00,0xF0,0xF6,0xFA,0x30,0x1C
+ ,0x9B,0xE0,0x00,0xF0,0x0E,0xF9,0x97,0xE0,0x03,0x94
+ ,0x00,0x25,0x3D,0x61,0x01,0x92,0x4F,0x4A,0x02,0x93
+ ,0x11,0x68,0x00,0x26,0x01,0x31,0x11,0x60,0x00,0xF0
+ ,0x01,0xF9,0xC0,0x20,0x00,0xF0,0xFE,0xF8,0xF9,0x68
+ ,0x00,0x29,0x0A,0xD0,0x00,0x21,0xF9,0x60,0x03,0x9C
+ ,0x7B,0x69,0x02,0x93,0xB9,0x68,0x01,0x9A,0x11,0x43
+ ,0x01,0x91,0x00,0x2C,0x46,0xD0,0xE3,0x1D,0x79,0x33
+ ,0x04,0x93,0x19,0x68,0x00,0x91,0x89,0x08,0x06,0xD3
+ ,0xA1,0x6F,0x01,0x9A,0x0A,0x40,0x8A,0x42,0x07,0xD1
+ ,0x04,0xE0,0x6F,0xE0,0xA1,0x6F,0x01,0x9A,0x11,0x40
+ ,0x01,0xD0,0x00,0x21,0x00,0xE0,0x07,0x21,0x22,0x6F
+ ,0x00,0x29,0x28,0xD1,0x01,0x99,0xE3,0x6F,0x19,0x60
+ ,0x00,0x99,0x49,0x08,0x03,0xD3,0xB9,0x68,0xA3,0x6F
+ ,0x99,0x43,0xB9,0x60,0x21,0x6F,0xA1,0x42,0x02,0xD1
+ ,0x00,0x21,0x03,0x91,0x08,0xE0,0x03,0x9B,0xA3,0x42
+ ,0x00,0xD1,0x03,0x91,0x63,0x6F,0x4B,0x67,0x21,0x6F
+ ,0x63,0x6F,0x19,0x67,0x79,0x69,0x01,0x39,0x79,0x61
+ ,0x00,0x21,0xA1,0x66,0x04,0x9B,0x00,0x2D,0x59,0x60
+ ,0x03,0xD1,0x25,0x1C,0x26,0x1C,0x21,0x67,0x02,0xE0
+ ,0x34,0x67,0x21,0x67,0x26,0x1C,0x02,0x9B,0x14,0x1C
+ ,0x01,0x3B,0x02,0x93,0x00,0x2B,0xA5,0xD1,0x03,0x99
+ ,0x39,0x61,0x00,0xF0,0xA5,0xF8,0x00,0x2D,0x18,0xD0
+ ,0x1C,0x4E,0x00,0x24,0x68,0x6E,0x2F,0x6F,0x00,0x28
+ ,0x04,0xD0,0xE8,0x1D,0x45,0x30,0x00,0xF0,0xB1,0xFA
+ ,0x00,0xE0,0xEC,0x64,0xC0,0x20,0x00,0xF0,0x94,0xF8
+ ,0x31,0x68,0x01,0x31,0x31,0x60,0x00,0xF0,0x8F,0xF8
+ ,0x28,0x1C,0x00,0xF0,0x06,0xFA,0x3D,0x1C,0xE8,0xD1
+ ,0xC0,0x20,0x00,0xF0,0x87,0xF8,0x0E,0x49,0x0A,0x68
+ ,0x01,0x3A,0x0A,0x60,0x00,0xF0,0x81,0xF8,0x0C,0x48
+ ,0x0C,0x49,0x00,0x68,0x09,0x68,0x88,0x42,0x05,0xD0
+ ,0x0B,0x48,0x00,0x68,0x00,0x28,0x01,0xD1,0x00,0xF0
+ ,0x59,0xFA,0x00,0x20,0x05,0xB0,0xF0,0xBD,0x79,0x69
+ ,0x00,0x29,0x00,0xD1,0x5D,0xE7,0xF9,0x68,0x01,0x31
+ ,0xF9,0x60,0x59,0xE7,0xD8,0x03,0x00,0x02,0xB8,0x03
+ ,0x00,0x02,0xBC,0x03,0x00,0x02,0xC8,0x03,0x00,0x02
+ ,0xFF,0xB5,0x07,0x1C,0xC0,0x20,0x0D,0x1C,0x09,0x9E
+ ,0x00,0xF0,0x5B,0xF8,0x02,0x9A,0x91,0x08,0x04,0xD3
+ ,0xB9,0x68,0x29,0x40,0xA9,0x42,0x0E,0xD1,0x02,0xE0
+ ,0xB9,0x68,0x29,0x40,0x0A,0xD0,0xB9,0x68,0x03,0x9B
+ ,0x00,0x24,0x19,0x60,0x02,0x9A,0x51,0x08,0x3D,0xD3
+ ,0xB9,0x68,0xA9,0x43,0xB9,0x60,0x39,0xE0,0x07,0x24
+ ,0x00,0x2E,0x36,0xD0,0x1D,0x49,0x0C,0x68,0x1D,0x49
+ ,0xA1,0x66,0xA5,0x67,0xE5,0x1D,0x02,0x9A,0x79,0x35
+ ,0x2A,0x60,0x03,0x9B,0xE3,0x67,0xE7,0x66,0x39,0x69
+ ,0x00,0x29,0x09,0xD0,0x21,0x67,0x39,0x69,0x49,0x6F
+ ,0x61,0x67,0x39,0x69,0x49,0x6F,0x0C,0x67,0x39,0x69
+ ,0x4C,0x67,0x02,0xE0,0x3C,0x61,0x24,0x67,0x64,0x67
+ ,0x79,0x69,0x01,0x31,0x79,0x61,0x07,0x21,0x21,0x63
+ ,0x01,0x21,0xA1,0x63,0x0E,0x49,0x0A,0x68,0x01,0x32
+ ,0x0A,0x60,0xE6,0x64,0x00,0xF0,0x18,0xF8,0x01,0x23
+ ,0xDE,0x42,0x03,0xD0,0xE0,0x1D,0x45,0x30,0x00,0xF0
+ ,0x97,0xFA,0x20,0x1C,0x00,0xF0,0xCE,0xFA,0x68,0x68
+ ,0x04,0xB0,0xF0,0xBD,0x00,0xF0,0x09,0xF8,0x20,0x1C
+ ,0xF9,0xE7,0x00,0x00,0xB8,0x03,0x00,0x02,0xA1,0x46
+ ,0x00,0x00,0xD8,0x03,0x00,0x02,0x00,0xA3,0x18,0x47
+ ,0x00,0x30,0x0F,0xE1,0x3F,0x20,0xA0,0xE3,0x02,0x10
+ ,0x03,0xE0,0x00,0x10,0x81,0xE1,0x01,0xF0,0x21,0xE1
+ ,0x02,0x00,0xC3,0xE1,0x1E,0xFF,0x2F,0xE1,0x00,0xB5
+ ,0xFF,0xF7,0xD7,0xFB,0xFF,0xF7,0xB1,0xFD,0x00,0xF0
+ ,0x8F,0xFB,0x00,0xF0,0x95,0xFB,0x00,0xF0,0xF5,0xF9
+ ,0x00,0xF0,0x99,0xFB,0x00,0xF0,0x9F,0xFB,0x00,0xBD
+ ,0x00,0xA0,0x00,0x47,0x13,0x00,0xA0,0xE3,0x00,0xF0
+ ,0x21,0xE1,0x48,0x10,0x9F,0xE5,0x00,0x00,0x91,0xE5
+ ,0x00,0x00,0x50,0xE3,0xFC,0xFF,0xFF,0x0A,0xD3,0x20
+ ,0xA0,0xE3,0x02,0xF0,0x21,0xE1,0x34,0x10,0x9F,0xE5
+ ,0x00,0x00,0x81,0xE5,0x04,0x20,0x90,0xE5,0x18,0x30
+ ,0x90,0xE5,0x01,0x20,0x82,0xE2,0x04,0x20,0x80,0xE5
+ ,0x20,0x20,0x9F,0xE5,0x08,0xD0,0x90,0xE5,0x00,0x30
+ ,0x82,0xE5,0x03,0x00,0xBD,0xE8,0x00,0x00,0x50,0xE3
+ ,0x01,0xF0,0x6F,0xE1,0xF0,0x80,0xFD,0x08,0xFF,0xDF
+ ,0xFD,0xE8,0xBC,0x03,0x00,0x02,0xB8,0x03,0x00,0x02
+ ,0x40,0x04,0x00,0x02,0xF0,0xB5,0x82,0xB0,0x4E,0x4B
+ ,0x98,0x42,0x01,0xD0,0x02,0xB0,0xF0,0xBD,0x00,0x20
+ ,0x00,0x90,0x00,0x26,0xC0,0x20,0xFF,0xF7,0x9F,0xFF
+ ,0x4A,0x4D,0x29,0x68,0x09,0x68,0x01,0x91,0x00,0x29
+ ,0x01,0xD0,0x01,0xAA,0x8A,0x61,0x29,0x68,0x46,0x4C
+ ,0x0E,0x60,0x29,0x68,0x04,0x31,0x29,0x60,0x22,0x68
+ ,0x91,0x42,0x02,0xD1,0x43,0x49,0x09,0x68,0x29,0x60
+ ,0x43,0x49,0x0E,0x60,0xFF,0xF7,0x87,0xFF,0xC0,0x20
+ ,0xFF,0xF7,0x84,0xFF,0x01,0x99,0x00,0x29,0x5C,0xD0
+ ,0x01,0x9C,0x21,0x69,0xA1,0x42,0x01,0xD1,0x00,0x21
+ ,0x08,0xE0,0x62,0x69,0x4A,0x61,0x21,0x69,0x62,0x69
+ ,0x11,0x61,0x22,0x69,0x01,0xA9,0x91,0x61,0x21,0x69
+ ,0x01,0x91,0x21,0x68,0x20,0x29,0x03,0xD9,0x20,0x39
+ ,0x21,0x60,0x00,0x25,0x04,0xE0,0x27,0x1D,0xA2,0xCF
+ ,0x21,0x60,0x00,0x29,0x03,0xD0,0x69,0x46,0xA1,0x61
+ ,0x24,0x61,0x00,0xE0,0xA6,0x61,0xFF,0xF7,0x5E,0xFF
+ ,0x00,0x2D,0x02,0xD0,0x38,0x1C,0x00,0xF0,0xFC,0xFB
+ ,0xC0,0x20,0xFF,0xF7,0x56,0xFF,0xA2,0x69,0x69,0x46
+ ,0x8A,0x42,0x25,0xD1,0x21,0x68,0x20,0x29,0x01,0xD9
+ ,0x1F,0x21,0x00,0xE0,0x01,0x39,0x20,0x4D,0x89,0x00
+ ,0x2A,0x68,0x89,0x18,0x1F,0x4A,0x12,0x68,0x91,0x42
+ ,0x07,0xD3,0x89,0x1A,0x00,0xD5,0x03,0x31,0x1D,0x4A
+ ,0x89,0x10,0x12,0x68,0x89,0x00,0x89,0x18,0x0A,0x68
+ ,0x00,0x2A,0x08,0xD0,0x22,0x61,0x0A,0x68,0x52,0x69
+ ,0x62,0x61,0x14,0x61,0x0A,0x68,0x54,0x61,0xA1,0x61
+ ,0x03,0xE0,0x24,0x61,0xA1,0x61,0x64,0x61,0x0C,0x60
+ ,0xFF,0xF7,0x2A,0xFF,0xC0,0x20,0xFF,0xF7,0x27,0xFF
+ ,0x01,0x99,0x00,0x29,0xA2,0xD1,0x0F,0x49,0x09,0x68
+ ,0x00,0x29,0x10,0xD1,0x0E,0x4C,0x03,0x21,0x22,0x68
+ ,0x11,0x63,0x22,0x68,0x01,0x21,0x91,0x63,0x0C,0x4A
+ ,0x11,0x68,0x01,0x31,0x11,0x60,0xFF,0xF7,0x13,0xFF
+ ,0x20,0x68,0x00,0xF0,0xD0,0xF9,0x6C,0xE7,0xFF,0xF7
+ ,0x0D,0xFF,0x69,0xE7,0x4D,0x49,0x54,0x41,0x50,0x04
+ ,0x00,0x02,0x4C,0x04,0x00,0x02,0x48,0x04,0x00,0x02
+ ,0x54,0x04,0x00,0x02,0xB8,0x03,0x00,0x02,0xD8,0x03
+ ,0x00,0x02,0x90,0xB5,0x07,0x1C,0x00,0x6B,0x04,0x28
+ ,0x0C,0xD1,0xC0,0x20,0xFF,0xF7,0xF6,0xFE,0x0A,0x49
+ ,0x0A,0x68,0x01,0x32,0x0A,0x60,0xFF,0xF7,0xF0,0xFE
+ ,0x38,0x1C,0x00,0xF0,0x67,0xF8,0x90,0xBD,0xC0,0x20
+ ,0xFF,0xF7,0xE9,0xFE,0xBC,0x6E,0xFF,0xF7,0xE6,0xFE
+ ,0x00,0x2C,0xF6,0xD0,0x38,0x1C,0x00,0xF0,0x83,0xFB
+ ,0x90,0xBD,0xD8,0x03,0x00,0x02,0x80,0xB5,0x0C,0x4F
+ ,0x39,0x68,0x88,0x6C,0x49,0x6C,0x00,0xF0,0x76,0xFB
+ ,0xC0,0x20,0xFF,0xF7,0xD4,0xFE,0x3A,0x68,0x01,0x21
+ ,0x11,0x63,0x3A,0x68,0x91,0x63,0x06,0x49,0x0A,0x68
+ ,0x01,0x32,0x0A,0x60,0xFF,0xF7,0xC9,0xFE,0x38,0x68
+ ,0x00,0xF0,0x86,0xF9,0x80,0xBD,0x00,0x00,0xB8,0x03
+ ,0x00,0x02,0xD8,0x03,0x00,0x02,0x00,0xA3,0x18,0x47
+ ,0x10,0x20,0x90,0xE5,0x03,0x20,0xC2,0xE3,0x48,0x20
+ ,0x42,0xE2,0x01,0x30,0xA0,0xE3,0x00,0x30,0x82,0xE5
+ ,0x33,0x30,0xA0,0xE3,0x04,0x30,0x82,0xE5,0x00,0x30
+ ,0xA0,0xE3,0x08,0x30,0x82,0xE5,0x0C,0x30,0x82,0xE5
+ ,0x10,0x30,0x82,0xE5,0x14,0x30,0x82,0xE5,0x18,0x30
+ ,0x82,0xE5,0x1C,0x30,0x82,0xE5,0x20,0x30,0x82,0xE5
+ ,0x24,0x30,0x82,0xE5,0x28,0x30,0x82,0xE5,0x2C,0x30
+ ,0x82,0xE5,0x0C,0x30,0x90,0xE5,0x30,0x30,0x82,0xE5
+ ,0x00,0x30,0xA0,0xE3,0x34,0x30,0x82,0xE5,0x38,0x30
+ ,0x82,0xE5,0x3C,0x30,0x82,0xE5,0x40,0x10,0x82,0xE5
+ ,0x44,0x30,0x82,0xE5,0x08,0x20,0x80,0xE5,0x1E,0xFF
+ ,0x2F,0xE1,0xF0,0xB5,0x00,0x24,0x07,0x1C,0xC0,0x20
+ ,0xFF,0xF7,0x80,0xFE,0x29,0x49,0x2A,0x4D,0x0A,0x68
+ ,0x01,0x3A,0x0A,0x60,0xBA,0x6B,0x00,0x21,0x00,0x2A
+ ,0x06,0xD0,0x3A,0x6B,0x01,0x2A,0x39,0xD0,0x02,0x2A
+ ,0x37,0xD0,0xB9,0x63,0x07,0xE0,0x3A,0x6B,0x00,0x2A
+ ,0x32,0xD0,0x7A,0x6B,0x00,0x2A,0x03,0xD0,0x79,0x63
+ ,0x03,0x21,0x39,0x63,0x2B,0xE0,0x39,0x63,0xF9,0x6A
+ ,0x1D,0x4B,0x8E,0x00,0x9A,0x59,0x00,0x2A,0x05,0xD0
+ ,0x51,0x6A,0x0F,0x62,0x57,0x62,0x79,0x62,0x3A,0x62
+ ,0x1E,0xE0,0x9F,0x51,0x3F,0x62,0x7F,0x62,0x17,0x4A
+ ,0x3B,0x6C,0x16,0x68,0x33,0x43,0x13,0x60,0x2A,0x68
+ ,0x15,0x4B,0x00,0x2A,0x02,0xD1,0x2F,0x60,0x19,0x60
+ ,0x0F,0xE0,0x1E,0x68,0xB1,0x42,0x0C,0xD2,0x19,0x60
+ ,0xD3,0x6B,0x8B,0x42,0x08,0xD9,0xD1,0x6A,0x8B,0x42
+ ,0x04,0xD0,0x0E,0x49,0x12,0x6C,0x0B,0x68,0x1A,0x43
+ ,0x0A,0x60,0x2F,0x60,0xFF,0xF7,0x38,0xFE,0x0B,0x48
+ ,0x00,0x68,0x29,0x68,0x88,0x42,0x04,0xD0,0x0A,0x48
+ ,0x00,0x68,0x00,0x28,0x00,0xD1,0x01,0x24,0x20,0x1C
+ ,0xF0,0xBD,0xD8,0x03,0x00,0x02,0xBC,0x03,0x00,0x02
+ ,0xE0,0x0B,0x00,0x02,0xCC,0x03,0x00,0x02,0xD4,0x03
+ ,0x00,0x02,0xD0,0x03,0x00,0x02,0xB8,0x03,0x00,0x02
+ ,0xC8,0x03,0x00,0x02,0x00,0xA0,0x00,0x47,0x00,0x00
+ ,0xA0,0xE3,0x00,0x10,0x0F,0xE1,0x20,0x10,0x81,0xE3
+ ,0xF3,0x40,0x2D,0xE9,0xD3,0x20,0xA0,0xE3,0x02,0xF0
+ ,0x21,0xE1,0x2C,0x30,0x9F,0xE5,0x00,0x00,0x93,0xE5
+ ,0x28,0x20,0x9F,0xE5,0x00,0x10,0x92,0xE5,0x08,0xD0
+ ,0x80,0xE5,0x00,0x40,0xA0,0xE3,0x00,0x00,0x51,0xE3
+ ,0x02,0x00,0x00,0x0A,0x1C,0x10,0x90,0xE5,0x00,0x40
+ ,0x82,0xE5,0x18,0x10,0x80,0xE5,0x00,0x40,0x83,0xE5
+ ,0x0A,0xFF,0xFF,0xEA,0xB8,0x03,0x00,0x02,0x40,0x04
+ ,0x00,0x02,0x02,0x48,0x00,0x21,0x01,0x60,0x41,0x60
+ ,0xF7,0x46,0x00,0x00,0x6C,0x04,0x00,0x02,0x90,0xB5
+ ,0x07,0x1C,0xC0,0x20,0xFF,0xF7,0xE3,0xFD,0xB9,0x69
+ ,0x00,0x24,0x00,0x29,0x16,0xD0,0x3A,0x69,0xBA,0x42
+ ,0x04,0xD1,0x0A,0x68,0xBA,0x42,0x0F,0xD1,0x0C,0x60
+ ,0x0D,0xE0,0x79,0x69,0x51,0x61,0x39,0x69,0x7A,0x69
+ ,0x11,0x61,0xB9,0x69,0x0A,0x68,0xBA,0x42,0x04,0xD1
+ ,0x3A,0x69,0x91,0x61,0x39,0x69,0xBA,0x69,0x11,0x60
+ ,0xBC,0x61,0xFF,0xF7,0xC6,0xFD,0x20,0x1C,0x90,0xBD
+ ,0xB0,0xB5,0x07,0x1C,0xC4,0x6E,0xC0,0x20,0xFF,0xF7
+ ,0xBE,0xFD,0xB9,0x6E,0x00,0x29,0x38,0xD0,0x00,0x2C
+ ,0x36,0xD0,0x21,0x68,0x1C,0x4B,0x99,0x42,0x32,0xD1
+ ,0x00,0x25,0xBD,0x66,0x39,0x6F,0xB9,0x42,0x01,0xD1
+ ,0x25,0x61,0x06,0xE0,0x21,0x61,0x79,0x6F,0x3A,0x6F
+ ,0x51,0x67,0x39,0x6F,0x7A,0x6F,0x11,0x67,0x61,0x69
+ ,0x01,0x39,0x61,0x61,0x39,0x6B,0x07,0x29,0x10,0xD1
+ ,0xFA,0x1D,0x79,0x32,0x51,0x60,0x10,0x49,0x0A,0x68
+ ,0x01,0x32,0x0A,0x60,0xFF,0xF7,0x98,0xFD,0x38,0x1C
+ ,0xFF,0xF7,0x0F,0xFF,0x00,0x28,0x04,0xD0,0xFF,0xF7
+ ,0x75,0xFF,0x01,0xE0,0xFF,0xF7,0x8E,0xFD,0x78,0x6E
+ ,0x00,0x28,0x04,0xD0,0xF8,0x1D,0x45,0x30,0xFF,0xF7
+ ,0x9F,0xFF,0x00,0xE0,0xFD,0x64,0xC0,0x20,0xFF,0xF7
+ ,0x82,0xFD,0xFF,0xF7,0x80,0xFD,0xB0,0xBD,0x00,0x00
+ ,0x4E,0x44,0x56,0x44,0xD8,0x03,0x00,0x02,0x80,0xB5
+ ,0x07,0x1C,0xC0,0x20,0xFF,0xF7,0x75,0xFD,0x39,0x68
+ ,0x00,0x29,0x27,0xD0,0xBA,0x69,0x00,0x2A,0x24,0xD1
+ ,0x20,0x29,0x01,0xD9,0x1F,0x21,0x00,0xE0,0x01,0x39
+ ,0x11,0x4A,0x89,0x00,0x12,0x68,0x89,0x18,0x10,0x4A
+ ,0x12,0x68,0x91,0x42,0x07,0xD3,0x89,0x1A,0x00,0xD5
+ ,0x03,0x31,0x0E,0x4A,0x89,0x10,0x12,0x68,0x89,0x00
+ ,0x89,0x18,0x0A,0x68,0x00,0x2A,0x08,0xD0,0x3A,0x61
+ ,0x0A,0x68,0x52,0x69,0x7A,0x61,0x17,0x61,0x0A,0x68
+ ,0x57,0x61,0xB9,0x61,0x03,0xE0,0x3F,0x61,0xB9,0x61
+ ,0x7F,0x61,0x0F,0x60,0xFF,0xF7,0x48,0xFD,0x00,0x20
+ ,0x80,0xBD,0x50,0x04,0x00,0x02,0x4C,0x04,0x00,0x02
+ ,0x48,0x04,0x00,0x02,0xF0,0xB5,0x05,0x1C,0xC0,0x20
+ ,0xFF,0xF7,0x3B,0xFD,0x67,0x49,0x67,0x4C,0x0A,0x68
+ ,0x67,0x4F,0x01,0x3A,0x0A,0x60,0xAA,0x6B,0x00,0x2A
+ ,0x74,0xD0,0x00,0x26,0xAE,0x63,0xEA,0x6A,0x2B,0x6A
+ ,0xAB,0x42,0x26,0xD0,0x69,0x6A,0x59,0x62,0x29,0x6A
+ ,0x6B,0x6A,0x19,0x62,0x91,0x00,0x5F,0x4A,0x53,0x58
+ ,0xAB,0x42,0x11,0xD1,0x2B,0x6A,0x53,0x50,0x5D,0x49
+ ,0x0B,0x68,0x00,0x2B,0x02,0xD0,0x2E,0x6C,0xB3,0x43
+ ,0x0B,0x60,0x5B,0x49,0x0B,0x68,0x9D,0x42,0x04,0xD1
+ ,0x5A,0x4B,0x1B,0x68,0x9B,0x00,0xD2,0x58,0x0A,0x60
+ ,0xFF,0xF7,0x0E,0xFD,0x55,0x49,0x38,0x68,0x09,0x68
+ ,0x88,0x42,0x60,0xD0,0x20,0x68,0x00,0x28,0x5E,0xD1
+ ,0x95,0xE0,0x00,0x26,0x4E,0x4B,0x92,0x00,0x9E,0x50
+ ,0x2A,0x6C,0xD3,0x43,0x50,0x4A,0x16,0x68,0x33,0x40
+ ,0x13,0x60,0x4B,0x4A,0x12,0x68,0x00,0x2A,0x03,0xD0
+ ,0x2E,0x6C,0xB2,0x43,0x48,0x4E,0x32,0x60,0x1A,0x06
+ ,0x12,0x0E,0x02,0xD0,0x49,0x4B,0x9A,0x5C,0x14,0xE0
+ ,0x1B,0x0A,0x1A,0x06,0x12,0x0E,0x03,0xD0,0x46,0x4B
+ ,0x9A,0x5C,0x08,0x32,0x0C,0xE0,0x1B,0x0A,0x1A,0x06
+ ,0x12,0x0E,0x03,0xD0,0x42,0x4B,0x9A,0x5C,0x10,0x32
+ ,0x04,0xE0,0x1A,0x0A,0x29,0xD0,0x3F,0x4B,0x9A,0x5C
+ ,0x18,0x32,0x3B,0x4B,0x1A,0x60,0x39,0x4A,0x12,0x68
+ ,0x95,0x42,0x4D,0xD1,0x38,0x4E,0x35,0x4B,0x32,0x68
+ ,0x36,0x4D,0x92,0x00,0x9A,0x58,0x2A,0x60,0x33,0x4A
+ ,0x12,0x68,0x00,0x2A,0x42,0xD0,0x0E,0x1C,0x09,0x68
+ ,0x01,0x31,0x31,0x60,0xFF,0xF7,0xC1,0xFC,0xC0,0x20
+ ,0xFF,0xF7,0xBE,0xFC,0x00,0xE0,0x42,0xE0,0x31,0x68
+ ,0x01,0x39,0x31,0x60,0x2A,0x49,0x0A,0x68,0x11,0x06
+ ,0x09,0x0E,0x0D,0xD0,0x2B,0x4B,0x59,0x5C,0x1E,0xE0
+ ,0x28,0x4B,0x20,0x21,0x19,0x60,0x25,0x49,0x00,0x26
+ ,0x0E,0x60,0xFF,0xF7,0xA9,0xFC,0x38,0xE0,0x39,0xE0
+ ,0x38,0xE0,0x13,0x0A,0x19,0x06,0x09,0x0E,0x03,0xD0
+ ,0x22,0x4B,0x59,0x5C,0x08,0x31,0x0B,0xE0,0x1B,0x0A
+ ,0x19,0x06,0x09,0x0E,0x03,0xD0,0x1E,0x4B,0x59,0x5C
+ ,0x10,0x31,0x03,0xE0,0x19,0x0A,0x1C,0x4B,0x59,0x5C
+ ,0x18,0x31,0x15,0x4B,0x89,0x00,0x59,0x58,0x17,0x4E
+ ,0xCB,0x6B,0x36,0x68,0xB3,0x42,0x05,0xD8,0x29,0x60
+ ,0x09,0x6C,0x11,0x4B,0xC9,0x43,0x11,0x40,0x19,0x60
+ ,0xFF,0xF7,0x82,0xFC,0x0F,0x4A,0x38,0x68,0x11,0x68
+ ,0x88,0x42,0x0F,0xD0,0x20,0x68,0x00,0x28,0x0C,0xD1
+ ,0x09,0xE0,0xFF,0xF7,0x77,0xFC,0x0A,0x49,0x38,0x68
+ ,0x09,0x68,0x88,0x42,0x04,0xD0,0x20,0x68,0x00,0x28
+ ,0x01,0xD1,0xFF,0xF7,0x51,0xFE,0xF0,0xBD,0xD8,0x03
+ ,0x00,0x02,0xC8,0x03,0x00,0x02,0xB8,0x03,0x00,0x02
+ ,0xE0,0x0B,0x00,0x02,0xD0,0x03,0x00,0x02,0xBC,0x03
+ ,0x00,0x02,0xD4,0x03,0x00,0x02,0xCC,0x03,0x00,0x02
+ ,0xE0,0x0A,0x00,0x02,0x02,0x48,0x00,0x21,0x01,0x60
+ ,0x41,0x60,0xF7,0x46,0x00,0x00,0x74,0x04,0x00,0x02
+ ,0x02,0x48,0x00,0x21,0x01,0x60,0x41,0x60,0xF7,0x46
+ ,0x00,0x00,0x7C,0x04,0x00,0x02,0x02,0x48,0x00,0x21
+ ,0x01,0x60,0x41,0x60,0xF7,0x46,0x00,0x00,0x84,0x04
+ ,0x00,0x02,0x02,0x48,0x00,0x21,0x01,0x60,0x41,0x60
+ ,0xF7,0x46,0x00,0x00,0x8C,0x04,0x00,0x02,0xBC,0x46
+ ,0x03,0x1C,0x08,0x43,0x80,0x07,0x13,0xD1,0x12,0x1F
+ ,0x05,0xD3,0x01,0xCB,0x80,0xC9,0xC0,0x1B,0x04,0xD1
+ ,0x12,0x1F,0xF9,0xD2,0xD2,0x1C,0x0C,0xD3,0x02,0xE0
+ ,0x1B,0x1F,0x09,0x1F,0xD2,0x1C,0x18,0x78,0x0F,0x78
+ ,0xC0,0x1B,0x04,0xD1,0x5B,0x1C,0x49,0x1C,0x52,0x1E
+ ,0xF7,0xD2,0x00,0x20,0x67,0x46,0xF7,0x46,0x43,0x1A
+ ,0x93,0x42,0x30,0xD3,0x84,0x46,0x8B,0x07,0x07,0xD0
+ ,0x52,0x1E,0x29,0xD3,0x0B,0x78,0x03,0x70,0x40,0x1C
+ ,0x49,0x1C,0x8B,0x07,0xF7,0xD1,0x83,0x07,0x17,0xD1
+ ,0x10,0x3A,0x05,0xD3,0xB0,0xB4,0xB8,0xC9,0xB8,0xC0
+ ,0x10,0x3A,0xFB,0xD2,0xB0,0xBC,0x0C,0x32,0x0F,0xD3
+ ,0x08,0xC9,0x08,0xC0,0x12,0x1F,0xFB,0xD2,0x0A,0xE0
+ ,0x08,0xC9,0x03,0x70,0x1B,0x0A,0x43,0x70,0x1B,0x0A
+ ,0x83,0x70,0x1B,0x0A,0xC3,0x70,0x00,0x1D,0x12,0x1F
+ ,0xF4,0xD2,0xD2,0x1C,0x05,0xD3,0x0B,0x78,0x03,0x70
+ ,0x49,0x1C,0x40,0x1C,0x52,0x1E,0xF9,0xD2,0x60,0x46
+ ,0xF7,0x46,0x03,0x1C,0x0B,0x43,0x13,0x43,0x9B,0x07
+ ,0x04,0xD1,0x12,0x1F,0x8B,0x58,0x83,0x50,0xFB,0xD1
+ ,0xF7,0x46,0x52,0x1E,0x8B,0x5C,0x83,0x54,0xFB,0xD1
+ ,0xF7,0x46,0x00,0x00,0x4B,0x08,0x02,0x1C,0x02,0xD1
+ ,0x00,0xF0,0x79,0xF8,0x52,0x00,0x9A,0x42,0xFC,0xD9
+ ,0x00,0x23,0x91,0x42,0x05,0xD2,0xDB,0x18,0x82,0x42
+ ,0x06,0xD0,0x52,0x08,0x91,0x42,0xF9,0xD3,0x5B,0x41
+ ,0x89,0x1A,0x82,0x42,0xF8,0xD1,0x18,0x1C,0xF7,0x46
+ ,0x00,0x00,0xCB,0x17,0x59,0x40,0xC9,0x1A,0xC2,0x17
+ ,0x50,0x40,0x80,0x1A,0x0C,0xB4,0x4B,0x08,0x02,0x1C
+ ,0x02,0xD1,0x00,0xF0,0x5A,0xF8,0x52,0x00,0x9A,0x42
+ ,0xFC,0xD9,0x00,0x23,0x91,0x42,0x05,0xD2,0xDB,0x18
+ ,0x82,0x42,0x06,0xD0,0x52,0x08,0x91,0x42,0xF9,0xD3
+ ,0x5B,0x41,0x89,0x1A,0x82,0x42,0xF8,0xD1,0x18,0x1C
+ ,0x0C,0xBC,0x5A,0x40,0x50,0x40,0x80,0x1A,0x59,0x40
+ ,0xC9,0x1A,0x70,0x47,0xB0,0xB5,0x0D,0x48,0x42,0x6E
+ ,0x03,0x6E,0x97,0x00,0xC1,0x1F,0x75,0x39,0x9C,0x00
+ ,0x0C,0x59,0xCD,0x59,0x2C,0x19,0xCC,0x51,0x59,0x1E
+ ,0x36,0x23,0x00,0x29,0x01,0x66,0x03,0xDA,0x51,0x1E
+ ,0x41,0x66,0x03,0x66,0x03,0xE0,0x51,0x1E,0x41,0x66
+ ,0x00,0xD5,0x43,0x66,0x60,0x00,0x40,0x08,0xB0,0xBD
+ ,0x10,0x05,0x00,0x02,0x80,0xB5,0x09,0x49,0x17,0x22
+ ,0x0A,0x66,0x36,0x22,0x4A,0x66,0x07,0x4A,0x00,0x21
+ ,0x03,0x0C,0x1F,0x18,0x8B,0x00,0xD7,0x50,0x05,0x4B
+ ,0x01,0x31,0x58,0x43,0x05,0x4B,0xC0,0x18,0x37,0x29
+ ,0xF4,0xDB,0x80,0xBD,0x10,0x05,0x00,0x02,0x94,0x04
+ ,0x00,0x02,0xCD,0x0D,0x01,0x00,0xE1,0x19,0xD6,0x66
+ ,0x00,0x47,0x08,0x47,0x10,0x47,0x18,0x47,0x20,0x47
+ ,0x28,0x47,0x30,0x47,0x38,0x47,0x78,0x47,0x00,0x00
+ ,0x2C,0xC0,0x9F,0xE5,0xFF,0x7F,0x8C,0xE8,0x3C,0xC0
+ ,0x8C,0xE2,0x0C,0x00,0x8F,0xE2,0x3C,0x10,0x4C,0xE2
+ ,0x04,0xE0,0x4E,0xE2,0x00,0xE0,0x8C,0xE5,0x6F,0xED
+ ,0xFF,0xEA,0x20,0x00,0x00,0x80,0x44,0x69,0x76,0x69
+ ,0x64,0x65,0x20,0x62,0x79,0x20,0x7A,0x65,0x72,0x6F
+ ,0x00,0x00,0x78,0x05,0x00,0x02,0x78,0x47,0x00,0x00
+ ,0x01,0xE0,0x8E,0xE3,0x04,0x00,0xA0,0xE3,0x00,0x00
+ ,0x90,0xE5,0xFF,0x04,0x00,0xE2,0xEA,0x04,0x50,0xE3
+ ,0x01,0x00,0xA0,0x03,0x00,0x00,0xA0,0x13,0x1E,0xFF
+ ,0x2F,0xE1,0x78,0x47,0x00,0x00,0x01,0xE0,0x8E,0xE3
+ ,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0x00,0x00,0x01,0xE0
+ ,0x8E,0xE3,0x05,0x0B,0x40,0xE2,0x1B,0x0B,0x50,0xE3
+ ,0x01,0x00,0xA0,0x33,0x00,0x00,0xA0,0x23,0x1E,0xFF
+ ,0x2F,0xE1,0x78,0x47,0x00,0x00,0x01,0xE0,0x8E,0xE3
+ ,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0x00,0x00,0x01,0xE0
+ ,0x8E,0xE3,0x1E,0xFF,0x2F,0xE1,0x78,0x47,0x00,0x00
+ ,0x01,0xE0,0x8E,0xE3,0x00,0x00,0xA0,0xE3,0x1E,0xFF
+ ,0x2F,0xE1,0x78,0x47,0x00,0x00,0x01,0xE0,0x8E,0xE3
+ ,0x00,0x00,0x8F,0xE2,0x1E,0xFF,0x2F,0xE1,0x55,0x6E
+ ,0x6B,0x6E,0x6F,0x77,0x6E,0x20,0x45,0x72,0x72,0x6F
+ ,0x72,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x42,0x72
+ ,0x61,0x6E,0x63,0x68,0x20,0x54,0x68,0x72,0x6F,0x75
+ ,0x67,0x68,0x20,0x5A,0x65,0x72,0x6F,0x00,0x01,0x00
+ ,0x02,0x00,0x55,0x6E,0x64,0x65,0x66,0x69,0x6E,0x65
+ ,0x64,0x20,0x49,0x6E,0x73,0x74,0x72,0x75,0x63,0x74
+ ,0x69,0x6F,0x6E,0x00,0x00,0x00,0x02,0x00,0x02,0x00
+ ,0x55,0x6E,0x64,0x65,0x66,0x69,0x6E,0x65,0x64,0x20
+ ,0x53,0x57,0x49,0x20,0x49,0x6E,0x73,0x74,0x72,0x75
+ ,0x63,0x74,0x69,0x6F,0x6E,0x00,0x00,0x00,0x03,0x00
+ ,0x02,0x00,0x50,0x72,0x65,0x66,0x65,0x74,0x63,0x68
+ ,0x20,0x41,0x62,0x6F,0x72,0x74,0x00,0x00,0x04,0x00
+ ,0x02,0x00,0x44,0x61,0x74,0x61,0x20,0x41,0x62,0x6F
+ ,0x72,0x74,0x00,0x00,0x05,0x00,0x02,0x00,0x41,0x64
+ ,0x64,0x72,0x65,0x73,0x73,0x20,0x45,0x78,0x63,0x65
+ ,0x70,0x74,0x69,0x6F,0x6E,0x00,0x00,0x00,0x06,0x00
+ ,0x02,0x00,0x55,0x6E,0x68,0x61,0x6E,0x64,0x6C,0x65
+ ,0x64,0x20,0x49,0x6E,0x74,0x65,0x72,0x72,0x75,0x70
+ ,0x74,0x00,0x07,0x00,0x02,0x00,0x55,0x6E,0x68,0x61
+ ,0x6E,0x64,0x6C,0x65,0x64,0x20,0x46,0x61,0x73,0x74
+ ,0x20,0x49,0x6E,0x74,0x65,0x72,0x72,0x75,0x70,0x74
+ ,0x00,0x00,0x00,0x00,0x44,0x4C,0x00,0x00,0x5C,0x4C
+ ,0x00,0x00,0x78,0x4C,0x00,0x00,0x98,0x4C,0x00,0x00
+ ,0xAC,0x4C,0x00,0x00,0xBC,0x4C,0x00,0x00,0xD4,0x4C
+ ,0x00,0x00,0xEC,0x4C,0x00,0x00,0x28,0x20,0x4F,0xE2
+ ,0x00,0x01,0x92,0xE7,0x07,0xED,0xFF,0xEA,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x40,0x2D,0xE9,0x50,0x00,0x9F,0xE5
+ ,0x50,0x10,0x9F,0xE5,0x01,0x20,0xA0,0xE1,0x4C,0x40
+ ,0x9F,0xE5,0x04,0x20,0x82,0xE0,0x05,0x00,0x00,0xEB
+ ,0x44,0x20,0x9F,0xE5,0x44,0x00,0x9F,0xE5,0x00,0x10
+ ,0xA0,0xE1,0x02,0x10,0x81,0xE0,0x05,0x00,0x00,0xEB
+ ,0x00,0x80,0xBD,0xE8,0x02,0x00,0x51,0xE1,0x04,0x30
+ ,0x90,0x34,0x04,0x30,0x81,0x34,0xFB,0xFF,0xFF,0x3A
+ ,0x0E,0xF0,0xA0,0xE1,0x00,0x20,0xA0,0xE3,0x01,0x00
+ ,0x50,0xE1,0x04,0x20,0x80,0x34,0xFB,0xFF,0xFF,0x3A
+ ,0x0E,0xF0,0xA0,0xE1,0xE8,0x4D,0x00,0x00,0x00,0x00
+ ,0x00,0x02,0xB8,0x05,0x00,0x00,0xB8,0x07,0x00,0x00
+ ,0xB8,0x05,0x00,0x02,0x00,0x00,0x00,0x00,0x14,0x00
+ ,0x0A,0x00,0x90,0x00,0x30,0x00,0x08,0x06,0x07,0x00
+ ,0x82,0x84,0x8B,0x96,0x09,0x04,0x02,0x41,0x00,0x00
+ ,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11,0x11
+ ,0x11,0x11,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,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,0x04,0xAC,0x6C
+ ,0x32,0x70,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x64,0x00,0x30,0x75,0x64,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x04,0x03,0x00,0x04,0xAC,0x6C
+ ,0x32,0x70,0x55,0x4E,0x48,0x00,0x00,0x00,0x00,0x00
+ ,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,0x01,0x00,0x00,0x00,0x00
+ ,0x45,0x55,0x00,0x00,0x00,0x00,0x00,0xFA,0x00,0x00
+ ,0x00,0xFA,0x00,0x00,0x2A,0x09,0x2A,0x09,0x1F,0x00
+ ,0xFF,0x00,0x08,0x08,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x02,0x00,0x41,0x54,0x4D,0x45,0x4C,0x5F
+ ,0x41,0x50,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0xFF,0xFF,0xFF,0xFF
+ ,0xFF,0xFF,0x01,0x00,0x05,0x00,0x00,0x00,0x00,0x08
+ ,0x00,0x00,0x00,0x00,0x01,0x01,0x00,0x64,0x02,0x10
+ ,0x1E,0x1E,0x1E,0x1E,0x00,0x00,0x28,0x28,0x28,0x00
+ ,0x00,0x32,0x3C,0x46,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,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,0x01
+ ,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01
+ ,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01
+ ,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x00,0x01
+ ,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x00,0x01,0x01
+ ,0x00,0x00,0x01,0x01,0x00,0x00,0x01,0x01,0x01,0x00
+ ,0x01,0x01,0x01,0x00,0x01,0x01,0x01,0x00,0x01,0x01
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x02,0x04,0x08,0x10,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xCC,0x01
+ ,0x00,0x02,0x00,0x00,0x00,0x07,0x03,0x01,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x12,0x01,0x10,0x01,0xFE,0x01
+ ,0x00,0x08,0xEB,0x03,0x05,0x76,0x00,0x01,0x00,0x00
+ ,0x00,0x01,0x09,0x02,0x20,0x00,0x01,0x01,0x00,0x80
+ ,0xFA,0x09,0x04,0x00,0x00,0x02,0xFF,0x00,0xFF,0x00
+ ,0x07,0x05,0x85,0x02,0x40,0x00,0x00,0x07,0x05,0x02
+ ,0x02,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0xFF,0x07,0xFF,0x07,0xFF,0x1F
+ ,0x00,0x06,0x00,0x1E,0x00,0x20,0xFF,0x3F,0xFC,0x01
+ ,0x01,0x01,0x01,0x0A,0x0A,0x0E,0x01,0x03,0x00,0x00
+ ,0x00,0x00,0xAA,0xAA,0x03,0x00,0x00,0x00,0xAA,0xAA
+ ,0x03,0x00,0x00,0xF8,0x37,0x81,0xF3,0x80,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x03,0x00,0x00,0x00
+ ,0x58,0x00,0x00,0x00,0x58,0x00,0x00,0x00,0xD8,0x05
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00
+ ,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00
+ ,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00
+ ,0x00,0x00,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00
+ ,0x04,0x00,0x00,0x00,0x04,0x00,0x00,0x00,0xF6,0x07
+ ,0x00,0x00,0xFB,0x07,0x00,0x00,0x00,0x08,0x00,0x00
+ ,0x05,0x08,0x00,0x00,0x0A,0x08,0x00,0x00,0x0F,0x08
+ ,0x00,0x00,0x14,0x08,0x00,0x00,0x19,0x08,0x00,0x00
+ ,0x1E,0x08,0x00,0x00,0x23,0x08,0x00,0x00,0x28,0x08
+ ,0x00,0x00,0x2D,0x08,0x00,0x00,0x32,0x08,0x00,0x00
+ ,0x3E,0x08,0x00,0x00,0x43,0x6F,0x70,0x79,0x72,0x69
+ ,0x67,0x68,0x74,0x20,0x28,0x63,0x29,0x20,0x31,0x39
+ ,0x39,0x36,0x2D,0x32,0x30,0x30,0x30,0x20,0x45,0x78
+ ,0x70,0x72,0x65,0x73,0x73,0x20,0x4C,0x6F,0x67,0x69
+ ,0x63,0x20,0x49,0x6E,0x63,0x2E,0x20,0x2A,0x20,0x54
+ ,0x68,0x72,0x65,0x61,0x64,0x58,0x20,0x54,0x48,0x55
+ ,0x4D,0x42,0x2D,0x46,0x2F,0x41,0x52,0x4D,0x20,0x56
+ ,0x65,0x72,0x73,0x69,0x6F,0x6E,0x20,0x47,0x33,0x2E
+ ,0x30,0x66,0x2E,0x33,0x2E,0x30,0x62,0x20,0x2A,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0xF0,0xF0,0xF0,0xF0,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x47,0x2D,0x47,0x42,0x2D,0x47,0x4C,0x2D
+ ,0x4D,0x2D,0x44,0x2D,0x44,0x4C,0x2D,0x4B,0x4D,0x4C
+ ,0x2D,0x43,0x4D,0x52,0x2D,0x48,0x4D,0x52,0x2D,0x4D
+ ,0x4C,0x32,0x2D,0x47,0x5A,0x2D,0x4B,0x48,0x32,0x2D
+ ,0x43,0x4D,0x2D,0x52,0x50,0x2D,0x54,0x43,0x2D,0x4E
+ ,0x48,0x2D,0x54,0x44,0x2D,0x41,0x50,0x2D,0x48,0x41
+ ,0x2D,0x47,0x46,0x2D,0x44,0x44,0x2D,0x41,0x54,0x2D
+ ,0x4D,0x46,0x2D,0x4D,0x53,0x2D,0x44,0x57,0x2D,0x55
+ ,0x53,0x41,0x2D,0x43,0x41,0x2D,0x53,0x44,0x2D,0x53
+ ,0x44,0x53,0x55,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,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
+ ,0x85,0x8E,0xD7,0x66,0x09,0x8C,0xD3,0xD5,0xF5,0xD8
+ ,0x09,0x0A,0xFB,0x87,0x1F,0xBF,0x67,0xF7,0x8D,0xCB
+ ,0x69,0x07,0xF7,0xBD,0x34,0x12,0x3D,0x50,0xC8,0x84
+ ,0x4F,0x7F,0xA3,0x02,0xDE,0x61,0xAE,0x8D,0x40,0xA7
+ ,0xE8,0xBD,0x24,0x7A,0xEA,0xA2,0x15,0x51,0x57,0x2E
+ ,0xE6,0xBB,0xFF,0x7F,0xD5,0xF6,0x7A,0x83,0x2A,0x63
+ ,0x77,0x1D,0x86,0x13,0x7C,0x2E,0x9F,0xE1,0x05,0x57
+ ,0x5F,0x69,0x2E,0x6B,0x93,0x87,0x6E,0x9A,0xA1,0x50
+ ,0x94,0x0E,0x8B,0x72,0xAE,0x55,0xCC,0xC5,0xB1,0x8A
+ ,0x0A,0xB1,0xD7,0x72,0x6F,0x85,0x17,0x5C,0x22,0xD0
+ ,0xA3,0xFD,0xC4,0x51,0x61,0x98,0xED,0x89,0x9F,0x82
+ ,0xDB,0xF1,0x9D,0xC5,0xFB,0xBC,0x89,0xC1,0xEE,0x83
+ ,0x59,0xB1,0x59,0x63,0x30,0x5C,0x50,0xCC,0xC9,0x5A
+ ,0xBC,0x9C,0xF9,0x30,0xE2,0x2F,0x42,0x5E,0xF6,0x39
+ ,0xD2,0x7B,0x15,0x75,0xFB,0x58,0xC1,0x40,0x3E,0x9A
+ ,0xEB,0x27,0xD9,0xA2,0x82,0xC5,0xC2,0xD6,0x69,0x05
+ ,0xB3,0x30,0x8E,0xED,0xD2,0xDD,0x83,0x10,0x41,0xA4
+ ,0x1D,0x1F,0x15,0xE2,0x60,0x56,0xC5,0x2F,0xF3,0x04
+ ,0x99,0xEF,0x8E,0xE1,0x08,0x32,0x59,0x4A,0x4C,0xED
+ ,0x7B,0x5B,0x40,0xFC,0x02,0x81,0xD9,0x41,0x53,0x51
+ ,0xFA,0x3D,0xFF,0xAC,0xB5,0x6C,0x09,0x6D,0x1D,0xCC
+ ,0xB3,0x2B,0xFF,0x15,0x3D,0x25,0x17,0x00,0x00,0x00
+ ,0x36,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00
+ ,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00};
diff --git a/rom2h.c b/rom2h.c
new file mode 100644
index 0000000..da44517
--- /dev/null
+++ b/rom2h.c
@@ -0,0 +1,39 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#define MAX_BUF 0x8000
+
+int main(int argc, char *argv[])
+{
+ unsigned char *buf;
+ FILE *fptr;
+ int size, i;
+
+ if(argc == 2){
+ buf = (char *)malloc(MAX_BUF);
+ fptr = fopen(argv[1], "r");
+ if(fptr){
+ printf("unsigned char InternalRFMD[] = {");
+
+ size = fread(buf, 1, MAX_BUF, fptr);
+
+ for(i = 0; i < size; i++){
+ if((i % 10) == 0)
+ printf("\n ");
+ printf("0x%02x,", buf[i]);
+ // printf("0x%02x,0x%02x,", buf[i+1], buf[i]);
+ }
+ fclose(fptr);
+
+ printf("\n};\n");
+ }else{
+ fprintf(stderr, "could not open %s: %s\n", argv[1], strerror(errno));
+ exit(EXIT_FAILURE);
+ }
+ free(buf);
+ }
+ exit(0);
+}
diff --git a/usbdfu.c b/usbdfu.c
new file mode 100644
index 0000000..9a9cf99
--- /dev/null
+++ b/usbdfu.c
@@ -0,0 +1,735 @@
+/* -*- linux-c -*- */
+/*
+ * USB Device Firmware Uploader
+ *
+ * Copyright (c) 2003 Oliver Kurth <oku@masqmail.cx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ * 2003_01_19 0.1:
+ * - initial release
+ *
+ * TODO:
+ * - make it more generic, so that it works with devices other than
+ * at76c503
+ */
+
+#include <linux/config.h>
+#include <linux/kernel.h>
+#include <linux/sched.h>
+#include <linux/signal.h>
+#include <linux/errno.h>
+#include <linux/poll.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/fcntl.h>
+#include <linux/module.h>
+#include <linux/spinlock.h>
+#include <linux/list.h>
+#include <linux/smp_lock.h>
+#include <linux/usb.h>
+#include "usbdfu.h"
+
+#ifdef CONFIG_USB_DEBUG
+static int debug = 1;
+#else
+static int debug;
+#endif
+
+/* Use our own dbg macro */
+#undef dbg
+#define dbg(format, arg...) do { if (debug) printk(KERN_DEBUG __FILE__ ": " format "\n" , ## arg); } while (0)
+
+
+/* Version Information */
+#define DRIVER_AUTHOR "Oliver Kurth oku@masqmail.cx"
+#define DRIVER_DESC "USB Device Fimware Uploader (DFU)"
+
+/* Module paramaters */
+MODULE_PARM(debug, "i");
+MODULE_PARM_DESC(debug, "Debug enabled or not");
+
+/* DFU states */
+
+#define STATE_IDLE 0x00
+#define STATE_DETACH 0x01
+#define STATE_DFU_IDLE 0x02
+#define STATE_DFU_DOWNLOAD_SYNC 0x03
+#define STATE_DFU_DOWNLOAD_BUSY 0x04
+#define STATE_DFU_DOWNLOAD_IDLE 0x05
+#define STATE_DFU_MANIFEST_SYNC 0x06
+#define STATE_DFU_MANIFEST 0x07
+#define STATE_DFU_MANIFEST_WAIT_RESET 0x08
+#define STATE_DFU_UPLOAD_IDLE 0x09
+#define STATE_DFU_ERROR 0x0a
+
+/* DFU commands */
+#define DFU_DETACH 0
+#define DFU_DNLOAD 1
+#define DFU_UPLOAD 2
+#define DFU_GETSTATUS 3
+#define DFU_CLRSTATUS 4
+#define DFU_GETSTATE 5
+#define DFU_ABORT 6
+
+struct dfu_status {
+ unsigned char bStatus;
+ unsigned char bwPollTimeout[3];
+ unsigned char bState;
+ unsigned char iString;
+} __attribute__ ((packed));
+
+struct usbdfu_driver {
+ struct list_head list;
+ struct usb_driver *driver;
+ u8 *fw_buf;
+ u32 fw_buf_len;
+};
+
+/* driver independent download context */
+struct dfu_ctx {
+ struct usb_device *udev;
+ u8 dfu_state;
+ struct dfu_status dfu_status;
+ u8 *buf;
+};
+
+#define KEVENT_FLAG_AGAIN 1
+#define KEVENT_FLAG_REMAP 2
+#define KEVENT_FLAG_RESET 3
+
+/* Structure to hold all of our device specific stuff */
+struct usbdfu {
+ struct usb_device * udev; /* save off the usb device pointer */
+ struct usb_interface * interface; /* the interface for this device */
+
+ struct timer_list timer_reset;
+
+ struct tq_struct kevent;
+ u32 kevent_flags;
+
+ struct semaphore sem; /* locks this structure */
+
+ struct usbdfu_driver *drv;
+ u8 op_mode;
+};
+
+LIST_HEAD(usbdfu_driver_list);
+struct semaphore usbdfu_lock;
+
+/* local function prototypes */
+static void * usbdfu_probe(struct usb_device *dev,
+ unsigned int ifnum, const struct usb_device_id *id);
+static void usbdfu_disconnect(struct usb_device *dev, void *ptr);
+
+/* usb specific object needed to register this driver with the usb subsystem */
+static struct usb_driver usbdfu_driver = {
+#if LINUX_VERSION_CODE >= KERNEL_VERSION(2,4,20)
+ owner: THIS_MODULE,
+#endif
+ name: "usbdfu",
+ probe: usbdfu_probe,
+ disconnect: usbdfu_disconnect,
+ id_table: NULL,
+};
+
+/**
+ * usbdfu_debug_data
+ */
+static inline void usbdfu_debug_data (const char *function, int size, const unsigned char *data)
+{
+ int i;
+
+ if (!debug)
+ return;
+
+ printk (KERN_DEBUG __FILE__": %s - length = %d, data = ",
+ function, size);
+ for (i = 0; i < size; ++i) {
+ printk ("%.2x ", data[i]);
+ }
+ printk ("\n");
+}
+
+
+#define USB_SUCCESS(a) (a >= 0)
+
+#define DFU_PACKETSIZE 1024
+
+#define INTERFACE_VENDOR_REQUEST_OUT 0x41
+#define INTERFACE_VENDOR_REQUEST_IN 0xc1
+
+#if 0
+static
+int dfu_detach(struct usb_device *udev)
+{
+ int result;
+
+ dbg("dfu_detach");
+
+ result = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+ DFU_DETACH,
+ USB_DIR_OUT | USB_TYPE_CLASS | USB_RECIP_INTERFACE,
+ 1000, /* Value */
+ 0, /* Index */
+ NULL, /* Buffer */
+ 0, /* Size */
+ HZ);
+
+ return result;
+}
+#endif
+
+static
+int dfu_download_block(struct dfu_ctx *ctx, u8 *buffer,
+ int bytes, int block)
+{
+ int result;
+ u8 *tmpbuf = ctx->buf;
+ struct usb_device *udev = ctx->udev;
+
+ dbg("dfu_download_block(): buffer=%p, bytes=%d, block=%d", buffer, bytes, block);
+
+ if(tmpbuf == NULL)
+ return -ENOMEM;
+
+ memcpy(tmpbuf, buffer, bytes);
+
+ result = usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+ DFU_DNLOAD,
+ USB_TYPE_CLASS | USB_DIR_OUT | USB_RECIP_INTERFACE,
+ block, /* Value */
+ 0, /* Index */
+ tmpbuf, /* Buffer */
+ bytes, /* Size */
+ HZ);
+ return result;
+}
+
+static
+int dfu_get_status(struct dfu_ctx *ctx, struct dfu_status *status)
+{
+ int result;
+ struct usb_device *udev = ctx->udev;
+
+// dbg("dfu_get_status()");
+
+ result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ DFU_GETSTATUS,
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, /* Value */
+ 0, /* Index */
+ status, /* Buffer */
+ sizeof(struct dfu_status), /* Size */
+ HZ);
+
+ return result;
+}
+
+static
+u8 dfu_get_state(struct dfu_ctx *ctx, u8 *state)
+{
+ int result;
+ struct usb_device *udev = ctx->udev;
+
+// dbg("dfu_get_state()");
+
+ result = usb_control_msg(udev, usb_rcvctrlpipe(udev, 0),
+ DFU_GETSTATE, /* Request */
+ USB_TYPE_CLASS | USB_DIR_IN | USB_RECIP_INTERFACE,
+ 0, /* Value */
+ 0, /* Index */
+ state, /* Buffer */
+ 1, /* Size */
+ HZ);
+
+ return result;
+}
+
+static inline
+u32 __get_timeout(struct dfu_status *s)
+{
+ unsigned long ret = 0;
+
+ ret = (unsigned long) (s->bwPollTimeout[2] << 16);
+ ret |= (unsigned long) (s->bwPollTimeout[1] << 8);
+ ret |= (unsigned long) (s->bwPollTimeout[0]);
+
+ return ret;
+}
+
+static
+struct dfu_ctx *dfu_alloc_ctx(struct usb_device *udev)
+{
+ struct dfu_ctx *ctx;
+
+ ctx = kmalloc(sizeof(struct dfu_ctx) + DFU_PACKETSIZE, GFP_KERNEL|GFP_DMA);
+ if(ctx){
+ ctx->udev = udev;
+ ctx->buf = (u8 *)&(ctx[1]);
+ }
+ return ctx;
+}
+
+int dfu_download(struct usb_device *udev, unsigned char *dfu_buffer,
+ unsigned int dfu_len)
+{
+ struct dfu_ctx *ctx;
+ struct dfu_status *dfu_stat_buf;
+ int status = 0;
+ int need_dfu_state = 1;
+ int is_done = 0;
+ u8 dfu_state = 0;
+ u32 dfu_timeout = 0;
+ int dfu_block_bytes = 0, dfu_bytes_left = dfu_len, dfu_buffer_offset = 0;
+ int dfu_block_cnt = 0;
+
+ if (dfu_len == 0) {
+ err("FW Buffer length invalid!");
+ return -EINVAL;
+ }
+
+ ctx = dfu_alloc_ctx(udev);
+ if(ctx == NULL)
+ return -ENOMEM;
+
+ dfu_stat_buf = &ctx->dfu_status;
+
+ do {
+ if (need_dfu_state) {
+ status = dfu_get_state(ctx, &ctx->dfu_state);
+ if (!USB_SUCCESS(status)) {
+ err("DFU: Failed to get DFU state: %d", status);
+ goto exit;
+ }
+ dfu_state = ctx->dfu_state;
+ need_dfu_state = 0;
+ }
+
+ switch (dfu_state) {
+ case STATE_DFU_DOWNLOAD_SYNC:
+ dbg("STATE_DFU_DOWNLOAD_SYNC");
+ if (USB_SUCCESS
+ (status = dfu_get_status(ctx, dfu_stat_buf))) {
+ dfu_state = dfu_stat_buf->bState;
+ dfu_timeout = __get_timeout(dfu_stat_buf);
+ need_dfu_state = 0;
+ }else
+ err("dfu_get_status failed with %d", status);
+ break;
+
+ case STATE_DFU_DOWNLOAD_BUSY:
+ dbg("STATE_DFU_DOWNLOAD_BUSY");
+ need_dfu_state = 1;
+
+ if (dfu_timeout >= 0){
+ dbg("DFU: Resetting device");
+ set_current_state( TASK_INTERRUPTIBLE );
+ schedule_timeout(1+dfu_timeout*HZ/1000);
+ }else
+ dbg("DFU: In progress");
+
+ break;
+
+ case STATE_DFU_DOWNLOAD_IDLE:
+ dbg("DOWNLOAD...");
+ /* fall through */
+ case STATE_DFU_IDLE:
+ dbg("DFU IDLE");
+
+ if (dfu_bytes_left <= DFU_PACKETSIZE)
+ dfu_block_bytes = dfu_bytes_left;
+ else
+ dfu_block_bytes = DFU_PACKETSIZE;
+
+ dfu_bytes_left -= dfu_block_bytes;
+ status = dfu_download_block(ctx,
+ dfu_buffer +
+ dfu_buffer_offset,
+ dfu_block_bytes,
+ dfu_block_cnt);
+ dfu_buffer_offset += dfu_block_bytes;
+ dfu_block_cnt++;
+
+ if (!USB_SUCCESS(status))
+ err("dfu_download_block failed with %d", status);
+ need_dfu_state = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_SYNC:
+ dbg("STATE_DFU_MANIFEST_SYNC");
+
+ status = dfu_get_status(ctx, dfu_stat_buf);
+
+ if (USB_SUCCESS(status)) {
+ dfu_state = dfu_stat_buf->bState;
+ dfu_timeout = __get_timeout(dfu_stat_buf);
+ need_dfu_state = 0;
+
+ if (dfu_timeout >= 0){
+ dbg("DFU: Resetting device");
+
+ set_current_state( TASK_INTERRUPTIBLE );
+ schedule_timeout(1+dfu_timeout*HZ/1000);
+ }else
+ dbg("DFU: In progress");
+ }
+ break;
+
+ case STATE_DFU_MANIFEST:
+ dbg("STATE_DFU_MANIFEST");
+ is_done = 1;
+ break;
+
+ case STATE_DFU_MANIFEST_WAIT_RESET:
+ dbg("STATE_DFU_MANIFEST_WAIT_RESET");
+// usb_reset_device(udev);
+ is_done = 1;
+ break;
+
+ case STATE_DFU_UPLOAD_IDLE:
+ dbg("STATE_DFU_UPLOAD_IDLE");
+ break;
+
+ case STATE_DFU_ERROR:
+ dbg("STATE_DFU_ERROR");
+// usb_reset_device(udev);
+ status = -EPIPE;
+ break;
+
+ default:
+ dbg("DFU UNKNOWN STATE (%d)", dfu_state);
+ status = -EINVAL;
+ break;
+ }
+ } while (!is_done && USB_SUCCESS(status));
+
+ exit:
+ kfree(ctx);
+ return status;
+}
+
+static inline
+int remap(struct usbdfu *dev)
+{
+ struct usb_device *udev = dev->udev;
+ return usb_control_msg(udev, usb_sndctrlpipe(udev,0),
+ 0x0a, INTERFACE_VENDOR_REQUEST_OUT,
+ 0, 0,
+ NULL, 0, HZ);
+}
+
+static inline
+int get_op_mode(struct usbdfu *dev, u8 *op_mode)
+{
+ struct usb_device *udev = dev->udev;
+ int ret;
+
+ ret = usb_control_msg(udev, usb_rcvctrlpipe(udev,0),
+ 0x33, INTERFACE_VENDOR_REQUEST_IN,
+ 0x01, 0,
+ op_mode, 1, HZ);
+ return ret;
+}
+
+static
+int usbdfu_download(struct usbdfu *dev, u8 *fw_buf, u32 fw_len)
+{
+ int ret;
+
+ info("downloading firmware");
+
+ ret = dfu_download(dev->udev, fw_buf, fw_len);
+
+ if(ret >= 0){
+ info("remap");
+ ret = remap(dev);
+ if(ret < 0)
+ err("remap failed: %d", ret);
+ }
+
+ return ret;
+}
+
+/* shamelessly copied from usbnet.c (oku) */
+static void defer_kevent (struct usbdfu *dev, int flag)
+{
+ set_bit (flag, &dev->kevent_flags);
+ if (!schedule_task (&dev->kevent))
+ err ("kevent %d may have been dropped", flag);
+ else
+ dbg ("kevent %d scheduled", flag);
+}
+
+static void kevent_timer_reset(unsigned long data)
+{
+ struct usbdfu *dev = (struct usbdfu *)data;
+
+ defer_kevent(dev, KEVENT_FLAG_RESET);
+
+ del_timer_sync(&dev->timer_reset);
+}
+
+/* TODO: how do we make sure the device hasn't been
+ plugged out in the meantime? */
+
+static void
+kevent(void *data)
+{
+ struct usbdfu *dev = data;
+ struct usb_driver *driver;
+ struct usb_device *udev;
+ struct usbdfu_driver *drv;
+ struct usb_interface *interface;
+
+ dbg("kevent entered");
+
+ /* some paranoid checks: */
+ if(!dev){
+ err("kevent: no dev!");
+ return;
+ }
+
+ down(&dev->sem);
+
+ if(!dev->drv){
+ err("kevent: no dev->drv!");
+ goto error;
+ }
+ driver = dev->drv->driver;
+ if(!driver){
+ err("kevent: no driver!");
+ goto error;
+ }
+ udev = dev->udev;
+ if(!udev){
+ err("kevent: no device!");
+ goto error;
+ }
+ drv = dev->drv;
+ interface = dev->interface;
+
+ up(&dev->sem);
+
+ /* releasing interface, so it can be claimed by our
+ fellow driver */
+ usb_driver_release_interface(&usbdfu_driver, dev->interface);
+
+ info("resetting device");
+ usb_reset_device(udev);
+
+ info("scanning unclaimed devices");
+ usb_scan_devices();
+
+ /* we cannot use dev after reset - disconnect may have been
+ been called, it's gone */
+
+ return;
+ error:
+ up(&dev->sem);
+ return;
+}
+
+int usbdfu_register(struct usb_driver *driver, u8 *fw_buf, int fw_buf_len)
+{
+ struct usbdfu_driver *drv = kmalloc(sizeof(struct usbdfu_driver), GFP_KERNEL);
+
+ if(!drv)
+ return -ENOMEM;
+
+ drv->fw_buf = fw_buf;
+ drv->fw_buf_len = fw_buf_len;
+ drv->driver = driver;
+
+ down(&usbdfu_lock);
+ list_add_tail(&drv->list, &usbdfu_driver_list);
+ up(&usbdfu_lock); /* before scan, because that calls probe() */
+
+ /* if the device is not yet plugged in, we are settled. If it already
+ is, we have to scan for unclaimed devices. This will call our
+ probe function again. */
+ /* I hope this works: */
+ usb_scan_devices();
+
+ return 0;
+}
+
+void usbdfu_deregister(struct usb_driver *driver)
+{
+ struct list_head *tmp;
+ struct usbdfu_driver *drv;
+
+ down(&usbdfu_lock);
+
+ for(tmp = usbdfu_driver_list.next;
+ tmp != &usbdfu_driver_list;
+ tmp = tmp->next) {
+
+ drv = list_entry(tmp, struct usbdfu_driver,
+ list);
+
+ if(drv->driver == driver)
+ break;
+ }
+ if(tmp != &usbdfu_driver_list){
+ list_del(&drv->list);
+ kfree(drv);
+ }
+ up(&usbdfu_lock);
+}
+
+static inline void usbdfu_delete (struct usbdfu *dev)
+{
+ kfree (dev);
+}
+
+static void * usbdfu_probe(struct usb_device *udev, unsigned int ifnum, const struct usb_device_id *id)
+{
+ struct usbdfu *dev = NULL;
+ struct usb_interface *interface;
+ struct list_head *tmp;
+ struct usbdfu_driver *drv = NULL;
+ int ret;
+
+ dbg("usbdfu_probe entered");
+
+ if(ifnum != 0){
+ info("cannot handle multiple interfaces");
+ return NULL;
+ }
+
+ interface = &udev->actconfig->interface[ifnum];
+
+ down(&usbdfu_lock);
+
+ dbg("searching driver");
+
+ for(tmp = usbdfu_driver_list.next;
+ tmp != &usbdfu_driver_list;
+ tmp = tmp->next) {
+ drv = list_entry(tmp, struct usbdfu_driver,
+ list);
+ if(usb_match_id(udev, interface, drv->driver->id_table))
+ break;
+ }
+
+ if(tmp == &usbdfu_driver_list)
+ goto exit; /* not for us */
+
+ dbg("driver %s found", drv->driver->name);
+
+ /* allocate memory for our device state and intialize it */
+ dev = kmalloc (sizeof(struct usbdfu), GFP_KERNEL);
+ if (dev == NULL) {
+ err ("out of memory");
+ goto exit;
+ }
+ memset (dev, 0, sizeof (*dev));
+
+ init_MUTEX (&dev->sem);
+
+ down(&dev->sem);
+
+ INIT_TQUEUE (&dev->kevent, kevent, dev);
+ dev->udev = udev;
+ dev->interface = interface;
+ dev->drv = drv;
+
+ ret = get_op_mode(dev, &dev->op_mode);
+ if(ret < 0){
+ /* this is not a problem: this happens on some hosts when the
+ fw is not loaded. */
+ err("get_op_mode() failed: %d", ret);
+ }else{
+ info("op_mode = %d", (int)dev->op_mode);
+ if(dev->op_mode == 4){
+ info("firmware already loaded");
+ goto error; /* it'fine, but we are not needed */
+ }
+ }
+
+ dbg("going for download");
+ /* here our main action takes place: */
+ ret = usbdfu_download(dev, drv->fw_buf, drv->fw_buf_len);
+ if(ret < 0){
+ err("download failed");
+ goto error;
+ }
+
+ set_bit(KEVENT_FLAG_AGAIN, &dev->kevent_flags);
+// defer_kevent(dev, KEVENT_FLAG_RESET);
+
+ init_timer(&dev->timer_reset);
+ dev->timer_reset.data = (long) dev;
+ dev->timer_reset.function = kevent_timer_reset;
+
+ mod_timer(&dev->timer_reset, jiffies + 2*HZ);
+
+ up(&dev->sem);
+ goto exit;
+
+error:
+ up(&dev->sem);
+ usbdfu_delete (dev);
+ dev = NULL;
+
+exit:
+ up(&usbdfu_lock);
+
+ dbg("usbdfu_probe() exiting");
+ return dev;
+}
+
+
+static void usbdfu_disconnect(struct usb_device *udev, void *ptr)
+{
+ struct usbdfu *dev;
+
+ dev = (struct usbdfu *)ptr;
+
+ usbdfu_delete(dev);
+
+ info("USB DFU now disconnected");
+}
+
+static int __init usbdfu_init(void)
+{
+ int result;
+
+ info(DRIVER_DESC " " DRIVER_VERSION);
+
+ init_MUTEX(&usbdfu_lock);
+
+ /* register this driver with the USB subsystem */
+ result = usb_register(&usbdfu_driver);
+ if (result < 0) {
+ err("usb_register failed for the "__FILE__" driver. Error number %d",
+ result);
+ return -1;
+ }
+
+ return 0;
+}
+
+/**
+ * usbdfu_exit
+ */
+static void __exit usbdfu_exit(void)
+{
+ /* deregister this driver with the USB subsystem */
+ usb_deregister(&usbdfu_driver);
+}
+
+module_init (usbdfu_init);
+module_exit (usbdfu_exit);
+
+EXPORT_SYMBOL(usbdfu_register);
+EXPORT_SYMBOL(usbdfu_deregister);
+
+MODULE_AUTHOR(DRIVER_AUTHOR);
+MODULE_DESCRIPTION(DRIVER_DESC);
+MODULE_LICENSE("GPL");
+
diff --git a/usbdfu.h b/usbdfu.h
new file mode 100644
index 0000000..e4d7fd0
--- /dev/null
+++ b/usbdfu.h
@@ -0,0 +1,19 @@
+/* -*- linux-c -*- */
+/*
+ * USB Device Firmware Uploader
+ *
+ * Copyright (c) 2003 Oliver Kurth <oku@masqmail.cx>
+ *
+ * This program is free software; you can redistribute it and/or
+ * modify it under the terms of the GNU General Public License as
+ * published by the Free Software Foundation; either version 2 of
+ * the License, or (at your option) any later version.
+ *
+ *
+ */
+
+int usbdfu_register(struct usb_driver *driver, u8 *fw_buf, int fw_buf_len);
+void usbdfu_deregister(struct usb_driver *driver);
+
+int dfu_download(struct usb_device *udev, unsigned char *dfu_buffer,
+ unsigned int dfu_len);