[Midnightbsd-cvs] src: dev/ral:

laffer1 at midnightbsd.org laffer1 at midnightbsd.org
Tue Nov 25 12:09:12 EST 2008


Log Message:
-----------


Modified Files:
--------------
    src/sys/dev/ral:
        if_ral_pci.c (r1.1.1.1 -> r1.2)

Added Files:
-----------
    src/sys/dev/ral:
        rt2560.c (r1.1)
        rt2560reg.h (r1.1)
        rt2560var.h (r1.1)
        rt2661.c (r1.1)
        rt2661_ucode.h (r1.1)
        rt2661reg.h (r1.1)
        rt2661var.h (r1.1)

-------------- next part --------------
--- /dev/null
+++ sys/dev/ral/rt2560reg.h
@@ -0,0 +1,487 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2560reg.h,v 1.2 2007/06/11 03:36:52 sam Exp $	*/
+
+/*-
+ * Copyright (c) 2005, 2006
+ *	Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define RT2560_DEFAULT_RSSI_CORR	0x79
+#define RT2560_NOISE_FLOOR		-95
+
+#define RT2560_TX_RING_COUNT		48
+#define RT2560_ATIM_RING_COUNT		4
+#define RT2560_PRIO_RING_COUNT		16
+#define RT2560_BEACON_RING_COUNT	1
+#define RT2560_RX_RING_COUNT		32
+
+#define RT2560_TX_DESC_SIZE	(sizeof (struct rt2560_tx_desc))
+#define RT2560_RX_DESC_SIZE	(sizeof (struct rt2560_rx_desc))
+
+#define RT2560_MAX_SCATTER	1
+
+/*
+ * Control and status registers.
+ */
+#define RT2560_CSR0		0x0000	/* ASIC version number */
+#define RT2560_CSR1		0x0004	/* System control */
+#define RT2560_CSR3		0x000c	/* STA MAC address 0 */
+#define RT2560_CSR4		0x0010	/* STA MAC address 1 */
+#define RT2560_CSR5		0x0014	/* BSSID 0 */
+#define RT2560_CSR6		0x0018	/* BSSID 1 */
+#define RT2560_CSR7		0x001c	/* Interrupt source */
+#define RT2560_CSR8		0x0020	/* Interrupt mask */
+#define RT2560_CSR9		0x0024	/* Maximum frame length */
+#define RT2560_SECCSR0		0x0028	/* WEP control */
+#define RT2560_CSR11		0x002c	/* Back-off control */
+#define RT2560_CSR12		0x0030	/* Synchronization configuration 0 */
+#define RT2560_CSR13		0x0034	/* Synchronization configuration 1 */
+#define RT2560_CSR14		0x0038	/* Synchronization control */
+#define RT2560_CSR15		0x003c	/* Synchronization status */
+#define RT2560_CSR16		0x0040	/* TSF timer 0 */
+#define RT2560_CSR17		0x0044	/* TSF timer 1 */
+#define RT2560_CSR18		0x0048	/* IFS timer 0 */
+#define RT2560_CSR19		0x004c	/* IFS timer 1 */
+#define RT2560_CSR20		0x0050	/* WAKEUP timer */
+#define RT2560_CSR21		0x0054	/* EEPROM control */
+#define RT2560_CSR22		0x0058	/* CFP control */
+#define RT2560_TXCSR0		0x0060	/* TX control */
+#define RT2560_TXCSR1		0x0064	/* TX configuration */
+#define RT2560_TXCSR2		0x0068	/* TX descriptor configuration */
+#define RT2560_TXCSR3		0x006c	/* TX ring base address */
+#define RT2560_TXCSR4		0x0070	/* TX ATIM ring base address */
+#define RT2560_TXCSR5		0x0074	/* TX PRIO ring base address */
+#define RT2560_TXCSR6		0x0078	/* Beacon base address */
+#define RT2560_TXCSR7		0x007c	/* AutoResponder control */
+#define RT2560_RXCSR0		0x0080	/* RX control */
+#define RT2560_RXCSR1		0x0084	/* RX descriptor configuration */
+#define RT2560_RXCSR2		0x0088	/* RX ring base address */
+#define RT2560_PCICSR		0x008c	/* PCI control */
+#define RT2560_RXCSR3		0x0090	/* BBP ID 0 */
+#define RT2560_TXCSR9		0x0094	/* OFDM TX BBP */
+#define RT2560_ARSP_PLCP_0	0x0098	/* Auto Responder PLCP address */
+#define RT2560_ARSP_PLCP_1	0x009c	/* Auto Responder Basic Rate mask */
+#define RT2560_CNT0		0x00a0	/* FCS error counter */
+#define RT2560_CNT1		0x00ac	/* PLCP error counter */
+#define RT2560_CNT2		0x00b0	/* Long error counter */
+#define RT2560_CNT3		0x00b8	/* CCA false alarm counter */
+#define RT2560_CNT4		0x00bc	/* RX FIFO Overflow counter */
+#define RT2560_CNT5		0x00c0	/* Tx FIFO Underrun counter */
+#define RT2560_PWRCSR0		0x00c4	/* Power mode configuration */
+#define RT2560_PSCSR0		0x00c8	/* Power state transition time */
+#define RT2560_PSCSR1		0x00cc	/* Power state transition time */
+#define RT2560_PSCSR2		0x00d0	/* Power state transition time */
+#define RT2560_PSCSR3		0x00d4	/* Power state transition time */
+#define RT2560_PWRCSR1		0x00d8	/* Manual power control/status */
+#define RT2560_TIMECSR		0x00dc	/* Timer control */
+#define RT2560_MACCSR0		0x00e0	/* MAC configuration */
+#define RT2560_MACCSR1		0x00e4	/* MAC configuration */
+#define RT2560_RALINKCSR	0x00e8	/* Ralink RX auto-reset BBCR */
+#define RT2560_BCNCSR		0x00ec	/* Beacon interval control */
+#define RT2560_BBPCSR		0x00f0	/* BBP serial control */
+#define RT2560_RFCSR		0x00f4	/* RF serial control */
+#define RT2560_LEDCSR		0x00f8	/* LED control */
+#define RT2560_SECCSR3		0x00fc	/* XXX not documented */
+#define RT2560_DMACSR0		0x0100	/* Current RX ring address */
+#define RT2560_DMACSR1		0x0104	/* Current Tx ring address */
+#define RT2560_DMACSR2		0x0104	/* Current Priority ring address */
+#define RT2560_DMACSR3		0x0104	/* Current ATIM ring address */
+#define RT2560_TXACKCSR0	0x0110	/* XXX not documented */
+#define RT2560_GPIOCSR		0x0120	/* */
+#define RT2560_BBBPPCSR		0x0124	/* BBP Pin Control */
+#define RT2560_FIFOCSR0		0x0128	/* TX FIFO pointer */
+#define RT2560_FIFOCSR1		0x012c	/* RX FIFO pointer */
+#define RT2560_BCNOCSR		0x0130	/* Beacon time offset */
+#define RT2560_RLPWCSR		0x0134	/* RX_PE Low Width */
+#define RT2560_TESTCSR		0x0138	/* Test Mode Select */
+#define RT2560_PLCP1MCSR	0x013c	/* Signal/Service/Length of ACK @1M */
+#define RT2560_PLCP2MCSR	0x0140	/* Signal/Service/Length of ACK @2M */
+#define RT2560_PLCP5p5MCSR	0x0144	/* Signal/Service/Length of ACK @5.5M */
+#define RT2560_PLCP11MCSR	0x0148	/* Signal/Service/Length of ACK @11M */
+#define RT2560_ACKPCTCSR	0x014c	/* ACK/CTS padload consume time */
+#define RT2560_ARTCSR1		0x0150	/* ACK/CTS padload consume time */
+#define RT2560_ARTCSR2		0x0154	/* ACK/CTS padload consume time */
+#define RT2560_SECCSR1		0x0158	/* WEP control */
+#define RT2560_BBPCSR1		0x015c	/* BBP TX Configuration */
+
+
+/* possible flags for register RXCSR0 */
+#define RT2560_DISABLE_RX		(1 << 0)
+#define RT2560_DROP_CRC_ERROR		(1 << 1)
+#define RT2560_DROP_PHY_ERROR		(1 << 2)
+#define RT2560_DROP_CTL			(1 << 3)
+#define RT2560_DROP_NOT_TO_ME		(1 << 4)
+#define RT2560_DROP_TODS		(1 << 5)
+#define RT2560_DROP_VERSION_ERROR	(1 << 6)
+
+/* possible flags for register CSR1 */
+#define RT2560_RESET_ASIC	(1 << 0)
+#define RT2560_RESET_BBP	(1 << 1)
+#define RT2560_HOST_READY	(1 << 2)
+
+/* possible flags for register CSR14 */
+#define RT2560_ENABLE_TSF		(1 << 0)
+#define RT2560_ENABLE_TSF_SYNC(x)	(((x) & 0x3) << 1)
+#define RT2560_ENABLE_TBCN		(1 << 3)
+#define RT2560_ENABLE_BEACON_GENERATOR	(1 << 6)
+
+/* possible flags for register CSR21 */
+#define RT2560_C	(1 << 1)
+#define RT2560_S	(1 << 2)
+#define RT2560_D	(1 << 3)
+#define RT2560_Q	(1 << 4)
+#define RT2560_93C46	(1 << 5)
+
+#define RT2560_SHIFT_D	3
+#define RT2560_SHIFT_Q	4
+
+/* possible flags for register TXCSR0 */
+#define RT2560_KICK_TX		(1 << 0)
+#define RT2560_KICK_ATIM	(1 << 1)
+#define RT2560_KICK_PRIO	(1 << 2)
+#define RT2560_ABORT_TX		(1 << 3)
+
+/* possible flags for register SECCSR0 */
+#define RT2560_KICK_DECRYPT	(1 << 0)
+
+/* possible flags for register SECCSR1 */
+#define RT2560_KICK_ENCRYPT	(1 << 0)
+
+/* possible flags for register CSR7 */
+#define RT2560_BEACON_EXPIRE	0x00000001
+#define RT2560_WAKEUP_EXPIRE	0x00000002
+#define RT2560_ATIM_EXPIRE	0x00000004
+#define RT2560_TX_DONE		0x00000008
+#define RT2560_ATIM_DONE	0x00000010
+#define RT2560_PRIO_DONE	0x00000020
+#define RT2560_RX_DONE		0x00000040
+#define RT2560_DECRYPTION_DONE	0x00000080
+#define RT2560_ENCRYPTION_DONE	0x00000100
+
+#define RT2560_INTR_MASK							\
+	(~(RT2560_BEACON_EXPIRE | RT2560_WAKEUP_EXPIRE | RT2560_TX_DONE |	\
+	   RT2560_PRIO_DONE | RT2560_RX_DONE | RT2560_DECRYPTION_DONE |		\
+	   RT2560_ENCRYPTION_DONE))
+
+/* Tx descriptor */
+struct rt2560_tx_desc {
+	uint32_t	flags;
+#define RT2560_TX_BUSY			(1 << 0)
+#define RT2560_TX_VALID			(1 << 1)
+
+#define RT2560_TX_RESULT_MASK		0x0000001c
+#define RT2560_TX_SUCCESS		(0 << 2)
+#define RT2560_TX_SUCCESS_RETRY		(1 << 2)
+#define RT2560_TX_FAIL_RETRY		(2 << 2)
+#define RT2560_TX_FAIL_INVALID		(3 << 2)
+#define RT2560_TX_FAIL_OTHER		(4 << 2)
+
+#define RT2560_TX_MORE_FRAG		(1 << 8)
+#define RT2560_TX_ACK			(1 << 9)
+#define RT2560_TX_TIMESTAMP		(1 << 10)
+#define RT2560_TX_OFDM			(1 << 11)
+#define RT2560_TX_CIPHER_BUSY		(1 << 12)
+
+#define RT2560_TX_IFS_MASK		0x00006000
+#define RT2560_TX_IFS_BACKOFF		(0 << 13)
+#define RT2560_TX_IFS_SIFS		(1 << 13)
+#define RT2560_TX_IFS_NEWBACKOFF	(2 << 13)
+#define RT2560_TX_IFS_NONE		(3 << 13)
+
+#define RT2560_TX_LONG_RETRY		(1 << 15)
+
+#define RT2560_TX_CIPHER_MASK		0xe0000000
+#define RT2560_TX_CIPHER_NONE		(0 << 29)
+#define RT2560_TX_CIPHER_WEP40		(1 << 29)
+#define RT2560_TX_CIPHER_WEP104		(2 << 29)
+#define RT2560_TX_CIPHER_TKIP		(3 << 29)
+#define RT2560_TX_CIPHER_AES		(4 << 29)
+
+	uint32_t	physaddr;
+	uint16_t	wme;
+#define RT2560_LOGCWMAX(x)	(((x) & 0xf) << 12)
+#define RT2560_LOGCWMIN(x)	(((x) & 0xf) << 8)
+#define RT2560_AIFSN(x)		(((x) & 0x3) << 6)
+#define RT2560_IVOFFSET(x)	(((x) & 0x3f))
+
+	uint16_t	reserved1;
+	uint8_t		plcp_signal;
+	uint8_t		plcp_service;
+#define RT2560_PLCP_LENGEXT	0x80
+
+	uint8_t		plcp_length_lo;
+	uint8_t		plcp_length_hi;
+	uint32_t	iv;
+	uint32_t	eiv;
+	uint8_t		key[IEEE80211_KEYBUF_SIZE];
+	uint32_t	reserved2[2];
+} __packed;
+
+/* Rx descriptor */
+struct rt2560_rx_desc {
+	uint32_t	flags;
+#define RT2560_RX_BUSY		(1 << 0)
+#define RT2560_RX_CRC_ERROR	(1 << 5)
+#define RT2560_RX_OFDM		(1 << 6)
+#define RT2560_RX_PHY_ERROR	(1 << 7)
+#define RT2560_RX_CIPHER_BUSY	(1 << 8)
+#define RT2560_RX_ICV_ERROR	(1 << 9)
+
+#define RT2560_RX_CIPHER_MASK	0xe0000000
+#define RT2560_RX_CIPHER_NONE	(0 << 29)
+#define RT2560_RX_CIPHER_WEP40	(1 << 29)
+#define RT2560_RX_CIPHER_WEP104	(2 << 29)
+#define RT2560_RX_CIPHER_TKIP	(3 << 29)
+#define RT2560_RX_CIPHER_AES	(4 << 29)
+
+	uint32_t	physaddr;
+	uint8_t		rate;
+	uint8_t		rssi;
+	uint8_t		ta[IEEE80211_ADDR_LEN];
+	uint32_t	iv;
+	uint32_t	eiv;
+	uint8_t		key[IEEE80211_KEYBUF_SIZE];
+	uint32_t	reserved[2];
+} __packed;
+
+#define RAL_RF1	0
+#define RAL_RF2	2
+#define RAL_RF3	1
+#define RAL_RF4	3
+
+#define RT2560_RF1_AUTOTUNE	0x08000
+#define RT2560_RF3_AUTOTUNE	0x00040
+
+#define RT2560_BBP_BUSY		(1 << 15)
+#define RT2560_BBP_WRITE	(1 << 16)
+#define RT2560_RF_20BIT		(20 << 24)
+#define RT2560_RF_BUSY		(1 << 31)
+
+#define RT2560_RF_2522	0x00
+#define RT2560_RF_2523	0x01
+#define RT2560_RF_2524	0x02
+#define RT2560_RF_2525	0x03
+#define RT2560_RF_2525E	0x04
+#define RT2560_RF_2526	0x05
+/* dual-band RF */
+#define RT2560_RF_5222	0x10
+
+#define RT2560_BBP_VERSION	0
+#define RT2560_BBP_TX		2
+#define RT2560_BBP_RX		14
+
+#define RT2560_BBP_ANTA		0x00
+#define RT2560_BBP_DIVERSITY	0x01
+#define RT2560_BBP_ANTB		0x02
+#define RT2560_BBP_ANTMASK	0x03
+#define RT2560_BBP_FLIPIQ	0x04
+
+#define RT2560_LED_MODE_DEFAULT		0
+#define RT2560_LED_MODE_TXRX_ACTIVITY	1
+#define RT2560_LED_MODE_SINGLE		2
+#define RT2560_LED_MODE_ASUS		3
+
+#define RT2560_JAPAN_FILTER	0x8
+
+#define RT2560_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
+
+#define RT2560_EEPROM_CONFIG0	16
+#define RT2560_EEPROM_BBP_BASE	19
+#define RT2560_EEPROM_TXPOWER	35
+#define RT2560_EEPROM_CALIBRATE	62
+
+/*
+ * control and status registers access macros
+ */
+#define RAL_READ(sc, reg)						\
+	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
+
+#define RAL_WRITE(sc, reg, val)						\
+	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+
+/*
+ * EEPROM access macro
+ */
+#define RT2560_EEPROM_CTL(sc, val) do {					\
+	RAL_WRITE((sc), RT2560_CSR21, (val));				\
+	DELAY(RT2560_EEPROM_DELAY);					\
+} while (/* CONSTCOND */0)
+
+/*
+ * Default values for MAC registers; values taken from the reference driver.
+ */
+#define RT2560_DEF_MAC				\
+	{ RT2560_PSCSR0,      0x00020002 },	\
+	{ RT2560_PSCSR1,      0x00000002 },	\
+	{ RT2560_PSCSR2,      0x00020002 },	\
+	{ RT2560_PSCSR3,      0x00000002 },	\
+	{ RT2560_TIMECSR,     0x00003f21 },	\
+	{ RT2560_CSR9,        0x00000780 },	\
+	{ RT2560_CSR11,       0x07041483 },	\
+	{ RT2560_CNT3,        0x00000000 },	\
+	{ RT2560_TXCSR1,      0x07614562 },	\
+	{ RT2560_ARSP_PLCP_0, 0x8c8d8b8a },	\
+	{ RT2560_ACKPCTCSR,   0x7038140a },	\
+	{ RT2560_ARTCSR1,     0x1d21252d },	\
+	{ RT2560_ARTCSR2,     0x1919191d },	\
+	{ RT2560_RXCSR0,      0xffffffff },	\
+	{ RT2560_RXCSR3,      0xb3aab3af },	\
+	{ RT2560_PCICSR,      0x000003b8 },	\
+	{ RT2560_PWRCSR0,     0x3f3b3100 },	\
+	{ RT2560_GPIOCSR,     0x0000ff00 },	\
+	{ RT2560_TESTCSR,     0x000000f0 },	\
+	{ RT2560_PWRCSR1,     0x000001ff },	\
+	{ RT2560_MACCSR0,     0x00213223 },	\
+	{ RT2560_MACCSR1,     0x00235518 },	\
+	{ RT2560_RLPWCSR,     0x00000040 },	\
+	{ RT2560_RALINKCSR,   0x9a009a11 },	\
+	{ RT2560_CSR7,        0xffffffff },	\
+	{ RT2560_BBPCSR1,     0x82188200 },	\
+	{ RT2560_TXACKCSR0,   0x00000020 },	\
+	{ RT2560_SECCSR3,     0x0000e78f }
+
+/*
+ * Default values for BBP registers; values taken from the reference driver.
+ */
+#define RT2560_DEF_BBP	\
+	{  3, 0x02 },	\
+	{  4, 0x19 },	\
+	{ 14, 0x1c },	\
+	{ 15, 0x30 },	\
+	{ 16, 0xac },	\
+	{ 17, 0x48 },	\
+	{ 18, 0x18 },	\
+	{ 19, 0xff },	\
+	{ 20, 0x1e },	\
+	{ 21, 0x08 },	\
+	{ 22, 0x08 },	\
+	{ 23, 0x08 },	\
+	{ 24, 0x80 },	\
+	{ 25, 0x50 },	\
+	{ 26, 0x08 },	\
+	{ 27, 0x23 },	\
+	{ 30, 0x10 },	\
+	{ 31, 0x2b },	\
+	{ 32, 0xb9 },	\
+	{ 34, 0x12 },	\
+	{ 35, 0x50 },	\
+	{ 39, 0xc4 },	\
+	{ 40, 0x02 },	\
+	{ 41, 0x60 },	\
+	{ 53, 0x10 },	\
+	{ 54, 0x18 },	\
+	{ 56, 0x08 },	\
+	{ 57, 0x10 },	\
+	{ 58, 0x08 },	\
+	{ 61, 0x60 },	\
+	{ 62, 0x10 },	\
+	{ 75, 0xff }
+
+/*
+ * Default values for RF register R2 indexed by channel numbers; values taken
+ * from the reference driver.
+ */
+#define RT2560_RF2522_R2						\
+{									\
+	0x307f6, 0x307fb, 0x30800, 0x30805, 0x3080a, 0x3080f, 0x30814,	\
+	0x30819, 0x3081e, 0x30823, 0x30828, 0x3082d, 0x30832, 0x3083e	\
+}
+
+#define RT2560_RF2523_R2						\
+{									\
+	0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,	\
+	0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346	\
+}
+
+#define RT2560_RF2524_R2						\
+{									\
+	0x00327, 0x00328, 0x00329, 0x0032a, 0x0032b, 0x0032c, 0x0032d,	\
+	0x0032e, 0x0032f, 0x00340, 0x00341, 0x00342, 0x00343, 0x00346	\
+}
+
+#define RT2560_RF2525_R2						\
+{									\
+	0x20327, 0x20328, 0x20329, 0x2032a, 0x2032b, 0x2032c, 0x2032d,	\
+	0x2032e, 0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20346	\
+}
+
+#define RT2560_RF2525_HI_R2						\
+{									\
+	0x2032f, 0x20340, 0x20341, 0x20342, 0x20343, 0x20344, 0x20345,	\
+	0x20346, 0x20347, 0x20348, 0x20349, 0x2034a, 0x2034b, 0x2034e	\
+}
+
+#define RT2560_RF2525E_R2						\
+{									\
+	0x2044d, 0x2044e, 0x2044f, 0x20460, 0x20461, 0x20462, 0x20463,	\
+	0x20464, 0x20465, 0x20466, 0x20467, 0x20468, 0x20469, 0x2046b	\
+}
+
+#define RT2560_RF2526_HI_R2						\
+{									\
+	0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d, 0x0022d,	\
+	0x0022e, 0x0022e, 0x0022f, 0x0022d, 0x00240, 0x00240, 0x00241	\
+}
+
+#define RT2560_RF2526_R2						\
+{									\
+	0x00226, 0x00227, 0x00227, 0x00228, 0x00228, 0x00229, 0x00229,	\
+	0x0022a, 0x0022a, 0x0022b, 0x0022b, 0x0022c, 0x0022c, 0x0022d	\
+}
+
+/*
+ * For dual-band RF, RF registers R1 and R4 also depend on channel number;
+ * values taken from the reference driver.
+ */
+#define RT2560_RF5222				\
+	{   1, 0x08808, 0x0044d, 0x00282 },	\
+	{   2, 0x08808, 0x0044e, 0x00282 },	\
+	{   3, 0x08808, 0x0044f, 0x00282 },	\
+	{   4, 0x08808, 0x00460, 0x00282 },	\
+	{   5, 0x08808, 0x00461, 0x00282 },	\
+	{   6, 0x08808, 0x00462, 0x00282 },	\
+	{   7, 0x08808, 0x00463, 0x00282 },	\
+	{   8, 0x08808, 0x00464, 0x00282 },	\
+	{   9, 0x08808, 0x00465, 0x00282 },	\
+	{  10, 0x08808, 0x00466, 0x00282 },	\
+	{  11, 0x08808, 0x00467, 0x00282 },	\
+	{  12, 0x08808, 0x00468, 0x00282 },	\
+	{  13, 0x08808, 0x00469, 0x00282 },	\
+	{  14, 0x08808, 0x0046b, 0x00286 },	\
+						\
+	{  36, 0x08804, 0x06225, 0x00287 },	\
+	{  40, 0x08804, 0x06226, 0x00287 },	\
+	{  44, 0x08804, 0x06227, 0x00287 },	\
+	{  48, 0x08804, 0x06228, 0x00287 },	\
+	{  52, 0x08804, 0x06229, 0x00287 },	\
+	{  56, 0x08804, 0x0622a, 0x00287 },	\
+	{  60, 0x08804, 0x0622b, 0x00287 },	\
+	{  64, 0x08804, 0x0622c, 0x00287 },	\
+						\
+	{ 100, 0x08804, 0x02200, 0x00283 },	\
+	{ 104, 0x08804, 0x02201, 0x00283 },	\
+	{ 108, 0x08804, 0x02202, 0x00283 },	\
+	{ 112, 0x08804, 0x02203, 0x00283 },	\
+	{ 116, 0x08804, 0x02204, 0x00283 },	\
+	{ 120, 0x08804, 0x02205, 0x00283 },	\
+	{ 124, 0x08804, 0x02206, 0x00283 },	\
+	{ 128, 0x08804, 0x02207, 0x00283 },	\
+	{ 132, 0x08804, 0x02208, 0x00283 },	\
+	{ 136, 0x08804, 0x02209, 0x00283 },	\
+	{ 140, 0x08804, 0x0220a, 0x00283 },	\
+						\
+	{ 149, 0x08808, 0x02429, 0x00281 },	\
+	{ 153, 0x08808, 0x0242b, 0x00281 },	\
+	{ 157, 0x08808, 0x0242d, 0x00281 },	\
+	{ 161, 0x08808, 0x0242f, 0x00281 }
--- /dev/null
+++ sys/dev/ral/rt2661_ucode.h
@@ -0,0 +1,2268 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2661_ucode.h,v 1.1 2006/03/05 20:41:51 damien Exp $	*/
+/*	OpenBSD: microcode.h,v 1.1 2006/01/09 20:03:40 damien Exp	*/
+
+/*-
+ * Copyright (c) 2005-2006, Ralink Technology, Corp.
+ *	Paul Lin <paul_lin at ralinktech.com.tw>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+/*
+ * This file contains the loadable 8051 microcodes for the Ralink RT2561,
+ * RT2561S and RT2661 chipsets.
+ */
+
+static const uint8_t rt2561_ucode[] = {
+	0x02, 0x1c, 0x12, 0x02, 0x13, 0xcb, 0xc2, 0x8c, 0x22, 0x22, 0x00,
+	0x02, 0x16, 0x0f, 0xc2, 0xaf, 0xc2, 0x8d, 0x75, 0x8c, 0x94, 0x75,
+	0x8a, 0x93, 0xd2, 0xaf, 0x22, 0x02, 0x18, 0xda, 0x12, 0x1b, 0xe8,
+	0x40, 0x03, 0x02, 0x02, 0x1e, 0x90, 0x21, 0x02, 0xe0, 0xf5, 0x2d,
+	0x90, 0x00, 0x03, 0xe0, 0x12, 0x08, 0x25, 0x00, 0xb0, 0x00, 0x00,
+	0xce, 0x01, 0x00, 0x5e, 0x10, 0x00, 0x6f, 0x11, 0x00, 0xf2, 0x20,
+	0x01, 0x4d, 0x21, 0x01, 0x70, 0x22, 0x01, 0x84, 0x30, 0x01, 0x8f,
+	0x31, 0x01, 0xd5, 0x50, 0x01, 0x9f, 0x51, 0x01, 0xf2, 0x52, 0x02,
+	0x06, 0x60, 0x00, 0x00, 0x02, 0x14, 0x90, 0x00, 0x0a, 0xe0, 0x20,
+	0xe5, 0x03, 0x30, 0x07, 0x03, 0xd2, 0x08, 0x22, 0x12, 0x17, 0xa5,
+	0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x11, 0xe5, 0x11, 0xc4, 0x33,
+	0x54, 0xe0, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83,
+	0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24,
+	0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x11, 0xf0,
+	0xc4, 0x33, 0x54, 0xe0, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x21,
+	0xf5, 0x83, 0xe5, 0x2d, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22,
+	0x12, 0x11, 0x31, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x31, 0x60, 0x05,
+	0x12, 0x1b, 0x8a, 0x80, 0x03, 0x12, 0x1b, 0x3d, 0xe4, 0x90, 0x21,
+	0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, 0x22, 0x75, 0x31, 0xff,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0,
+	0x54, 0xfe, 0xf0, 0x54, 0x3e, 0xf0, 0xe4, 0x90, 0x00, 0x0b, 0xf0,
+	0xf0, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, 0x22,
+	0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x04, 0x0e, 0x90, 0x34,
+	0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x21, 0x14, 0x12, 0x08, 0x01,
+	0x90, 0x34, 0xc0, 0x12, 0x08, 0x0d, 0x90, 0x21, 0x18, 0x12, 0x08,
+	0x01, 0x90, 0x34, 0xc8, 0x12, 0x08, 0x0d, 0x90, 0x21, 0x1c, 0x12,
+	0x08, 0x01, 0x90, 0x34, 0xc4, 0x12, 0x08, 0x0d, 0x90, 0x34, 0xcc,
+	0x74, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x01,
+	0xe0, 0x44, 0x01, 0xf0, 0x44, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0,
+	0x44, 0x10, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x1c, 0x62, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90,
+	0x01, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x54, 0xbf, 0xf0, 0x90, 0x00,
+	0x0b, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf,
+	0x2d, 0x12, 0x1c, 0x62, 0x22, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03,
+	0x12, 0x04, 0x0e, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x1c, 0x62, 0x22, 0xd2, 0x05, 0x85, 0x2d, 0x23, 0xe4, 0x90, 0x21,
+	0x03, 0xf0, 0x22, 0x12, 0x1a, 0x74, 0xc2, 0x00, 0xe4, 0x90, 0x21,
+	0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, 0x22, 0x85, 0x2d, 0x25,
+	0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xff, 0xf0, 0xe4, 0x90, 0x00,
+	0x07, 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x00,
+	0x08, 0xf0, 0x90, 0x21, 0x00, 0xe0, 0x90, 0x00, 0x09, 0xf0, 0x90,
+	0x00, 0x07, 0x74, 0x71, 0xf0, 0xef, 0x44, 0x04, 0x90, 0x00, 0x0b,
+	0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, 0x90, 0x21, 0x00, 0xe0,
+	0xff, 0x54, 0x1f, 0xf5, 0x30, 0xa3, 0xe0, 0xf5, 0x27, 0x8f, 0x26,
+	0x12, 0x08, 0x90, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x1c, 0x62, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x2c, 0x12, 0x18,
+	0x13, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62,
+	0x22, 0x12, 0x19, 0x53, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d,
+	0x12, 0x1c, 0x62, 0x22, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d,
+	0x12, 0x1c, 0x62, 0x22, 0x8e, 0x15, 0x8f, 0x16, 0xca, 0xed, 0xca,
+	0xc9, 0xeb, 0xc9, 0x30, 0x0a, 0x04, 0x7f, 0x4a, 0x80, 0x02, 0x7f,
+	0x42, 0xcb, 0xef, 0xcb, 0xea, 0xc3, 0x94, 0x04, 0x50, 0x02, 0x80,
+	0x01, 0xc3, 0x40, 0x04, 0xcb, 0x44, 0x20, 0xcb, 0x85, 0x16, 0x82,
+	0x85, 0x15, 0x83, 0xeb, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x16, 0x82,
+	0x85, 0x15, 0x83, 0xa3, 0xa3, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0x85,
+	0x16, 0x82, 0x85, 0x15, 0x83, 0xa3, 0xa3, 0xa3, 0xf0, 0xe5, 0x16,
+	0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x0f,
+	0xf0, 0xe5, 0x16, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5,
+	0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35,
+	0x15, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x24, 0x07, 0xf5, 0x82,
+	0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xea, 0x90, 0x1a,
+	0x9c, 0x93, 0xfb, 0xea, 0x64, 0x01, 0x60, 0x08, 0xea, 0x64, 0x02,
+	0x60, 0x03, 0xba, 0x03, 0x04, 0xcb, 0x44, 0x08, 0xcb, 0xe5, 0x16,
+	0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xeb, 0xf0,
+	0xe5, 0x16, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83,
+	0x74, 0xff, 0xf0, 0xe5, 0x16, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35,
+	0x15, 0xf5, 0x83, 0xe9, 0xf0, 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82,
+	0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x04, 0xf0, 0x25, 0x1a, 0xf5,
+	0x1a, 0xe4, 0x35, 0x19, 0xf5, 0x19, 0xea, 0xc3, 0x94, 0x04, 0x40,
+	0x03, 0x02, 0x03, 0xd6, 0xea, 0x60, 0x03, 0xba, 0x01, 0x1f, 0xea,
+	0x24, 0x01, 0xfd, 0xe4, 0x33, 0xfc, 0xe5, 0x1a, 0xae, 0x19, 0x78,
+	0x03, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x12, 0x07,
+	0x96, 0x8e, 0x19, 0x8f, 0x1a, 0x02, 0x03, 0xb6, 0xea, 0x24, 0xff,
+	0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x07,
+	0x84, 0xcc, 0xee, 0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8,
+	0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48,
+	0xfe, 0x12, 0x07, 0x96, 0x8c, 0x1b, 0x8d, 0x1c, 0xea, 0x24, 0xff,
+	0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x07,
+	0x84, 0xcc, 0xee, 0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8,
+	0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48,
+	0xfe, 0x12, 0x07, 0x96, 0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1c, 0x45,
+	0x1b, 0x60, 0x08, 0x05, 0x1a, 0xe5, 0x1a, 0x70, 0x02, 0x05, 0x19,
+	0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f,
+	0x03, 0x12, 0x07, 0x84, 0xd3, 0xe5, 0x1c, 0x9f, 0xe5, 0x1b, 0x9e,
+	0x50, 0x18, 0xe5, 0x1c, 0x45, 0x1b, 0x60, 0x12, 0xba, 0x03, 0x0f,
+	0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83,
+	0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, 0xe4,
+	0x35, 0x15, 0xf5, 0x83, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0xff, 0xe5,
+	0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef,
+	0xf0, 0x80, 0x2d, 0xe5, 0x1a, 0x54, 0x3f, 0xff, 0xe5, 0x16, 0x24,
+	0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0xe5,
+	0x1a, 0xae, 0x19, 0x78, 0x06, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8,
+	0xf9, 0xff, 0xe5, 0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x15,
+	0xf5, 0x83, 0xef, 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xe0,
+	0x44, 0x01, 0xf0, 0x22, 0x8e, 0x12, 0x8f, 0x13, 0x8d, 0x14, 0xe5,
+	0x14, 0xa2, 0xe1, 0x92, 0x09, 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82,
+	0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe5, 0x34, 0x24, 0x1a,
+	0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfb, 0xa2, 0x09,
+	0x92, 0x0a, 0x75, 0x19, 0x00, 0x75, 0x1a, 0x1a, 0x12, 0x02, 0x1f,
+	0x30, 0x09, 0x04, 0x7f, 0xc8, 0x80, 0x02, 0x7f, 0xe8, 0xe5, 0x13,
+	0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0,
+	0xe5, 0x31, 0x60, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x01, 0xe5,
+	0x13, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef,
+	0xf0, 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5,
+	0x83, 0xe0, 0xff, 0x7d, 0x1a, 0x7c, 0x00, 0x12, 0x0e, 0x64, 0xe5,
+	0x13, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef,
+	0xf0, 0xe5, 0x13, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5,
+	0x83, 0xee, 0xf0, 0xe5, 0x31, 0x60, 0x60, 0xe5, 0x13, 0x24, 0x1c,
+	0xff, 0xe4, 0x35, 0x12, 0xfe, 0xe5, 0x34, 0x24, 0x12, 0xfd, 0xe4,
+	0x35, 0x33, 0xfc, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab,
+	0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30,
+	0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, 0xe5,
+	0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d,
+	0x08, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, 0xe5, 0x34,
+	0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff,
+	0xe5, 0x13, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83,
+	0xef, 0xf0, 0x80, 0x3f, 0xe5, 0x13, 0x24, 0x1c, 0xff, 0xe4, 0x35,
+	0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06,
+	0x12, 0x14, 0xab, 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12,
+	0xfe, 0x7c, 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12,
+	0x14, 0xab, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe,
+	0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14,
+	0xab, 0xe5, 0x13, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5,
+	0x83, 0xe4, 0xf0, 0xe5, 0x13, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35,
+	0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82,
+	0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0xc3, 0x13, 0xff, 0xe5,
+	0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef,
+	0xf0, 0x30, 0x09, 0x41, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4,
+	0x35, 0x12, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x31, 0x60, 0x04, 0x7e,
+	0x00, 0x80, 0x02, 0x7e, 0x10, 0xef, 0x4e, 0xf0, 0xe5, 0x31, 0x60,
+	0x06, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x0f, 0xe5, 0x14, 0x30, 0xe0,
+	0x06, 0x7e, 0x00, 0x7f, 0xff, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00,
+	0xe5, 0x13, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83,
+	0xef, 0xf0, 0x22, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35,
+	0x12, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x14, 0x30, 0xe0,
+	0x0f, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5,
+	0x83, 0xe0, 0xff, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31,
+	0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5,
+	0x34, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0,
+	0x30, 0xe7, 0x3b, 0xe5, 0x34, 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35,
+	0x33, 0xf5, 0x83, 0xe0, 0x65, 0x2b, 0x70, 0x03, 0x75, 0x2b, 0xff,
+	0xe5, 0x34, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83,
+	0xe0, 0xff, 0x12, 0x1c, 0x62, 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x18,
+	0x7c, 0x8e, 0x33, 0x8f, 0x34, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3,
+	0xe0, 0x8e, 0x33, 0xf5, 0x34, 0xc3, 0x22, 0xd2, 0x0a, 0xe5, 0x34,
+	0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x70,
+	0x3a, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82,
+	0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff,
+	0xee, 0x9c, 0xfe, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0,
+	0xd3, 0x94, 0x00, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x03, 0x02,
+	0x07, 0x27, 0x80, 0xc6, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0,
+	0xfe, 0xa3, 0xe0, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x03,
+	0x02, 0x07, 0x27, 0x12, 0x1c, 0x41, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0x9f, 0xee, 0x64, 0x80,
+	0xf8, 0xec, 0x64, 0x80, 0x98, 0x40, 0x20, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3,
+	0xe0, 0xff, 0xed, 0x9f, 0xff, 0xec, 0x9e, 0xd0, 0x82, 0xd0, 0x83,
+	0xf0, 0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe5, 0x34, 0x24, 0x10, 0xf5,
+	0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0xef, 0x9d,
+	0xfd, 0xee, 0x94, 0x00, 0xfc, 0x12, 0x16, 0x5a, 0x50, 0x2c, 0x85,
+	0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe,
+	0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3,
+	0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c,
+	0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x20,
+	0x0a, 0x03, 0x02, 0x06, 0x37, 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x18,
+	0x7c, 0x8e, 0x33, 0x8f, 0x34, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe,
+	0xa3, 0xe0, 0xd3, 0x94, 0x00, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40,
+	0x0d, 0x7e, 0x22, 0x7f, 0x10, 0xad, 0x34, 0xac, 0x33, 0x12, 0x15,
+	0x0e, 0x80, 0x1a, 0x12, 0x1b, 0xab, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0xee, 0x8f, 0xf0, 0x12, 0x07, 0xeb, 0x7e, 0x22, 0x7f, 0x30,
+	0xad, 0x34, 0xac, 0x33, 0x12, 0x15, 0x0e, 0x90, 0x22, 0x2e, 0xe0,
+	0xfe, 0xa3, 0xe0, 0xff, 0x65, 0x34, 0x70, 0x03, 0xee, 0x65, 0x33,
+	0x70, 0x02, 0xd3, 0x22, 0x8e, 0x33, 0x8f, 0x34, 0xc3, 0x22, 0xef,
+	0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0, 0xa4, 0x28, 0xce,
+	0x8d, 0xf0, 0xa4, 0x2e, 0xfe, 0x22, 0xbc, 0x00, 0x0b, 0xbe, 0x00,
+	0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 0xf0, 0x22, 0xe4, 0xcc,
+	0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xec,
+	0x33, 0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05, 0xfc, 0xee, 0x9d,
+	0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, 0xfd, 0x22, 0xed, 0xf8,
+	0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe, 0xad, 0xf0, 0x75,
+	0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd, 0x40, 0x07, 0x98,
+	0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, 0xc3, 0x98, 0xfd, 0x0f, 0xd5,
+	0xf0, 0xea, 0x22, 0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5,
+	0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xe0,
+	0x38, 0xf0, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe,
+	0xa3, 0xe0, 0xff, 0x22, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee,
+	0xf0, 0xa3, 0xef, 0xf0, 0x22, 0xa4, 0x25, 0x82, 0xf5, 0x82, 0xe5,
+	0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8,
+	0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3,
+	0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73,
+	0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf,
+	0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0xe4, 0xff, 0x90, 0x30, 0x8c,
+	0xe4, 0xf0, 0xef, 0x90, 0x1b, 0x51, 0x93, 0x44, 0x80, 0x90, 0x30,
+	0x8d, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30,
+	0x8c, 0xe0, 0xfe, 0x74, 0x36, 0x2f, 0xf8, 0xc6, 0xee, 0xc6, 0xa3,
+	0xe0, 0xfe, 0xef, 0x90, 0x1b, 0x51, 0x93, 0x44, 0x80, 0x6e, 0x60,
+	0x01, 0x1f, 0x0f, 0xef, 0xc3, 0x94, 0x09, 0x40, 0xc8, 0x22, 0x00,
+	0x00, 0x00, 0x00, 0xe5, 0x30, 0x12, 0x08, 0x25, 0x08, 0xb1, 0x00,
+	0x09, 0x1f, 0x01, 0x09, 0x87, 0x02, 0x0a, 0x1b, 0x03, 0x0a, 0x6f,
+	0x04, 0x0a, 0xb6, 0x05, 0x0b, 0x29, 0x06, 0x0b, 0x98, 0x07, 0x00,
+	0x00, 0x0b, 0xd0, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a,
+	0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34, 0x98,
+	0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01,
+	0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6, 0x05,
+	0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d, 0xe5,
+	0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12,
+	0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7, 0x05,
+	0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d, 0xe5,
+	0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12,
+	0xf7, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5,
+	0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a,
+	0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34, 0x98,
+	0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01,
+	0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, 0xe5, 0x27, 0x30, 0xe6,
+	0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27,
+	0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x1f, 0x43, 0x12, 0x08,
+	0x80, 0x1a, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80,
+	0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12,
+	0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12,
+	0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12,
+	0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x43, 0x12, 0x01,
+	0x43, 0x12, 0x04, 0xe5, 0x26, 0x30, 0xe5, 0x5c, 0x90, 0x34, 0x98,
+	0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, 0xe5,
+	0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12,
+	0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x30,
+	0x43, 0x12, 0x08, 0x80, 0x2b, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43,
+	0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7,
+	0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0xe5, 0x27,
+	0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0x4f,
+	0xf0, 0xe4, 0xf5, 0x2c, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x80,
+	0x15, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x27, 0xf4,
+	0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0x4f, 0xf0,
+	0x90, 0x30, 0x35, 0xe0, 0xf5, 0x12, 0x53, 0x12, 0xe0, 0xe5, 0x12,
+	0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0,
+	0xf5, 0x12, 0xe5, 0x26, 0x30, 0xe5, 0x3c, 0x90, 0x34, 0x98, 0xe0,
+	0x44, 0x01, 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd,
+	0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53,
+	0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0xe5, 0x26, 0x54, 0xc0,
+	0x60, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x80, 0x06, 0x53,
+	0x12, 0xfe, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0,
+	0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0xc2, 0x01,
+	0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x27,
+	0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd,
+	0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53,
+	0x12, 0xf7, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x08, 0x53, 0x12, 0xfe,
+	0x53, 0x12, 0xfb, 0x80, 0x06, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04,
+	0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x30, 0x3a, 0xe5,
+	0x12, 0xf0, 0x22, 0x20, 0x02, 0x13, 0x12, 0x1c, 0x1e, 0xaf, 0x29,
+	0x7e, 0x00, 0x12, 0x1c, 0x74, 0xaf, 0x35, 0x7e, 0x00, 0x12, 0x1c,
+	0x7b, 0xd2, 0x02, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26,
+	0x20, 0xe5, 0x0d, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x34, 0x98,
+	0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01,
+	0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x2c, 0xc2, 0x01, 0x12, 0x00,
+	0x06, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03,
+	0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7,
+	0x80, 0x03, 0x43, 0x12, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04,
+	0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x30, 0x01, 0x03, 0x02,
+	0x0b, 0xd0, 0x12, 0x15, 0xc0, 0xd2, 0x01, 0x22, 0xc2, 0x01, 0x12,
+	0x00, 0x06, 0xe5, 0x26, 0x20, 0xe5, 0x09, 0x90, 0x34, 0x98, 0xe0,
+	0x54, 0xfe, 0xf0, 0x80, 0x55, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01,
+	0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6, 0x05,
+	0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d, 0xe5,
+	0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12,
+	0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7, 0x05,
+	0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d, 0xe5,
+	0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12,
+	0xf7, 0x43, 0x12, 0x01, 0x53, 0x12, 0xfb, 0x90, 0x30, 0x3a, 0xe5,
+	0x12, 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x22, 0xe5, 0x26,
+	0x30, 0xe5, 0x2c, 0x20, 0x03, 0x21, 0xd2, 0x03, 0x12, 0x1c, 0x1e,
+	0x75, 0x35, 0x06, 0x75, 0x29, 0x09, 0xaf, 0x29, 0x7e, 0x00, 0x12,
+	0x1c, 0x74, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x53, 0x12, 0xfe,
+	0x43, 0x12, 0x04, 0xe5, 0x12, 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x44,
+	0x01, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22,
+	0xe5, 0x31, 0x64, 0x01, 0x70, 0x41, 0x12, 0x1a, 0xd4, 0x40, 0x03,
+	0x02, 0x0d, 0x4f, 0x12, 0x1b, 0x65, 0x50, 0x20, 0x7e, 0x2b, 0x7f,
+	0x80, 0x7d, 0x03, 0x12, 0x04, 0x0e, 0x7f, 0x01, 0x12, 0x19, 0x78,
+	0x40, 0x09, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f, 0x22,
+	0x12, 0x0d, 0x50, 0x75, 0x2f, 0x01, 0x22, 0x7f, 0x01, 0x12, 0x19,
+	0x78, 0x50, 0x04, 0x75, 0x2f, 0x02, 0x22, 0xd2, 0x09, 0x12, 0x0f,
+	0xee, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x1a, 0x1d, 0x50, 0x51, 0x12,
+	0x1b, 0xcb, 0x90, 0x30, 0xf4, 0xe0, 0xf5, 0x2a, 0x7e, 0x30, 0x7f,
+	0xec, 0xa3, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, 0x19, 0x2b, 0xe4, 0xff,
+	0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0a, 0x74, 0x02, 0xf0, 0x90,
+	0x00, 0x0b, 0xe0, 0x44, 0x02, 0xff, 0xf0, 0xfd, 0x90, 0x01, 0x05,
+	0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x44, 0x20, 0xf0, 0xed,
+	0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0, 0x90, 0x34, 0xcc, 0xe0, 0x44,
+	0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01,
+	0xf0, 0xd2, 0x04, 0x12, 0x1a, 0x3a, 0x50, 0x43, 0x12, 0x1a, 0x57,
+	0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x30, 0x7d, 0xec, 0x75, 0x1b, 0x11,
+	0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, 0x30, 0xf5, 0xe0, 0x75, 0xf0,
+	0x20, 0xa4, 0xff, 0xae, 0xf0, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b,
+	0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0x90, 0x00, 0x04, 0xf0,
+	0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0x00, 0x0a, 0x74,
+	0x40, 0xf0, 0x4d, 0x90, 0x00, 0x0b, 0xf0, 0xc2, 0x04, 0x12, 0x1a,
+	0xfe, 0x50, 0x38, 0x12, 0x1a, 0x57, 0x7e, 0x30, 0x7f, 0xe0, 0x7c,
+	0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab,
+	0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4,
+	0xff, 0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd,
+	0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54,
+	0xdf, 0xf0, 0xc2, 0x04, 0x12, 0x1b, 0x28, 0x50, 0x25, 0x12, 0x1a,
+	0x57, 0x7f, 0x02, 0x12, 0x19, 0x78, 0x90, 0x01, 0x04, 0xe0, 0x54,
+	0x7f, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xe4,
+	0x90, 0x00, 0x04, 0xf0, 0xef, 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0,
+	0xc2, 0x04, 0x12, 0x1a, 0xd4, 0x50, 0x2d, 0x12, 0x1a, 0x57, 0x7e,
+	0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b,
+	0x06, 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90,
+	0x00, 0x0a, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0x90,
+	0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xc2, 0x04, 0x22, 0x90, 0x34,
+	0xcd, 0xe0, 0xf9, 0x20, 0xe3, 0xf8, 0xe5, 0x2b, 0xf4, 0x60, 0x66,
+	0x90, 0x34, 0xc0, 0x12, 0x08, 0x01, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, 0x82,
+	0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08,
+	0x0d, 0x90, 0x34, 0xc8, 0x12, 0x08, 0x01, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5,
+	0x82, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12,
+	0x08, 0x0d, 0x90, 0x34, 0xd0, 0x12, 0x08, 0x01, 0x85, 0x34, 0x82,
+	0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19,
+	0xe5, 0x82, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83,
+	0x12, 0x08, 0x0d, 0xe5, 0x34, 0x24, 0xf0, 0xff, 0xe5, 0x33, 0x34,
+	0xde, 0xfe, 0xef, 0x78, 0x05, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8,
+	0xf9, 0xf5, 0x2b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0,
+	0x20, 0x12, 0x08, 0x19, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4,
+	0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, 0x01, 0x90, 0x34, 0xc0, 0x12,
+	0x08, 0x0d, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20,
+	0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, 0x82, 0x24, 0x08, 0xf5, 0x82,
+	0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, 0x01, 0x90, 0x34, 0xc8,
+	0x12, 0x08, 0x0d, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0,
+	0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, 0x82, 0x24, 0x0c, 0xf5,
+	0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, 0x01, 0x90, 0x34,
+	0xc4, 0x12, 0x08, 0x0d, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0,
+	0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0, 0xe9, 0x44, 0x04, 0x90,
+	0x34, 0xcd, 0xf0, 0x90, 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3,
+	0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x8f,
+	0x15, 0x8c, 0x16, 0x8d, 0x17, 0xe5, 0x15, 0xc3, 0x94, 0x04, 0x50,
+	0x56, 0xe5, 0x15, 0x94, 0x00, 0x40, 0x06, 0x7a, 0x00, 0x7b, 0x60,
+	0x80, 0x04, 0x7a, 0x00, 0x7b, 0xc0, 0xe5, 0x17, 0xc4, 0xf8, 0x54,
+	0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48, 0xfe,
+	0xe5, 0x15, 0x90, 0x1a, 0x8e, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x07,
+	0x96, 0xef, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xc4, 0xf8,
+	0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48,
+	0xfe, 0xe5, 0x15, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x07, 0x96, 0xed,
+	0x4c, 0x60, 0x63, 0x0b, 0xbb, 0x00, 0x01, 0x0a, 0x80, 0x5c, 0x7a,
+	0x00, 0x7b, 0x1a, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, 0xc3, 0x33,
+	0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, 0x3e, 0xfe,
+	0xe5, 0x15, 0x90, 0x1a, 0x8e, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x07,
+	0x96, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9,
+	0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02,
+	0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4,
+	0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1a, 0x8e, 0x93, 0xfd, 0x7c, 0x00,
+	0x12, 0x07, 0x96, 0xed, 0x4c, 0x60, 0x07, 0x74, 0x04, 0x2b, 0xfb,
+	0xe4, 0x3a, 0xfa, 0xcf, 0xeb, 0xcf, 0xce, 0xea, 0xce, 0x22, 0xe5,
+	0x2e, 0x14, 0x60, 0x1d, 0x14, 0x60, 0x3d, 0x14, 0x60, 0x5d, 0x14,
+	0x70, 0x03, 0x02, 0x0f, 0xd7, 0x24, 0x04, 0x60, 0x03, 0x02, 0x0f,
+	0xed, 0x20, 0x0d, 0x03, 0x02, 0x0f, 0xed, 0x75, 0x2e, 0x01, 0x22,
+	0x90, 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x03, 0x44, 0x20, 0xf0,
+	0xe5, 0x40, 0x45, 0x3f, 0x60, 0x03, 0x02, 0x0f, 0xed, 0x75, 0x2e,
+	0x02, 0x12, 0x19, 0x9b, 0x12, 0x1b, 0x78, 0xaf, 0x28, 0x12, 0x1a,
+	0xa8, 0x22, 0x90, 0x01, 0x03, 0xe0, 0xff, 0x30, 0xe7, 0x76, 0xef,
+	0x44, 0x80, 0x90, 0x01, 0x03, 0xf0, 0x12, 0x08, 0x51, 0x12, 0x19,
+	0xde, 0x12, 0x1b, 0xbb, 0x75, 0x2e, 0x03, 0xaf, 0x22, 0x7e, 0x00,
+	0x12, 0x1c, 0x2a, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, 0x21, 0x12,
+	0x14, 0x41, 0x12, 0x1b, 0x78, 0x12, 0x19, 0xbe, 0x12, 0x1b, 0xbb,
+	0x12, 0x1c, 0x04, 0x30, 0x0d, 0x0b, 0x75, 0x2e, 0x01, 0xaf, 0x32,
+	0x7e, 0x00, 0x12, 0x1c, 0x2a, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90,
+	0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x2c, 0x44, 0x20, 0xf0, 0x12,
+	0x14, 0x41, 0x12, 0x1b, 0x78, 0x12, 0x19, 0xbe, 0x12, 0x1b, 0xbb,
+	0x12, 0x1c, 0x04, 0x75, 0x2e, 0x04, 0x22, 0xe5, 0x40, 0x45, 0x3f,
+	0x70, 0x10, 0x30, 0x0d, 0x0a, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0xfe,
+	0x12, 0x1c, 0x2a, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, 0x00, 0x04,
+	0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x30, 0x09, 0x32, 0xe5,
+	0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3,
+	0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0,
+	0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02,
+	0xc3, 0x22, 0x12, 0x05, 0xed, 0x50, 0xf3, 0x90, 0x00, 0x0a, 0xe0,
+	0x20, 0xe5, 0x03, 0x30, 0x07, 0x41, 0xe5, 0x34, 0x45, 0x33, 0x70,
+	0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83,
+	0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef,
+	0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef,
+	0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x12, 0x05,
+	0xed, 0x50, 0xf3, 0x80, 0xb5, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x16, 0xea, 0xd3, 0x22, 0x12,
+	0x1a, 0xfe, 0x40, 0x05, 0x12, 0x1a, 0xd4, 0x50, 0x44, 0x7e, 0x30,
+	0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06,
+	0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00,
+	0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b,
+	0xe0, 0x54, 0xbf, 0xf0, 0x54, 0x7f, 0xff, 0xf0, 0xe4, 0x90, 0x30,
+	0xe9, 0xf0, 0xef, 0x54, 0xfd, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90,
+	0x00, 0x04, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f,
+	0x12, 0x1b, 0x13, 0x50, 0x48, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c,
+	0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab, 0x90,
+	0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff,
+	0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0,
+	0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xff, 0x12, 0x19,
+	0x78, 0x50, 0x04, 0x75, 0x2f, 0x07, 0x22, 0x90, 0x01, 0x04, 0xe0,
+	0x54, 0x7f, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f,
+	0x22, 0xc2, 0xaf, 0xe4, 0xf5, 0x2f, 0xf5, 0x88, 0x75, 0xa8, 0x0f,
+	0x75, 0x89, 0x11, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x0f, 0x75,
+	0x31, 0xff, 0x75, 0x2b, 0xff, 0x90, 0x22, 0x2e, 0xf0, 0xa3, 0xf0,
+	0x90, 0x22, 0x4e, 0xf0, 0xa3, 0xf0, 0xc2, 0x05, 0xc2, 0x08, 0xc2,
+	0x00, 0xc2, 0x07, 0xc2, 0x04, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0,
+	0x90, 0x00, 0x0b, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x03, 0x74, 0xff,
+	0xf0, 0xe4, 0x90, 0x01, 0x04, 0xf0, 0x90, 0x01, 0x05, 0x74, 0xff,
+	0xf0, 0xe4, 0x90, 0x01, 0x06, 0xf0, 0x90, 0x00, 0x04, 0xf0, 0x90,
+	0x30, 0xe8, 0x74, 0x10, 0xf0, 0x90, 0x01, 0x07, 0xf0, 0x90, 0x01,
+	0x08, 0x04, 0xf0, 0x90, 0x01, 0x09, 0x74, 0x48, 0xf0, 0x90, 0x01,
+	0x0a, 0x74, 0x7f, 0xf0, 0x90, 0x01, 0x02, 0x74, 0x1f, 0xf0, 0x90,
+	0x01, 0x00, 0x74, 0x14, 0xf0, 0x90, 0x01, 0x01, 0x74, 0x20, 0xf0,
+	0x90, 0x00, 0x00, 0xe0, 0x44, 0x80, 0xf0, 0x75, 0x49, 0x00, 0x75,
+	0x4a, 0x01, 0xc2, 0x01, 0xd2, 0xaf, 0x22, 0x12, 0x1a, 0xd4, 0x50,
+	0x2d, 0x12, 0x18, 0x48, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0,
+	0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12,
+	0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0,
+	0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5,
+	0x2f, 0x22, 0x12, 0x1b, 0x28, 0x50, 0x50, 0x12, 0x18, 0x48, 0x90,
+	0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0,
+	0x90, 0x01, 0x03, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x44,
+	0x80, 0xf0, 0x7f, 0x02, 0x12, 0x19, 0x78, 0x50, 0x04, 0x75, 0x2f,
+	0x05, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75,
+	0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74,
+	0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee,
+	0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5, 0x2f, 0x22,
+	0x90, 0x30, 0x30, 0x74, 0x02, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12,
+	0xd0, 0x90, 0x30, 0x30, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x12, 0x15,
+	0x12, 0x70, 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xeb,
+	0xe5, 0x12, 0x45, 0x11, 0x70, 0x12, 0x12, 0x1a, 0x74, 0x90, 0x21,
+	0x00, 0xe0, 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0,
+	0xc3, 0x22, 0xe4, 0x90, 0x34, 0x58, 0xf0, 0x90, 0x34, 0x32, 0x74,
+	0x1f, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90, 0x34, 0x81,
+	0xe0, 0x64, 0x03, 0x60, 0x0e, 0xe5, 0x12, 0x15, 0x12, 0x70, 0x02,
+	0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xea, 0xe5, 0x12, 0x45,
+	0x11, 0x70, 0x12, 0x12, 0x1a, 0x74, 0x90, 0x21, 0x00, 0xe0, 0x60,
+	0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, 0x22, 0x90,
+	0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe4, 0x90, 0x00, 0x01, 0xf0,
+	0xd3, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x10, 0x12, 0x1c, 0x57,
+	0x50, 0x26, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x10, 0xfd, 0x80,
+	0x03, 0x43, 0x10, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x10,
+	0xf7, 0x80, 0x03, 0x43, 0x10, 0x08, 0x53, 0x10, 0xfe, 0x43, 0x10,
+	0x04, 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0x12, 0x1c, 0x4c, 0x50,
+	0x48, 0x90, 0x01, 0x03, 0xe0, 0xf5, 0x10, 0x54, 0x1c, 0x60, 0x3e,
+	0xe5, 0x10, 0x54, 0xe3, 0xf0, 0xa3, 0xe0, 0xf5, 0x10, 0xf0, 0xe5,
+	0x27, 0x30, 0xe6, 0x05, 0x43, 0x10, 0x02, 0x80, 0x03, 0x53, 0x10,
+	0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x10, 0x08, 0x80, 0x03,
+	0x53, 0x10, 0xf7, 0x53, 0x10, 0xfe, 0x43, 0x10, 0x04, 0x90, 0x30,
+	0x3a, 0xe5, 0x10, 0xf0, 0xaf, 0x29, 0x7e, 0x00, 0x12, 0x1c, 0x74,
+	0xaf, 0x35, 0x7e, 0x00, 0x12, 0x1c, 0x7b, 0x22, 0x12, 0x1a, 0xbf,
+	0x50, 0x72, 0x12, 0x1c, 0x41, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0xe0, 0xfc, 0xa3, 0xe0, 0xc3, 0x9f, 0xf5, 0x12, 0xec, 0x9e, 0xf5,
+	0x11, 0xd3, 0xe5, 0x12, 0x94, 0x00, 0xe5, 0x11, 0x64, 0x80, 0x94,
+	0x80, 0x40, 0x06, 0xae, 0x11, 0xaf, 0x12, 0x80, 0x04, 0x7e, 0x00,
+	0x7f, 0x00, 0x8e, 0x11, 0x8f, 0x12, 0xe5, 0x34, 0x24, 0x10, 0xf5,
+	0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xc3, 0x95, 0x12, 0xf5,
+	0x12, 0xe4, 0x95, 0x11, 0xf5, 0x11, 0xc3, 0x64, 0x80, 0x94, 0x80,
+	0x50, 0x05, 0xe4, 0xf5, 0x11, 0xf5, 0x12, 0xe5, 0x34, 0x24, 0x12,
+	0xff, 0xe4, 0x35, 0x33, 0xfe, 0xad, 0x12, 0x7b, 0x01, 0x12, 0x19,
+	0x2b, 0x90, 0x01, 0x05, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0,
+	0x44, 0x20, 0xf0, 0x75, 0x2f, 0x03, 0x22, 0xc0, 0xe0, 0xc0, 0xf0,
+	0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf,
+	0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34,
+	0xe5, 0x2f, 0x25, 0xe0, 0x24, 0x9b, 0xf5, 0x82, 0xe4, 0x34, 0x1b,
+	0xf5, 0x83, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xca, 0xee, 0xca,
+	0xf9, 0x12, 0x08, 0x4b, 0x12, 0x1b, 0xf6, 0x50, 0x02, 0xd2, 0x07,
+	0x12, 0x17, 0x2c, 0x12, 0x00, 0x1e, 0x12, 0x1a, 0xe9, 0x50, 0x05,
+	0xaf, 0x25, 0x12, 0x1c, 0x62, 0x30, 0x05, 0x1b, 0xe5, 0x2f, 0x70,
+	0x17, 0x20, 0x04, 0x14, 0x12, 0x12, 0x4e, 0x92, 0x00, 0xc2, 0x05,
+	0xd2, 0x0b, 0xa2, 0x00, 0xe4, 0x33, 0xf5, 0x14, 0xaf, 0x23, 0x12,
+	0x16, 0xa2, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0,
+	0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x29, 0xa0, 0xe0, 0x70, 0x63, 0x90,
+	0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc2, 0xf0, 0xa3, 0x74, 0x01,
+	0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29,
+	0xa0, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc5, 0xf0,
+	0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0,
+	0xff, 0x90, 0x29, 0xa1, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3,
+	0x74, 0xc4, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90,
+	0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa2, 0xf0, 0x90, 0x30, 0x8c,
+	0xe4, 0xf0, 0xa3, 0x74, 0xc3, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3,
+	0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0x90, 0x29, 0xa3, 0xf0, 0x22,
+	0x8e, 0x16, 0x8f, 0x17, 0x8c, 0x18, 0x8d, 0x19, 0xe4, 0xff, 0xef,
+	0xc3, 0x9b, 0x50, 0x53, 0xe5, 0x1b, 0x30, 0xe0, 0x12, 0xef, 0x7c,
+	0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, 0x83,
+	0xe0, 0xf5, 0x1c, 0x80, 0x1f, 0xe5, 0x1b, 0x30, 0xe1, 0x13, 0xef,
+	0x7c, 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5,
+	0x83, 0xe4, 0x93, 0xf5, 0x1c, 0x80, 0x07, 0xe5, 0x19, 0x2f, 0xf8,
+	0xe6, 0xf5, 0x1c, 0xe5, 0x1b, 0x30, 0xe4, 0x0f, 0xe5, 0x17, 0x2f,
+	0xf5, 0x82, 0xe4, 0x35, 0x16, 0xf5, 0x83, 0xe5, 0x1c, 0xf0, 0x80,
+	0x06, 0xe5, 0x17, 0x2f, 0xf8, 0xa6, 0x1c, 0x0f, 0x80, 0xa8, 0x22,
+	0x8c, 0x13, 0x8d, 0x14, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e,
+	0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0x4c, 0x60, 0x41, 0xef, 0x24,
+	0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0,
+	0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x85, 0x14,
+	0x82, 0x85, 0x13, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xd3, 0xed,
+	0x9b, 0xea, 0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, 0x40, 0x13,
+	0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc,
+	0xa3, 0xe0, 0xce, 0xec, 0xce, 0xff, 0x80, 0xaf, 0xad, 0x14, 0xac,
+	0x13, 0x12, 0x18, 0xaf, 0x22, 0x12, 0x1a, 0xbf, 0x50, 0x4f, 0xe5,
+	0x34, 0x24, 0x12, 0xff, 0xe4, 0x35, 0x33, 0xfe, 0xe5, 0x34, 0x24,
+	0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe4,
+	0xfb, 0x12, 0x19, 0x2b, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4,
+	0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x7e, 0x00, 0x12, 0x1c, 0x36,
+	0x90, 0x00, 0x0a, 0x74, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44,
+	0x40, 0xff, 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x80, 0xf0, 0x4f, 0x90,
+	0x00, 0x0b, 0xf0, 0x90, 0x30, 0xe9, 0x74, 0x01, 0xf0, 0x75, 0x2f,
+	0x06, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xff, 0xe5, 0x27, 0x30, 0xe6,
+	0x12, 0x30, 0x0c, 0x06, 0xef, 0x54, 0xf5, 0xfe, 0x80, 0x04, 0xef,
+	0x44, 0x0a, 0xfe, 0xcf, 0xee, 0xcf, 0x80, 0x10, 0x30, 0x0c, 0x06,
+	0xef, 0x44, 0x0a, 0xfe, 0x80, 0x04, 0xef, 0x54, 0xf5, 0xfe, 0xcf,
+	0xee, 0xcf, 0xcf, 0x54, 0xfe, 0xcf, 0xcf, 0x44, 0x04, 0xcf, 0x90,
+	0x30, 0x3a, 0xef, 0xf0, 0x30, 0x0c, 0x09, 0x7f, 0x08, 0x7e, 0x00,
+	0x12, 0x1c, 0x74, 0x80, 0x07, 0x7f, 0x22, 0x7e, 0x01, 0x12, 0x1c,
+	0x74, 0xb2, 0x0c, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0,
+	0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, 0xc2, 0x8c, 0xc2,
+	0x8d, 0xd3, 0xe5, 0x4a, 0x94, 0x00, 0xe5, 0x49, 0x94, 0x00, 0x40,
+	0x08, 0xe5, 0x4a, 0x15, 0x4a, 0x70, 0x02, 0x15, 0x49, 0xd3, 0xe5,
+	0x4c, 0x94, 0x00, 0xe5, 0x4b, 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4c,
+	0x15, 0x4c, 0x70, 0x02, 0x15, 0x4b, 0x12, 0x00, 0x0e, 0xd2, 0x8c,
+	0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0,
+	0xe0, 0x32, 0xc3, 0xef, 0x94, 0x04, 0xee, 0x64, 0x80, 0x94, 0x80,
+	0x40, 0x0c, 0xd3, 0xed, 0x94, 0x04, 0xec, 0x64, 0x80, 0x94, 0x80,
+	0x50, 0x01, 0x22, 0xc3, 0xef, 0x94, 0xfc, 0xee, 0x64, 0x80, 0x94,
+	0x7f, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0xfc, 0xec, 0x64, 0x80, 0x94,
+	0x7f, 0x50, 0x01, 0x22, 0xd3, 0xef, 0x94, 0x04, 0xee, 0x64, 0x80,
+	0x94, 0x80, 0x50, 0x0d, 0xc3, 0xed, 0x94, 0xfc, 0xec, 0x64, 0x80,
+	0x94, 0x7f, 0x40, 0x02, 0xd3, 0x22, 0xc3, 0x22, 0xe4, 0xfe, 0xef,
+	0xf4, 0x60, 0x41, 0x74, 0x04, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21,
+	0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x23, 0x74, 0x04, 0x2e, 0xf5, 0x82,
+	0xe4, 0x34, 0x21, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x0b, 0x0d, 0x74,
+	0x08, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x14,
+	0xf0, 0x90, 0x00, 0x02, 0x74, 0x01, 0xf0, 0x22, 0xbe, 0x03, 0x0a,
+	0x90, 0x00, 0x02, 0x74, 0x01, 0xf0, 0xe4, 0xfe, 0x80, 0xc2, 0x0e,
+	0x80, 0xbf, 0x22, 0x8e, 0x13, 0x8f, 0x14, 0x12, 0x1c, 0x41, 0xc3,
+	0xef, 0x95, 0x14, 0xff, 0xee, 0x95, 0x13, 0xcd, 0xef, 0xcd, 0xfc,
+	0xd3, 0xed, 0x94, 0x00, 0xec, 0x64, 0x80, 0x94, 0x80, 0x40, 0x05,
+	0xce, 0xec, 0xce, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x01, 0xcc, 0xee,
+	0xcc, 0xec, 0x90, 0x00, 0x05, 0xf0, 0x90, 0x00, 0x06, 0xef, 0xf0,
+	0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44,
+	0x02, 0xf0, 0x22, 0x30, 0x07, 0x3c, 0xe5, 0x2f, 0x70, 0x38, 0xc2,
+	0x07, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x11, 0xf5,
+	0x12, 0x90, 0x22, 0x4e, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x22,
+	0x2e, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x22, 0x4e, 0xe5, 0x11,
+	0xf0, 0xa3, 0xe5, 0x12, 0xf0, 0x8e, 0x33, 0x8f, 0x34, 0x30, 0x08,
+	0x05, 0x12, 0x17, 0xa5, 0xc2, 0x08, 0xc2, 0x09, 0x12, 0x0f, 0xee,
+	0x22, 0x7f, 0x80, 0x7e, 0x29, 0xe4, 0xfd, 0xfc, 0x8f, 0x82, 0x8e,
+	0x83, 0xe0, 0xfb, 0x74, 0x45, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, 0x74,
+	0x04, 0x2f, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfb, 0x74,
+	0x41, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x08, 0x2f, 0xff, 0xe4,
+	0x3e, 0xfe, 0x0d, 0xbd, 0x00, 0x01, 0x0c, 0xed, 0x64, 0x04, 0x4c,
+	0x70, 0xcf, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xc4, 0x33, 0x54, 0xe0,
+	0x24, 0x10, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xab, 0x82, 0xfa, 0x12,
+	0x1b, 0xab, 0x8b, 0x82, 0x8a, 0x83, 0xee, 0x8f, 0xf0, 0x12, 0x07,
+	0xeb, 0x7e, 0x22, 0x7f, 0x30, 0xcd, 0xeb, 0xcd, 0xcc, 0xea, 0xcc,
+	0x12, 0x15, 0x0e, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x1c, 0x62, 0x22, 0x90, 0x00, 0x00, 0x74, 0x0e, 0xf0, 0x00, 0x00,
+	0x00, 0xe4, 0xf0, 0x12, 0x11, 0x31, 0x12, 0x1c, 0x88, 0x90, 0x34,
+	0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x30, 0xb4, 0x05, 0x0a, 0x12,
+	0x1c, 0x4c, 0x50, 0x0d, 0x12, 0x15, 0xc0, 0x80, 0x08, 0xe5, 0x30,
+	0xb4, 0x07, 0x03, 0x12, 0x12, 0xd4, 0x12, 0x0f, 0x2a, 0x80, 0xe4,
+	0x80, 0xfe, 0x22, 0xe4, 0xff, 0xe5, 0x30, 0x24, 0xfe, 0x70, 0x2c,
+	0xe4, 0xfe, 0xee, 0xc3, 0x95, 0x2c, 0x50, 0x12, 0x74, 0x01, 0xc8,
+	0xee, 0xc8, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xcf, 0x4f,
+	0xcf, 0x0e, 0x80, 0xe8, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0xfe,
+	0xe5, 0x27, 0x54, 0x1f, 0x6f, 0xf4, 0xce, 0x4e, 0xce, 0xee, 0xf0,
+	0x22, 0x90, 0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd,
+	0xe0, 0x54, 0xfe, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x20, 0xe3, 0xf9,
+	0x90, 0x01, 0x11, 0xe0, 0x54, 0x22, 0xff, 0xbf, 0x22, 0x03, 0xd3,
+	0x80, 0x01, 0xc3, 0x50, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7,
+	0xf0, 0x90, 0x01, 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0xef, 0x24,
+	0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0,
+	0xfb, 0xca, 0xec, 0xca, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3c, 0xf5,
+	0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x24, 0x1e, 0xf5, 0x82,
+	0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xce, 0xea,
+	0xce, 0xcf, 0xeb, 0xcf, 0x22, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4,
+	0x3e, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xed, 0x24, 0x1e,
+	0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xea, 0xf0, 0xa3, 0xeb, 0xf0,
+	0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0,
+	0xa3, 0xed, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc2, 0xaf, 0xc2,
+	0x8e, 0xc2, 0x8f, 0xd3, 0xe5, 0x40, 0x94, 0x00, 0xe5, 0x3f, 0x94,
+	0x00, 0x40, 0x0d, 0xe5, 0x40, 0x15, 0x40, 0x70, 0x02, 0x15, 0x3f,
+	0x12, 0x1c, 0x6b, 0xd2, 0x8e, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0xe0,
+	0x32, 0x12, 0x1a, 0xbf, 0x50, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c,
+	0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab,
+	0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2,
+	0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f, 0x22, 0x8e, 0x13, 0x8f,
+	0x14, 0x8d, 0x15, 0xeb, 0x60, 0x09, 0x14, 0x70, 0x1b, 0xaf, 0x15,
+	0x12, 0x19, 0xfe, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0xac, 0x13, 0xad,
+	0x14, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, 0xaf, 0x15,
+	0x12, 0x19, 0xfe, 0x22, 0x12, 0x17, 0x6c, 0x90, 0x21, 0x01, 0xe0,
+	0xf5, 0x28, 0x74, 0x41, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x32, 0x74,
+	0x45, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x22, 0x90, 0x21, 0x00, 0xe0,
+	0x60, 0x03, 0xd2, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0xcd, 0xef, 0xcd,
+	0x90, 0x01, 0x02, 0xe0, 0x30, 0xe7, 0x02, 0xc3, 0x22, 0x7e, 0x2a,
+	0x7f, 0x00, 0x12, 0x04, 0x0e, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80,
+	0xf0, 0x90, 0x01, 0x02, 0xe0, 0x44, 0x80, 0xf0, 0xd3, 0x22, 0x90,
+	0x34, 0x30, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x1f, 0xf0, 0xa3,
+	0xe4, 0xf0, 0x90, 0x01, 0x10, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80,
+	0xf6, 0x90, 0x01, 0x12, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, 0xf6,
+	0x22, 0xe4, 0xff, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x90, 0x30, 0x8c,
+	0xf0, 0xef, 0x90, 0x1b, 0x51, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3,
+	0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22,
+	0xe4, 0xff, 0xef, 0x90, 0x1b, 0x5b, 0x93, 0x90, 0x30, 0x8c, 0xf0,
+	0xef, 0x90, 0x1b, 0x51, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74,
+	0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, 0xe4,
+	0x90, 0x00, 0x05, 0xf0, 0xef, 0x60, 0x02, 0x80, 0x02, 0x7f, 0x01,
+	0x90, 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0,
+	0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x90, 0x30, 0xf0,
+	0xe0, 0xf5, 0x2a, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90,
+	0x30, 0xf2, 0xe0, 0x60, 0x08, 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0,
+	0xd3, 0x22, 0xc3, 0x22, 0x90, 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90,
+	0x00, 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x70,
+	0x08, 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22,
+	0x90, 0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0,
+	0x54, 0xfe, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90,
+	0x01, 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0x90, 0x00, 0x01, 0x74,
+	0x0e, 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x34,
+	0x58, 0x74, 0x01, 0xf0, 0x90, 0x30, 0x30, 0x74, 0x04, 0xf0, 0x22,
+	0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60,
+	0x6c, 0x90, 0xc8, 0x00, 0x01, 0x02, 0x03, 0x0b, 0x0f, 0x0a, 0x0e,
+	0x09, 0x0d, 0x08, 0x0c, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0x3f, 0x4f, 0xf0, 0x90, 0x01, 0x02,
+	0xe0, 0x44, 0x80, 0xf0, 0x22, 0x90, 0x01, 0x03, 0xe0, 0x30, 0xe7,
+	0x0c, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0,
+	0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe1, 0x0c,
+	0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xd3,
+	0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe2, 0x0c, 0x74,
+	0x04, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xf0, 0xd3, 0x22,
+	0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe6, 0x0c, 0x74, 0x40,
+	0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xd3, 0x22, 0xc3,
+	0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe7, 0x0c, 0x74, 0x80, 0xf0,
+	0x90, 0x00, 0x0b, 0xe0, 0x54, 0x7f, 0xf0, 0xd3, 0x22, 0xc3, 0x22,
+	0x90, 0x01, 0x05, 0xe0, 0x30, 0xe5, 0x0c, 0x74, 0x20, 0xf0, 0x90,
+	0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0xe4,
+	0xf5, 0x31, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x22, 0x2e,
+	0x74, 0x21, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0x22, 0x52, 0x53, 0x54,
+	0x12, 0x15, 0x16, 0x10, 0x11, 0x40, 0x00, 0x20, 0x00, 0x40, 0xff,
+	0x3f, 0x3f, 0xbd, 0x28, 0x21, 0x00, 0xe5, 0x34, 0x24, 0x11, 0xf5,
+	0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe6, 0x02, 0xd3,
+	0x22, 0xc3, 0x22, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, 0x74,
+	0xb0, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x22, 0x75,
+	0x31, 0x01, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b,
+	0xe0, 0x44, 0x20, 0xf0, 0x22, 0x0b, 0xd1, 0x13, 0x53, 0x15, 0x6b,
+	0x11, 0xc6, 0x00, 0x09, 0x19, 0x03, 0x10, 0x95, 0x1b, 0xda, 0x90,
+	0x30, 0x64, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0x25, 0xe0, 0xff,
+	0xee, 0x33, 0xfe, 0x22, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3,
+	0x74, 0xb0, 0xf0, 0xa3, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x90, 0x01,
+	0x00, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40,
+	0xf0, 0x22, 0x12, 0x1a, 0xbf, 0x50, 0x08, 0xd2, 0x09, 0x12, 0x0f,
+	0xee, 0xe4, 0xf5, 0x2f, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe0,
+	0x05, 0x74, 0x01, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a,
+	0xe0, 0x30, 0xe5, 0x05, 0x74, 0x20, 0xf0, 0xd3, 0x22, 0xc3, 0x22,
+	0x90, 0x34, 0x30, 0x74, 0x1f, 0xf0, 0xa3, 0xe4, 0xf0, 0xa3, 0xf0,
+	0xa3, 0xf0, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81,
+	0x4c, 0x02, 0x17, 0xdc, 0xc2, 0xaf, 0xc2, 0x8c, 0xc2, 0x8d, 0x12,
+	0x00, 0x0e, 0xd2, 0xaf, 0x22, 0xc2, 0x8e, 0x8e, 0x3f, 0x8f, 0x40,
+	0x12, 0x1c, 0x6b, 0xd2, 0x8e, 0x22, 0x90, 0x30, 0x3c, 0xef, 0xf0,
+	0xee, 0x44, 0x80, 0xa3, 0xf0, 0x22, 0x90, 0x30, 0x78, 0xe0, 0xfd,
+	0xa3, 0xe0, 0xfe, 0xed, 0xff, 0x22, 0xe5, 0x4a, 0x45, 0x49, 0x70,
+	0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0xe5, 0x4c, 0x45, 0x4b, 0x70,
+	0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0xc2, 0x0b, 0xe4, 0xf5, 0x14,
+	0x12, 0x16, 0xa2, 0x22, 0xc2, 0x8f, 0x75, 0x8d, 0xf5, 0x75, 0x8b,
+	0x41, 0x22, 0x8e, 0x49, 0x8f, 0x4a, 0xd2, 0x8c, 0x22, 0x8e, 0x4b,
+	0x8f, 0x4c, 0xd2, 0x8c, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0xc2, 0x0d, 0xe4, 0xf5, 0x2e, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xac, 0x30
+};
+
+static const uint8_t rt2561s_ucode[] = {
+	0x02, 0x1c, 0x2d, 0x02, 0x07, 0xdf, 0xc2, 0x8c, 0x22, 0x22, 0x00,
+	0x02, 0x19, 0x43, 0xc2, 0xaf, 0xc2, 0x8d, 0x75, 0x8c, 0x94, 0x75,
+	0x8a, 0x93, 0xd2, 0xaf, 0x22, 0x02, 0x1a, 0x9c, 0x12, 0x08, 0xdf,
+	0x40, 0x03, 0x02, 0x02, 0x1e, 0x90, 0x21, 0x02, 0xe0, 0xf5, 0x2d,
+	0x90, 0x00, 0x03, 0xe0, 0x12, 0x04, 0x3f, 0x00, 0xb0, 0x00, 0x00,
+	0xce, 0x01, 0x00, 0x5e, 0x10, 0x00, 0x6f, 0x11, 0x00, 0xf2, 0x20,
+	0x01, 0x4d, 0x21, 0x01, 0x70, 0x22, 0x01, 0x84, 0x30, 0x01, 0x8f,
+	0x31, 0x01, 0xd5, 0x50, 0x01, 0x9f, 0x51, 0x01, 0xf2, 0x52, 0x02,
+	0x06, 0x60, 0x00, 0x00, 0x02, 0x14, 0x90, 0x00, 0x0a, 0xe0, 0x20,
+	0xe5, 0x03, 0x30, 0x07, 0x03, 0xd2, 0x08, 0x22, 0x12, 0x14, 0x2b,
+	0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x11, 0xe5, 0x11, 0xc4, 0x33,
+	0x54, 0xe0, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83,
+	0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24,
+	0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x11, 0xf0,
+	0xc4, 0x33, 0x54, 0xe0, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x21,
+	0xf5, 0x83, 0xe5, 0x2d, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22,
+	0x12, 0x05, 0xcb, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x31, 0x60, 0x05,
+	0x12, 0x1b, 0xe0, 0x80, 0x03, 0x12, 0x1b, 0xa6, 0xe4, 0x90, 0x21,
+	0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, 0x22, 0x75, 0x31, 0xff,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0,
+	0x54, 0xfe, 0xf0, 0x54, 0x3e, 0xf0, 0xe4, 0x90, 0x00, 0x0b, 0xf0,
+	0xf0, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, 0x22,
+	0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0xfb, 0x90, 0x34,
+	0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x21, 0x14, 0x12, 0x04, 0x1b,
+	0x90, 0x34, 0xc0, 0x12, 0x04, 0x27, 0x90, 0x21, 0x18, 0x12, 0x04,
+	0x1b, 0x90, 0x34, 0xc8, 0x12, 0x04, 0x27, 0x90, 0x21, 0x1c, 0x12,
+	0x04, 0x1b, 0x90, 0x34, 0xc4, 0x12, 0x04, 0x27, 0x90, 0x34, 0xcc,
+	0x74, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x01,
+	0xe0, 0x44, 0x01, 0xf0, 0x44, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0,
+	0x44, 0x10, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x10, 0xe8, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90,
+	0x01, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x54, 0xbf, 0xf0, 0x90, 0x00,
+	0x0b, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf,
+	0x2d, 0x12, 0x10, 0xe8, 0x22, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03,
+	0x12, 0x0a, 0xfb, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x10, 0xe8, 0x22, 0xd2, 0x05, 0x85, 0x2d, 0x23, 0xe4, 0x90, 0x21,
+	0x03, 0xf0, 0x22, 0x12, 0x13, 0xae, 0xc2, 0x00, 0xe4, 0x90, 0x21,
+	0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, 0x22, 0x85, 0x2d, 0x25,
+	0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xff, 0xf0, 0xe4, 0x90, 0x00,
+	0x07, 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x00,
+	0x08, 0xf0, 0x90, 0x21, 0x00, 0xe0, 0x90, 0x00, 0x09, 0xf0, 0x90,
+	0x00, 0x07, 0x74, 0x71, 0xf0, 0xef, 0x44, 0x04, 0x90, 0x00, 0x0b,
+	0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, 0x90, 0x21, 0x00, 0xe0,
+	0xff, 0x54, 0x1f, 0xf5, 0x30, 0xa3, 0xe0, 0xf5, 0x27, 0x8f, 0x26,
+	0x12, 0x14, 0x62, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12,
+	0x10, 0xe8, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x2c, 0x12, 0x17,
+	0xa3, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8,
+	0x22, 0x12, 0x1a, 0xed, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d,
+	0x12, 0x10, 0xe8, 0x22, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d,
+	0x12, 0x10, 0xe8, 0x22, 0xe5, 0x31, 0x64, 0x01, 0x70, 0x41, 0x12,
+	0x08, 0xed, 0x40, 0x03, 0x02, 0x03, 0x9d, 0x12, 0x0e, 0x34, 0x50,
+	0x20, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0xfb, 0x7f,
+	0x01, 0x12, 0x0a, 0xd8, 0x40, 0x09, 0xd2, 0x09, 0x12, 0x0e, 0x47,
+	0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x09, 0x64, 0x75, 0x2f, 0x01, 0x22,
+	0x7f, 0x01, 0x12, 0x0a, 0xd8, 0x50, 0x04, 0x75, 0x2f, 0x02, 0x22,
+	0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x08,
+	0x90, 0x50, 0x51, 0x12, 0x0a, 0xac, 0x90, 0x30, 0xf4, 0xe0, 0xf5,
+	0x2a, 0x7e, 0x30, 0x7f, 0xec, 0xa3, 0xe0, 0xfd, 0xe4, 0xfb, 0x12,
+	0x0d, 0xa0, 0xe4, 0xff, 0xfe, 0x12, 0x0e, 0x29, 0x90, 0x00, 0x0a,
+	0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xff, 0xf0,
+	0xfd, 0x90, 0x01, 0x05, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0,
+	0x44, 0x20, 0xf0, 0xed, 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0, 0x90,
+	0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0,
+	0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xd2, 0x04, 0x12, 0x08, 0xad, 0x50,
+	0x43, 0x12, 0x0a, 0xbb, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x30, 0x7d,
+	0xec, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, 0x30,
+	0xf5, 0xe0, 0x75, 0xf0, 0x20, 0xa4, 0xff, 0xae, 0xf0, 0x12, 0x0e,
+	0x29, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4,
+	0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0,
+	0x90, 0x00, 0x0a, 0x74, 0x40, 0xf0, 0x4d, 0x90, 0x00, 0x0b, 0xf0,
+	0xc2, 0x04, 0x12, 0x09, 0x25, 0x50, 0x38, 0x12, 0x0a, 0xbb, 0x7e,
+	0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b,
+	0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90,
+	0x00, 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x0e, 0x29, 0x90, 0x00,
+	0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90,
+	0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0x04, 0x12, 0x09, 0x4f,
+	0x50, 0x25, 0x12, 0x0a, 0xbb, 0x7f, 0x02, 0x12, 0x0a, 0xd8, 0x90,
+	0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54,
+	0xfd, 0xff, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xef, 0x54, 0xbf,
+	0x90, 0x00, 0x0b, 0xf0, 0xc2, 0x04, 0x12, 0x08, 0xed, 0x50, 0x2d,
+	0x12, 0x0a, 0xbb, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e,
+	0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04,
+	0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x90, 0x01, 0x06, 0xe0,
+	0x54, 0xdf, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xc2,
+	0x04, 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0,
+	0xa4, 0x28, 0xce, 0x8d, 0xf0, 0xa4, 0x2e, 0xfe, 0x22, 0xbc, 0x00,
+	0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 0xf0,
+	0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee,
+	0x33, 0xfe, 0xec, 0x33, 0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05,
+	0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, 0xfd,
+	0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe,
+	0xad, 0xf0, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd,
+	0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, 0xc3, 0x98,
+	0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xc5, 0xf0, 0xf8, 0xa3, 0xe0,
+	0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02,
+	0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd,
+	0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x22, 0xec, 0xf0, 0xa3, 0xed,
+	0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22, 0xa4, 0x25, 0x82,
+	0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xd0, 0x83,
+	0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70,
+	0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88,
+	0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3,
+	0xa3, 0x80, 0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0xe5, 0x2e,
+	0x14, 0x60, 0x1d, 0x14, 0x60, 0x3d, 0x14, 0x60, 0x5d, 0x14, 0x70,
+	0x03, 0x02, 0x05, 0x18, 0x24, 0x04, 0x60, 0x03, 0x02, 0x05, 0x2e,
+	0x20, 0x0d, 0x03, 0x02, 0x05, 0x2e, 0x75, 0x2e, 0x01, 0x22, 0x90,
+	0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x03, 0x44, 0x20, 0xf0, 0xe5,
+	0x40, 0x45, 0x3f, 0x60, 0x03, 0x02, 0x05, 0x2e, 0x75, 0x2e, 0x02,
+	0x12, 0x1b, 0x12, 0x12, 0x1b, 0xce, 0xaf, 0x28, 0x12, 0x1b, 0x8f,
+	0x22, 0x90, 0x01, 0x03, 0xe0, 0xff, 0x30, 0xe7, 0x76, 0xef, 0x44,
+	0x80, 0x90, 0x01, 0x03, 0xf0, 0x12, 0x08, 0x55, 0x12, 0x1b, 0x55,
+	0x12, 0x1c, 0x01, 0x75, 0x2e, 0x03, 0xaf, 0x22, 0x7e, 0x00, 0x12,
+	0x1c, 0x45, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, 0x21, 0x12, 0x17,
+	0xd8, 0x12, 0x1b, 0xce, 0x12, 0x1b, 0x35, 0x12, 0x1c, 0x01, 0x12,
+	0x1c, 0x1f, 0x30, 0x0d, 0x0b, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0x7e,
+	0x00, 0x12, 0x1c, 0x45, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, 0x00,
+	0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x2c, 0x44, 0x20, 0xf0, 0x12, 0x17,
+	0xd8, 0x12, 0x1b, 0xce, 0x12, 0x1b, 0x35, 0x12, 0x1c, 0x01, 0x12,
+	0x1c, 0x1f, 0x75, 0x2e, 0x04, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70,
+	0x10, 0x30, 0x0d, 0x0a, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0xfe, 0x12,
+	0x1c, 0x45, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x12, 0x09, 0x25, 0x40,
+	0x05, 0x12, 0x08, 0xed, 0x50, 0x44, 0x7e, 0x30, 0x7f, 0xe0, 0x7c,
+	0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8,
+	0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4,
+	0xff, 0xfe, 0x12, 0x0e, 0x29, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf,
+	0xf0, 0x54, 0x7f, 0xff, 0xf0, 0xe4, 0x90, 0x30, 0xe9, 0xf0, 0xef,
+	0x54, 0xfd, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0,
+	0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x12, 0x09, 0x3a,
+	0x50, 0x48, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75,
+	0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74,
+	0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x0e,
+	0x29, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0x54, 0xfd, 0xf0,
+	0xe4, 0x90, 0x00, 0x04, 0xf0, 0xff, 0x12, 0x0a, 0xd8, 0x50, 0x04,
+	0x75, 0x2f, 0x07, 0x22, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0,
+	0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0xc2, 0xaf,
+	0xe4, 0xf5, 0x2f, 0xf5, 0x88, 0x75, 0xa8, 0x0f, 0x75, 0x89, 0x11,
+	0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x0f, 0x75, 0x31, 0xff, 0x75,
+	0x2b, 0xff, 0x90, 0x22, 0x2e, 0xf0, 0xa3, 0xf0, 0x90, 0x22, 0x4e,
+	0xf0, 0xa3, 0xf0, 0xc2, 0x05, 0xc2, 0x08, 0xc2, 0x00, 0xc2, 0x07,
+	0xc2, 0x04, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b,
+	0x74, 0x01, 0xf0, 0x90, 0x01, 0x03, 0x74, 0xff, 0xf0, 0xe4, 0x90,
+	0x01, 0x04, 0xf0, 0x90, 0x01, 0x05, 0x74, 0xff, 0xf0, 0xe4, 0x90,
+	0x01, 0x06, 0xf0, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x30, 0xe8, 0x74,
+	0x10, 0xf0, 0x90, 0x01, 0x07, 0xf0, 0x90, 0x01, 0x08, 0x04, 0xf0,
+	0x90, 0x01, 0x09, 0x74, 0x48, 0xf0, 0x90, 0x01, 0x0a, 0x74, 0x7f,
+	0xf0, 0x90, 0x01, 0x02, 0x74, 0x1f, 0xf0, 0x90, 0x01, 0x00, 0x74,
+	0x14, 0xf0, 0x90, 0x01, 0x01, 0x74, 0x20, 0xf0, 0x90, 0x00, 0x00,
+	0xe0, 0x44, 0x80, 0xf0, 0x75, 0x49, 0x00, 0x75, 0x4a, 0x01, 0xc2,
+	0x01, 0xd2, 0xaf, 0x22, 0x12, 0x08, 0xed, 0x50, 0x2d, 0x12, 0x0a,
+	0x78, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0x7e, 0x30, 0x7f,
+	0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12,
+	0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a,
+	0xf0, 0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x12,
+	0x09, 0x4f, 0x50, 0x50, 0x12, 0x0a, 0x78, 0x90, 0x00, 0x0b, 0xe0,
+	0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x03,
+	0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, 0xf0, 0x7f,
+	0x02, 0x12, 0x0a, 0xd8, 0x50, 0x04, 0x75, 0x2f, 0x05, 0x22, 0x7e,
+	0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b,
+	0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90,
+	0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x0e, 0x47, 0x90, 0x01, 0x04,
+	0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5, 0x2f, 0x22, 0x90, 0x30, 0x3a,
+	0xe0, 0xf5, 0x10, 0x12, 0x1c, 0x5c, 0x50, 0x26, 0xe5, 0x27, 0x30,
+	0xe6, 0x05, 0x53, 0x10, 0xfd, 0x80, 0x03, 0x43, 0x10, 0x02, 0xe5,
+	0x27, 0x30, 0xe7, 0x05, 0x53, 0x10, 0xf7, 0x80, 0x03, 0x43, 0x10,
+	0x08, 0x53, 0x10, 0xfe, 0x43, 0x10, 0x04, 0x90, 0x30, 0x3a, 0xe5,
+	0x10, 0xf0, 0x12, 0x1c, 0x51, 0x50, 0x48, 0x90, 0x01, 0x03, 0xe0,
+	0xf5, 0x10, 0x54, 0x1c, 0x60, 0x3e, 0xe5, 0x10, 0x54, 0xe3, 0xf0,
+	0xa3, 0xe0, 0xf5, 0x10, 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43,
+	0x10, 0x02, 0x80, 0x03, 0x53, 0x10, 0xfd, 0xe5, 0x27, 0x30, 0xe7,
+	0x05, 0x43, 0x10, 0x08, 0x80, 0x03, 0x53, 0x10, 0xf7, 0x53, 0x10,
+	0xfe, 0x43, 0x10, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0xaf,
+	0x29, 0x7e, 0x00, 0x12, 0x1c, 0x70, 0xaf, 0x35, 0x7e, 0x00, 0x12,
+	0x1c, 0x77, 0x22, 0x12, 0x08, 0xca, 0x50, 0x72, 0x12, 0x10, 0xcd,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xc3,
+	0x9f, 0xf5, 0x12, 0xec, 0x9e, 0xf5, 0x11, 0xd3, 0xe5, 0x12, 0x94,
+	0x00, 0xe5, 0x11, 0x64, 0x80, 0x94, 0x80, 0x40, 0x06, 0xae, 0x11,
+	0xaf, 0x12, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x8e, 0x11, 0x8f,
+	0x12, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5,
+	0x83, 0xe0, 0xc3, 0x95, 0x12, 0xf5, 0x12, 0xe4, 0x95, 0x11, 0xf5,
+	0x11, 0xc3, 0x64, 0x80, 0x94, 0x80, 0x50, 0x05, 0xe4, 0xf5, 0x11,
+	0xf5, 0x12, 0xe5, 0x34, 0x24, 0x12, 0xff, 0xe4, 0x35, 0x33, 0xfe,
+	0xad, 0x12, 0x7b, 0x01, 0x12, 0x0d, 0xa0, 0x90, 0x01, 0x05, 0x74,
+	0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x44, 0x20, 0xf0, 0x75, 0x2f,
+	0x03, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0,
+	0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, 0x90, 0x22, 0x2e, 0xe0, 0xfe,
+	0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, 0xe5, 0x2f, 0x25, 0xe0, 0x24,
+	0xf1, 0xf5, 0x82, 0xe4, 0x34, 0x1b, 0xf5, 0x83, 0xe4, 0x93, 0xfe,
+	0x74, 0x01, 0x93, 0xca, 0xee, 0xca, 0xf9, 0x12, 0x04, 0x65, 0x12,
+	0x09, 0x17, 0x50, 0x02, 0xd2, 0x07, 0x12, 0x19, 0x8e, 0x12, 0x00,
+	0x1e, 0x12, 0x09, 0x02, 0x50, 0x05, 0xaf, 0x25, 0x12, 0x10, 0xe8,
+	0x30, 0x05, 0x1b, 0xe5, 0x2f, 0x70, 0x17, 0x20, 0x04, 0x14, 0x12,
+	0x13, 0x28, 0x92, 0x00, 0xc2, 0x05, 0xd2, 0x0b, 0xa2, 0x00, 0xe4,
+	0x33, 0xf5, 0x14, 0xaf, 0x23, 0x12, 0x10, 0xf1, 0xd2, 0xaf, 0xd0,
+	0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xe4,
+	0xff, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xef, 0x90, 0x1b, 0xba, 0x93,
+	0x44, 0x80, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3,
+	0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xfe, 0x74, 0x36, 0x2f, 0xf8,
+	0xc6, 0xee, 0xc6, 0xa3, 0xe0, 0xfe, 0xef, 0x90, 0x1b, 0xba, 0x93,
+	0x44, 0x80, 0x6e, 0x60, 0x01, 0x1f, 0x0f, 0xef, 0xc3, 0x94, 0x09,
+	0x40, 0xc8, 0x22, 0x90, 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, 0x00,
+	0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x60, 0x08,
+	0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90,
+	0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe4,
+	0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x70, 0x08, 0x90, 0x00, 0x0a, 0x74,
+	0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x01, 0x03, 0xe0, 0x30,
+	0xe7, 0x0c, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f,
+	0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe0,
+	0x05, 0x74, 0x01, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a,
+	0xe0, 0x30, 0xe1, 0x0c, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0,
+	0x54, 0xfd, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0,
+	0x30, 0xe2, 0x0c, 0x74, 0x04, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54,
+	0xfb, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30,
+	0xe5, 0x05, 0x74, 0x20, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00,
+	0x0a, 0xe0, 0x30, 0xe6, 0x0c, 0x74, 0x40, 0xf0, 0x90, 0x00, 0x0b,
+	0xe0, 0x54, 0xbf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a,
+	0xe0, 0x30, 0xe7, 0x0c, 0x74, 0x80, 0xf0, 0x90, 0x00, 0x0b, 0xe0,
+	0x54, 0x7f, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x01, 0x05, 0xe0,
+	0x30, 0xe5, 0x0c, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54,
+	0xdf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x34, 0xcd, 0xe0, 0xf9,
+	0x20, 0xe3, 0xf8, 0xe5, 0x2b, 0xf4, 0x60, 0x66, 0x90, 0x34, 0xc0,
+	0x12, 0x04, 0x1b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0,
+	0x20, 0xe5, 0x2b, 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, 0x04, 0xf5,
+	0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x04, 0x27, 0x90, 0x34,
+	0xc8, 0x12, 0x04, 0x1b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75,
+	0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, 0x08,
+	0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x04, 0x27, 0x90,
+	0x34, 0xd0, 0x12, 0x04, 0x1b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24,
+	0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x04, 0x27,
+	0xe5, 0x34, 0x24, 0xf0, 0xff, 0xe5, 0x33, 0x34, 0xde, 0xfe, 0xef,
+	0x78, 0x05, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x2b,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0x12, 0x04,
+	0x33, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5,
+	0x83, 0x12, 0x04, 0x1b, 0x90, 0x34, 0xc0, 0x12, 0x04, 0x27, 0x85,
+	0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12,
+	0x04, 0x33, 0xe5, 0x82, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83,
+	0xf5, 0x83, 0x12, 0x04, 0x1b, 0x90, 0x34, 0xc8, 0x12, 0x04, 0x27,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b,
+	0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35,
+	0x83, 0xf5, 0x83, 0x12, 0x04, 0x1b, 0x90, 0x34, 0xc4, 0x12, 0x04,
+	0x27, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x01, 0x00,
+	0xe0, 0x44, 0x08, 0xf0, 0xe9, 0x44, 0x04, 0x90, 0x34, 0xcd, 0xf0,
+	0x90, 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01,
+	0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x90, 0x34, 0xce, 0xe0,
+	0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54, 0xfe, 0xf0, 0x90,
+	0x34, 0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x01, 0x11, 0xe0, 0x54,
+	0x22, 0xff, 0xbf, 0x22, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x50, 0xf0,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0,
+	0x54, 0xbf, 0xf0, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0,
+	0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0x22, 0x90, 0x34, 0xce,
+	0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54, 0xfe, 0xf0,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0,
+	0x54, 0xbf, 0xf0, 0x22, 0xcd, 0xef, 0xcd, 0x90, 0x01, 0x02, 0xe0,
+	0x30, 0xe7, 0x02, 0xc3, 0x22, 0x7e, 0x2a, 0x7f, 0x00, 0x12, 0x0a,
+	0xfb, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, 0xf0, 0x90, 0x01, 0x02,
+	0xe0, 0x44, 0x80, 0xf0, 0xd3, 0x22, 0x8e, 0x12, 0x8f, 0x13, 0x8d,
+	0x14, 0xe5, 0x14, 0xa2, 0xe1, 0x92, 0x09, 0xe5, 0x34, 0x24, 0x19,
+	0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe5, 0x34,
+	0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfb,
+	0xa2, 0x09, 0x92, 0x0a, 0x75, 0x19, 0x00, 0x75, 0x1a, 0x1a, 0x12,
+	0x11, 0x39, 0x30, 0x09, 0x04, 0x7f, 0xc8, 0x80, 0x02, 0x7f, 0xe8,
+	0xe5, 0x13, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83,
+	0xef, 0xf0, 0xe5, 0x31, 0x60, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f,
+	0x01, 0xe5, 0x13, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5,
+	0x83, 0xef, 0xf0, 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35,
+	0x33, 0xf5, 0x83, 0xe0, 0xff, 0x7d, 0x1a, 0x7c, 0x00, 0x12, 0x0c,
+	0xda, 0xe5, 0x13, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5,
+	0x83, 0xef, 0xf0, 0xe5, 0x13, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35,
+	0x12, 0xf5, 0x83, 0xee, 0xf0, 0xe5, 0x31, 0x60, 0x60, 0xe5, 0x13,
+	0x24, 0x1c, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0xe5, 0x34, 0x24, 0x12,
+	0xfd, 0xe4, 0x35, 0x33, 0xfc, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12,
+	0x13, 0xc8, 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, 0xfe,
+	0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x13,
+	0xc8, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c,
+	0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x13, 0xc8,
+	0xe5, 0x34, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83,
+	0xe0, 0xff, 0xe5, 0x13, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x12,
+	0xf5, 0x83, 0xef, 0xf0, 0x80, 0x3f, 0xe5, 0x13, 0x24, 0x1c, 0xff,
+	0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11,
+	0x7b, 0x06, 0x12, 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4,
+	0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b,
+	0x06, 0x12, 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35,
+	0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06,
+	0x12, 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35,
+	0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x13, 0x24, 0x2f, 0xf5, 0x82,
+	0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x34, 0x24, 0x11,
+	0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0xc3, 0x13,
+	0xff, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5,
+	0x83, 0xef, 0xf0, 0x30, 0x09, 0x41, 0xe5, 0x13, 0x24, 0x30, 0xf5,
+	0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x31, 0x60,
+	0x04, 0x7e, 0x00, 0x80, 0x02, 0x7e, 0x10, 0xef, 0x4e, 0xf0, 0xe5,
+	0x31, 0x60, 0x06, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x0f, 0xe5, 0x14,
+	0x30, 0xe0, 0x06, 0x7e, 0x00, 0x7f, 0xff, 0x80, 0x04, 0x7e, 0x00,
+	0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12,
+	0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82,
+	0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x14,
+	0x30, 0xe0, 0x0f, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35,
+	0x33, 0xf5, 0x83, 0xe0, 0xff, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x13,
+	0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0,
+	0x22, 0x8f, 0x15, 0x8c, 0x16, 0x8d, 0x17, 0xe5, 0x15, 0xc3, 0x94,
+	0x04, 0x50, 0x56, 0xe5, 0x15, 0x94, 0x00, 0x40, 0x06, 0x7a, 0x00,
+	0x7b, 0x60, 0x80, 0x04, 0x7a, 0x00, 0x7b, 0xc0, 0xe5, 0x17, 0xc4,
+	0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0,
+	0x48, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x75, 0x93, 0xfd, 0x7c, 0x00,
+	0x12, 0x03, 0xb0, 0xef, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17,
+	0xc4, 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54,
+	0xf0, 0x48, 0xfe, 0xe5, 0x15, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x03,
+	0xb0, 0xed, 0x4c, 0x60, 0x63, 0x0b, 0xbb, 0x00, 0x01, 0x0a, 0x80,
+	0x5c, 0x7a, 0x00, 0x7b, 0x1a, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02,
+	0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4,
+	0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x75, 0x93, 0xfd, 0x7c, 0x00,
+	0x12, 0x03, 0xb0, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce,
+	0xd8, 0xf9, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xae, 0x16,
+	0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b,
+	0xff, 0xe4, 0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x75, 0x93, 0xfd,
+	0x7c, 0x00, 0x12, 0x03, 0xb0, 0xed, 0x4c, 0x60, 0x07, 0x74, 0x04,
+	0x2b, 0xfb, 0xe4, 0x3a, 0xfa, 0xcf, 0xeb, 0xcf, 0xce, 0xea, 0xce,
+	0x22, 0x8e, 0x13, 0x8f, 0x14, 0x8d, 0x15, 0xeb, 0x60, 0x09, 0x14,
+	0x70, 0x1b, 0xaf, 0x15, 0x12, 0x0e, 0x0a, 0x22, 0x7e, 0x30, 0x7f,
+	0xe0, 0xac, 0x13, 0xad, 0x14, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12,
+	0x13, 0xc8, 0xaf, 0x15, 0x12, 0x0e, 0x0a, 0x22, 0x8e, 0x13, 0x8f,
+	0x14, 0x12, 0x10, 0xcd, 0xc3, 0xef, 0x95, 0x14, 0xff, 0xee, 0x95,
+	0x13, 0xcd, 0xef, 0xcd, 0xfc, 0xd3, 0xed, 0x94, 0x00, 0xec, 0x64,
+	0x80, 0x94, 0x80, 0x40, 0x05, 0xce, 0xec, 0xce, 0x80, 0x04, 0x7e,
+	0x00, 0x7f, 0x01, 0xcc, 0xee, 0xcc, 0xec, 0x90, 0x00, 0x05, 0xf0,
+	0x90, 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0,
+	0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x00,
+	0x05, 0xf0, 0xef, 0x60, 0x02, 0x80, 0x02, 0x7f, 0x01, 0x90, 0x00,
+	0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, 0x90, 0x00,
+	0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x90, 0x30, 0x3c, 0xef, 0xf0,
+	0xee, 0x44, 0x80, 0xa3, 0xf0, 0x22, 0xe5, 0x34, 0x24, 0x11, 0xf5,
+	0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe6, 0x02, 0xd3,
+	0x22, 0xc3, 0x22, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00,
+	0x0a, 0xf0, 0x30, 0x09, 0x32, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02,
+	0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0,
+	0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d,
+	0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0,
+	0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x12, 0x0e, 0xee,
+	0x50, 0xf3, 0x90, 0x00, 0x0a, 0xe0, 0x20, 0xe5, 0x03, 0x30, 0x07,
+	0x41, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x85, 0x34,
+	0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3,
+	0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0,
+	0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0,
+	0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x34, 0x45, 0x33,
+	0x70, 0x02, 0xc3, 0x22, 0x12, 0x0e, 0xee, 0x50, 0xf3, 0x80, 0xb5,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
+	0x12, 0x0d, 0xc8, 0xd3, 0x22, 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82,
+	0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe7, 0x3b, 0xe5, 0x34,
+	0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x65,
+	0x2b, 0x70, 0x03, 0x75, 0x2b, 0xff, 0xe5, 0x34, 0x24, 0x1d, 0xf5,
+	0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x10, 0xe8,
+	0x7e, 0x22, 0x7f, 0x10, 0x12, 0x1a, 0x3e, 0x8e, 0x33, 0x8f, 0x34,
+	0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34,
+	0xc3, 0x22, 0xd2, 0x0a, 0xe5, 0x34, 0x24, 0x1b, 0xf5, 0x82, 0xe4,
+	0x35, 0x33, 0xf5, 0x83, 0xe0, 0x70, 0x3a, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3,
+	0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xfe, 0xd0, 0x82,
+	0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xd3, 0x94, 0x00, 0xee, 0x64,
+	0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x10, 0x28, 0x80, 0xc6, 0x85,
+	0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0xee,
+	0x64, 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x10, 0x28, 0x12, 0x10,
+	0xcd, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0,
+	0xfd, 0xc3, 0x9f, 0xee, 0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98,
+	0x40, 0x20, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0,
+	0x82, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xed, 0x9f, 0xff,
+	0xec, 0x9e, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xc2,
+	0x0a, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0,
+	0xff, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5,
+	0x83, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xfd, 0xee, 0x94, 0x00, 0xfc,
+	0x12, 0x10, 0x85, 0x50, 0x2c, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34,
+	0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd,
+	0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0,
+	0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x20, 0x0a, 0x03, 0x02, 0x0f, 0x38,
+	0x7e, 0x22, 0x7f, 0x10, 0x12, 0x1a, 0x3e, 0x8e, 0x33, 0x8f, 0x34,
+	0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xd3, 0x94, 0x00,
+	0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0d, 0x7e, 0x22, 0x7f, 0x10,
+	0xad, 0x34, 0xac, 0x33, 0x12, 0x18, 0x42, 0x80, 0x1a, 0x12, 0x10,
+	0xd8, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xee, 0x8f, 0xf0, 0x12,
+	0x04, 0x05, 0x7e, 0x22, 0x7f, 0x30, 0xad, 0x34, 0xac, 0x33, 0x12,
+	0x18, 0x42, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x65,
+	0x34, 0x70, 0x03, 0xee, 0x65, 0x33, 0x70, 0x02, 0xd3, 0x22, 0x8e,
+	0x33, 0x8f, 0x34, 0xc3, 0x22, 0xc3, 0xef, 0x94, 0x04, 0xee, 0x64,
+	0x80, 0x94, 0x80, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0x04, 0xec, 0x64,
+	0x80, 0x94, 0x80, 0x50, 0x01, 0x22, 0xc3, 0xef, 0x94, 0xfc, 0xee,
+	0x64, 0x80, 0x94, 0x7f, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0xfc, 0xec,
+	0x64, 0x80, 0x94, 0x7f, 0x50, 0x01, 0x22, 0xd3, 0xef, 0x94, 0x04,
+	0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x0d, 0xc3, 0xed, 0x94, 0xfc,
+	0xec, 0x64, 0x80, 0x94, 0x7f, 0x40, 0x02, 0xd3, 0x22, 0xc3, 0x22,
+	0x90, 0x30, 0x78, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0xff, 0x22,
+	0x90, 0x30, 0x64, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0x25, 0xe0,
+	0xff, 0xee, 0x33, 0xfe, 0x22, 0xc2, 0x0b, 0xe4, 0xf5, 0x14, 0x12,
+	0x10, 0xf1, 0x22, 0xe4, 0xfe, 0xef, 0xf4, 0x60, 0x41, 0x74, 0x04,
+	0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe0, 0xb4, 0xff,
+	0x23, 0x74, 0x04, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83,
+	0xef, 0xf0, 0x30, 0x0b, 0x0d, 0x74, 0x08, 0x2e, 0xf5, 0x82, 0xe4,
+	0x34, 0x21, 0xf5, 0x83, 0xe5, 0x14, 0xf0, 0x90, 0x00, 0x02, 0x74,
+	0x01, 0xf0, 0x22, 0xbe, 0x03, 0x0a, 0x90, 0x00, 0x02, 0x74, 0x01,
+	0xf0, 0xe4, 0xfe, 0x80, 0xc2, 0x0e, 0x80, 0xbf, 0x22, 0x8e, 0x15,
+	0x8f, 0x16, 0xca, 0xed, 0xca, 0xc9, 0xeb, 0xc9, 0x30, 0x0a, 0x04,
+	0x7f, 0x4a, 0x80, 0x02, 0x7f, 0x42, 0xcb, 0xef, 0xcb, 0xea, 0xc3,
+	0x94, 0x04, 0x50, 0x02, 0x80, 0x01, 0xc3, 0x40, 0x04, 0xcb, 0x44,
+	0x20, 0xcb, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xeb, 0xf0, 0xa3,
+	0xe4, 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xa3, 0xa3, 0xe5,
+	0x1a, 0xf0, 0xe5, 0x19, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xa3,
+	0xa3, 0xa3, 0xf0, 0xe5, 0x16, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35,
+	0x15, 0xf5, 0x83, 0x74, 0x0f, 0xf0, 0xe5, 0x16, 0x24, 0x05, 0xf5,
+	0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x24,
+	0x06, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe4, 0xf0, 0xe5,
+	0x16, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74,
+	0x10, 0xf0, 0xea, 0x90, 0x1b, 0x83, 0x93, 0xfb, 0xea, 0x64, 0x01,
+	0x60, 0x08, 0xea, 0x64, 0x02, 0x60, 0x03, 0xba, 0x03, 0x04, 0xcb,
+	0x44, 0x08, 0xcb, 0xe5, 0x16, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35,
+	0x15, 0xf5, 0x83, 0xeb, 0xf0, 0xe5, 0x16, 0x24, 0x15, 0xf5, 0x82,
+	0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0xff, 0xf0, 0xe5, 0x16, 0x24,
+	0x16, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe9, 0xf0, 0xe5,
+	0x16, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74,
+	0x04, 0xf0, 0x25, 0x1a, 0xf5, 0x1a, 0xe4, 0x35, 0x19, 0xf5, 0x19,
+	0xea, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x02, 0x12, 0xf0, 0xea, 0x60,
+	0x03, 0xba, 0x01, 0x1f, 0xea, 0x24, 0x01, 0xfd, 0xe4, 0x33, 0xfc,
+	0xe5, 0x1a, 0xae, 0x19, 0x78, 0x03, 0xc3, 0x33, 0xce, 0x33, 0xce,
+	0xd8, 0xf9, 0xff, 0x12, 0x03, 0xb0, 0x8e, 0x19, 0x8f, 0x1a, 0x02,
+	0x12, 0xd0, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e,
+	0x00, 0x7f, 0x0b, 0x12, 0x03, 0x9e, 0xcc, 0xee, 0xcc, 0xcd, 0xef,
+	0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5,
+	0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x03, 0xb0, 0x8c, 0x1b,
+	0x8d, 0x1c, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e,
+	0x00, 0x7f, 0x0b, 0x12, 0x03, 0x9e, 0xcc, 0xee, 0xcc, 0xcd, 0xef,
+	0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5,
+	0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x03, 0xb0, 0x8e, 0x19,
+	0x8f, 0x1a, 0xe5, 0x1c, 0x45, 0x1b, 0x60, 0x08, 0x05, 0x1a, 0xe5,
+	0x1a, 0x70, 0x02, 0x05, 0x19, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34,
+	0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x03, 0x12, 0x03, 0x9e, 0xd3, 0xe5,
+	0x1c, 0x9f, 0xe5, 0x1b, 0x9e, 0x50, 0x18, 0xe5, 0x1c, 0x45, 0x1b,
+	0x60, 0x12, 0xba, 0x03, 0x0f, 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82,
+	0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x16,
+	0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe5, 0x1a,
+	0xf0, 0xe5, 0x19, 0xff, 0xe5, 0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4,
+	0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x2d, 0xe5, 0x1a, 0x54,
+	0x3f, 0xff, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15,
+	0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x1a, 0xae, 0x19, 0x78, 0x06, 0xce,
+	0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe5, 0x16, 0x24, 0x0b,
+	0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0x85, 0x16,
+	0x82, 0x85, 0x15, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x90, 0x30,
+	0x30, 0x74, 0x02, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90,
+	0x30, 0x30, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x12, 0x15, 0x12, 0x70,
+	0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xeb, 0xe5, 0x12,
+	0x45, 0x11, 0x70, 0x12, 0x12, 0x13, 0xae, 0x90, 0x21, 0x00, 0xe0,
+	0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, 0x22,
+	0xe4, 0x90, 0x34, 0x58, 0xf0, 0x90, 0x34, 0x32, 0x74, 0x1f, 0xf0,
+	0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90, 0x34, 0x81, 0xe0, 0x64,
+	0x03, 0x60, 0x0e, 0xe5, 0x12, 0x15, 0x12, 0x70, 0x02, 0x15, 0x11,
+	0xe5, 0x12, 0x45, 0x11, 0x70, 0xea, 0xe5, 0x12, 0x45, 0x11, 0x70,
+	0x12, 0x12, 0x13, 0xae, 0x90, 0x21, 0x00, 0xe0, 0x60, 0x07, 0x90,
+	0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, 0x22, 0x90, 0x34, 0x98,
+	0xe0, 0x44, 0x04, 0xf0, 0xe4, 0x90, 0x00, 0x01, 0xf0, 0xd3, 0x22,
+	0x90, 0x00, 0x01, 0x74, 0x0e, 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x54,
+	0xfb, 0xf0, 0x90, 0x34, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x30, 0x30,
+	0x74, 0x04, 0xf0, 0x22, 0x8e, 0x16, 0x8f, 0x17, 0x8c, 0x18, 0x8d,
+	0x19, 0xe4, 0xff, 0xef, 0xc3, 0x9b, 0x50, 0x53, 0xe5, 0x1b, 0x30,
+	0xe0, 0x12, 0xef, 0x7c, 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, 0x18,
+	0x8d, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x1c, 0x80, 0x1f, 0xe5, 0x1b,
+	0x30, 0xe1, 0x13, 0xef, 0x7c, 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35,
+	0x18, 0x8d, 0x82, 0xf5, 0x83, 0xe4, 0x93, 0xf5, 0x1c, 0x80, 0x07,
+	0xe5, 0x19, 0x2f, 0xf8, 0xe6, 0xf5, 0x1c, 0xe5, 0x1b, 0x30, 0xe4,
+	0x0f, 0xe5, 0x17, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x16, 0xf5, 0x83,
+	0xe5, 0x1c, 0xf0, 0x80, 0x06, 0xe5, 0x17, 0x2f, 0xf8, 0xa6, 0x1c,
+	0x0f, 0x80, 0xa8, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xc4, 0x33, 0x54,
+	0xe0, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xab, 0x82, 0xfa,
+	0x12, 0x10, 0xd8, 0x8b, 0x82, 0x8a, 0x83, 0xee, 0x8f, 0xf0, 0x12,
+	0x04, 0x05, 0x7e, 0x22, 0x7f, 0x30, 0xcd, 0xeb, 0xcd, 0xcc, 0xea,
+	0xcc, 0x12, 0x18, 0x42, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d,
+	0x12, 0x10, 0xe8, 0x22, 0xe5, 0x30, 0x12, 0x04, 0x3f, 0x14, 0x83,
+	0x00, 0x14, 0xf1, 0x01, 0x15, 0x59, 0x02, 0x15, 0xed, 0x03, 0x16,
+	0x41, 0x04, 0x16, 0x88, 0x05, 0x16, 0xfb, 0x06, 0x17, 0x6a, 0x07,
+	0x00, 0x00, 0x17, 0xa2, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30,
+	0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34,
+	0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44,
+	0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6,
+	0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d,
+	0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53,
+	0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7,
+	0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d,
+	0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53,
+	0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a,
+	0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30,
+	0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34,
+	0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44,
+	0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, 0xe5, 0x27, 0x30,
+	0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5,
+	0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x1f, 0x43, 0x12,
+	0x08, 0x80, 0x1a, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02,
+	0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43,
+	0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43,
+	0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01,
+	0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x43, 0x12,
+	0x01, 0x43, 0x12, 0x04, 0xe5, 0x26, 0x30, 0xe5, 0x5c, 0x90, 0x34,
+	0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c,
+	0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43,
+	0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80,
+	0x30, 0x43, 0x12, 0x08, 0x80, 0x2b, 0xe5, 0x27, 0x30, 0xe6, 0x05,
+	0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30,
+	0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0xe5,
+	0x27, 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0,
+	0x4f, 0xf0, 0xe4, 0xf5, 0x2c, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0,
+	0x80, 0x15, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x27,
+	0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0x4f,
+	0xf0, 0x90, 0x30, 0x35, 0xe0, 0xf5, 0x12, 0x53, 0x12, 0xe0, 0xe5,
+	0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a,
+	0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x30, 0xe5, 0x3c, 0x90, 0x34, 0x98,
+	0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12,
+	0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05,
+	0x53, 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0xe5, 0x26, 0x54,
+	0xc0, 0x60, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x80, 0x06,
+	0x53, 0x12, 0xfe, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12,
+	0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0xc2,
+	0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5,
+	0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12,
+	0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03,
+	0x53, 0x12, 0xf7, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x08, 0x53, 0x12,
+	0xfe, 0x53, 0x12, 0xfb, 0x80, 0x06, 0x43, 0x12, 0x01, 0x43, 0x12,
+	0x04, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x30, 0x3a,
+	0xe5, 0x12, 0xf0, 0x22, 0x20, 0x02, 0x13, 0x12, 0x1c, 0x39, 0xaf,
+	0x29, 0x7e, 0x00, 0x12, 0x1c, 0x70, 0xaf, 0x35, 0x7e, 0x00, 0x12,
+	0x1c, 0x77, 0xd2, 0x02, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5,
+	0x26, 0x20, 0xe5, 0x0d, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x34,
+	0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44,
+	0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x2c, 0xc2, 0x01, 0x12,
+	0x00, 0x06, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80,
+	0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12,
+	0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12,
+	0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x30, 0x01, 0x03,
+	0x02, 0x17, 0xa2, 0x12, 0x18, 0xf4, 0xd2, 0x01, 0x22, 0xc2, 0x01,
+	0x12, 0x00, 0x06, 0xe5, 0x26, 0x20, 0xe5, 0x09, 0x90, 0x34, 0x98,
+	0xe0, 0x54, 0xfe, 0xf0, 0x80, 0x55, 0x90, 0x34, 0x98, 0xe0, 0x44,
+	0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6,
+	0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d,
+	0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53,
+	0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7,
+	0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d,
+	0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53,
+	0x12, 0xf7, 0x43, 0x12, 0x01, 0x53, 0x12, 0xfb, 0x90, 0x30, 0x3a,
+	0xe5, 0x12, 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x22, 0xe5,
+	0x26, 0x30, 0xe5, 0x2c, 0x20, 0x03, 0x21, 0xd2, 0x03, 0x12, 0x1c,
+	0x39, 0x75, 0x35, 0x06, 0x75, 0x29, 0x09, 0xaf, 0x29, 0x7e, 0x00,
+	0x12, 0x1c, 0x70, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x53, 0x12,
+	0xfe, 0x43, 0x12, 0x04, 0xe5, 0x12, 0xf0, 0x90, 0x34, 0x98, 0xe0,
+	0x44, 0x01, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0,
+	0x22, 0xe4, 0xff, 0xe5, 0x30, 0x24, 0xfe, 0x70, 0x2c, 0xe4, 0xfe,
+	0xee, 0xc3, 0x95, 0x2c, 0x50, 0x12, 0x74, 0x01, 0xc8, 0xee, 0xc8,
+	0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xcf, 0x4f, 0xcf, 0x0e,
+	0x80, 0xe8, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0xfe, 0xe5, 0x27,
+	0x54, 0x1f, 0x6f, 0xf4, 0xce, 0x4e, 0xce, 0xee, 0xf0, 0x22, 0x90,
+	0x29, 0xa0, 0xe0, 0x70, 0x63, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3,
+	0x74, 0xc2, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90,
+	0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa0, 0xf0, 0x90, 0x30, 0x8c,
+	0xe4, 0xf0, 0xa3, 0x74, 0xc5, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3,
+	0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa1, 0xf0,
+	0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc4, 0xf0, 0xa3, 0x74,
+	0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90,
+	0x29, 0xa2, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc3,
+	0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c,
+	0xe0, 0x90, 0x29, 0xa3, 0xf0, 0x22, 0x8c, 0x13, 0x8d, 0x14, 0xef,
+	0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3,
+	0xe0, 0x4c, 0x60, 0x41, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e,
+	0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83, 0xe0,
+	0xfc, 0xa3, 0xe0, 0xfd, 0x85, 0x14, 0x82, 0x85, 0x13, 0x83, 0xe0,
+	0xfa, 0xa3, 0xe0, 0xfb, 0xd3, 0xed, 0x9b, 0xea, 0x64, 0x80, 0xf8,
+	0xec, 0x64, 0x80, 0x98, 0x40, 0x13, 0xef, 0x24, 0x1e, 0xf5, 0x82,
+	0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xce, 0xec, 0xce,
+	0xff, 0x80, 0xaf, 0xad, 0x14, 0xac, 0x13, 0x12, 0x1a, 0x71, 0x22,
+	0x12, 0x08, 0xca, 0x50, 0x4f, 0xe5, 0x34, 0x24, 0x12, 0xff, 0xe4,
+	0x35, 0x33, 0xfe, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35,
+	0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, 0x0d, 0xa0, 0xe5,
+	0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0,
+	0xff, 0x7e, 0x00, 0x12, 0x0e, 0x29, 0x90, 0x00, 0x0a, 0x74, 0x40,
+	0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x40, 0xff, 0xf0, 0x90, 0x00,
+	0x0a, 0x74, 0x80, 0xf0, 0x4f, 0x90, 0x00, 0x0b, 0xf0, 0x90, 0x30,
+	0xe9, 0x74, 0x01, 0xf0, 0x75, 0x2f, 0x06, 0x22, 0x90, 0x30, 0x3a,
+	0xe0, 0xff, 0xe5, 0x27, 0x30, 0xe6, 0x12, 0x30, 0x0c, 0x06, 0xef,
+	0x54, 0xf5, 0xfe, 0x80, 0x04, 0xef, 0x44, 0x0a, 0xfe, 0xcf, 0xee,
+	0xcf, 0x80, 0x10, 0x30, 0x0c, 0x06, 0xef, 0x44, 0x0a, 0xfe, 0x80,
+	0x04, 0xef, 0x54, 0xf5, 0xfe, 0xcf, 0xee, 0xcf, 0xcf, 0x54, 0xfe,
+	0xcf, 0xcf, 0x44, 0x04, 0xcf, 0x90, 0x30, 0x3a, 0xef, 0xf0, 0x30,
+	0x0c, 0x09, 0x7f, 0x08, 0x7e, 0x00, 0x12, 0x1c, 0x70, 0x80, 0x07,
+	0x7f, 0x22, 0x7e, 0x01, 0x12, 0x1c, 0x70, 0xb2, 0x0c, 0x22, 0xc0,
+	0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0,
+	0x08, 0xc2, 0xaf, 0xc2, 0x8c, 0xc2, 0x8d, 0xd3, 0xe5, 0x4a, 0x94,
+	0x00, 0xe5, 0x49, 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4a, 0x15, 0x4a,
+	0x70, 0x02, 0x15, 0x49, 0xd3, 0xe5, 0x4c, 0x94, 0x00, 0xe5, 0x4b,
+	0x94, 0x00, 0x40, 0x08, 0xe5, 0x4c, 0x15, 0x4c, 0x70, 0x02, 0x15,
+	0x4b, 0x12, 0x00, 0x0e, 0xd2, 0x8c, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
+	0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x30, 0x07, 0x3c,
+	0xe5, 0x2f, 0x70, 0x38, 0xc2, 0x07, 0x90, 0x22, 0x2e, 0xe0, 0xfe,
+	0xa3, 0xe0, 0x8e, 0x11, 0xf5, 0x12, 0x90, 0x22, 0x4e, 0xe0, 0xfe,
+	0xa3, 0xe0, 0xff, 0x90, 0x22, 0x2e, 0xee, 0xf0, 0xa3, 0xef, 0xf0,
+	0x90, 0x22, 0x4e, 0xe5, 0x11, 0xf0, 0xa3, 0xe5, 0x12, 0xf0, 0x8e,
+	0x33, 0x8f, 0x34, 0x30, 0x08, 0x05, 0x12, 0x14, 0x2b, 0xc2, 0x08,
+	0xc2, 0x09, 0x12, 0x0e, 0x47, 0x22, 0x7f, 0x80, 0x7e, 0x29, 0xe4,
+	0xfd, 0xfc, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfb, 0x74, 0x45, 0x2d,
+	0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x04, 0x2f, 0xf5, 0x82, 0xe4, 0x3e,
+	0xf5, 0x83, 0xe0, 0xfb, 0x74, 0x41, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6,
+	0x74, 0x08, 0x2f, 0xff, 0xe4, 0x3e, 0xfe, 0x0d, 0xbd, 0x00, 0x01,
+	0x0c, 0xed, 0x64, 0x04, 0x4c, 0x70, 0xcf, 0x22, 0x90, 0x00, 0x00,
+	0x74, 0x0e, 0xf0, 0x00, 0x00, 0x00, 0xe4, 0xf0, 0x12, 0x05, 0xcb,
+	0x12, 0x1c, 0x84, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5,
+	0x30, 0xb4, 0x05, 0x0a, 0x12, 0x1c, 0x51, 0x50, 0x0d, 0x12, 0x18,
+	0xf4, 0x80, 0x08, 0xe5, 0x30, 0xb4, 0x07, 0x03, 0x12, 0x06, 0xe8,
+	0x12, 0x04, 0x6b, 0x80, 0xe4, 0x80, 0xfe, 0x22, 0xef, 0x24, 0x1e,
+	0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb,
+	0xca, 0xec, 0xca, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83,
+	0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4,
+	0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xce, 0xea, 0xce,
+	0xcf, 0xeb, 0xcf, 0x22, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e,
+	0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xed, 0x24, 0x1e, 0xf5,
+	0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xea, 0xf0, 0xa3, 0xeb, 0xf0, 0xef,
+	0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3,
+	0xed, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc2, 0xaf, 0xc2, 0x8e,
+	0xc2, 0x8f, 0xd3, 0xe5, 0x40, 0x94, 0x00, 0xe5, 0x3f, 0x94, 0x00,
+	0x40, 0x0d, 0xe5, 0x40, 0x15, 0x40, 0x70, 0x02, 0x15, 0x3f, 0x12,
+	0x1c, 0x67, 0xd2, 0x8e, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0xe0, 0x32,
+	0x12, 0x08, 0xca, 0x50, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c,
+	0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90,
+	0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09,
+	0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x19, 0xce, 0x90,
+	0x21, 0x01, 0xe0, 0xf5, 0x28, 0x74, 0x41, 0x25, 0x28, 0xf8, 0xe6,
+	0xf5, 0x32, 0x74, 0x45, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x22, 0x90,
+	0x21, 0x00, 0xe0, 0x60, 0x03, 0xd2, 0x0d, 0x22, 0xc2, 0x0d, 0x22,
+	0x90, 0x34, 0x30, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x1f, 0xf0,
+	0xa3, 0xe4, 0xf0, 0x90, 0x01, 0x10, 0xe0, 0x20, 0xe1, 0x03, 0x00,
+	0x80, 0xf6, 0x90, 0x01, 0x12, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80,
+	0xf6, 0x22, 0xe4, 0xff, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x90, 0x30,
+	0x8c, 0xf0, 0xef, 0x90, 0x1b, 0xba, 0x93, 0x90, 0x30, 0x8d, 0xf0,
+	0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3,
+	0x22, 0xe4, 0xff, 0xef, 0x90, 0x1b, 0xc4, 0x93, 0x90, 0x30, 0x8c,
+	0xf0, 0xef, 0x90, 0x1b, 0xba, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3,
+	0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22,
+	0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60,
+	0x6c, 0x90, 0xc8, 0x00, 0x01, 0x02, 0x03, 0x0b, 0x0f, 0x0a, 0x0e,
+	0x09, 0x0d, 0x08, 0x0c, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0x3f, 0x4f, 0xf0, 0x90, 0x01, 0x02,
+	0xe0, 0x44, 0x80, 0xf0, 0x22, 0xe4, 0xf5, 0x31, 0x90, 0x00, 0x0a,
+	0x74, 0xff, 0xf0, 0x90, 0x22, 0x2e, 0x74, 0x21, 0xf0, 0xa3, 0x74,
+	0x10, 0xf0, 0x22, 0x52, 0x53, 0x54, 0x12, 0x15, 0x16, 0x10, 0x11,
+	0x40, 0x00, 0x20, 0x00, 0x40, 0xff, 0x3f, 0x3f, 0xbd, 0x28, 0x21,
+	0x00, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, 0x74, 0xb0, 0xf0,
+	0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x22, 0x75, 0x31, 0x01,
+	0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44,
+	0x20, 0xf0, 0x22, 0x02, 0x1f, 0x07, 0x67, 0x18, 0x9f, 0x06, 0x60,
+	0x00, 0x09, 0x1a, 0xc5, 0x05, 0x2f, 0x1c, 0x11, 0x90, 0x30, 0x40,
+	0x74, 0x32, 0xf0, 0xa3, 0x74, 0xb0, 0xf0, 0xa3, 0xe4, 0xf0, 0xa3,
+	0xf0, 0x22, 0x12, 0x08, 0xca, 0x50, 0x08, 0xd2, 0x09, 0x12, 0x0e,
+	0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x90, 0x34, 0x30, 0x74, 0x1f, 0xf0,
+	0xa3, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0x22, 0x78, 0x7f, 0xe4,
+	0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x4c, 0x02, 0x1a, 0x07, 0xc2, 0xaf,
+	0xc2, 0x8c, 0xc2, 0x8d, 0x12, 0x00, 0x0e, 0xd2, 0xaf, 0x22, 0xc2,
+	0x8e, 0x8e, 0x3f, 0x8f, 0x40, 0x12, 0x1c, 0x67, 0xd2, 0x8e, 0x22,
+	0xe5, 0x4a, 0x45, 0x49, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22,
+	0xe5, 0x4c, 0x45, 0x4b, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22,
+	0xc2, 0x8f, 0x75, 0x8d, 0xf5, 0x75, 0x8b, 0x41, 0x22, 0x8e, 0x49,
+	0x8f, 0x4a, 0xd2, 0x8c, 0x22, 0x8e, 0x4b, 0x8f, 0x4c, 0xd2, 0x8c,
+	0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x0d, 0xe4, 0xf5,
+	0x2e, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbb, 0x60
+};
+
+static const uint8_t rt2661_ucode[] = {
+	0x02, 0x12, 0xde, 0x02, 0x14, 0xf0, 0xc2, 0x8c, 0x22, 0x22, 0x00,
+	0x02, 0x16, 0xe5, 0xc2, 0xaf, 0xc2, 0x8d, 0x75, 0x8c, 0x94, 0x75,
+	0x8a, 0x93, 0xd2, 0xaf, 0x22, 0x02, 0x19, 0x89, 0xe5, 0x30, 0x12,
+	0x0f, 0xe5, 0x00, 0x3f, 0x00, 0x00, 0xad, 0x01, 0x01, 0x15, 0x02,
+	0x01, 0xa9, 0x03, 0x01, 0xfd, 0x04, 0x02, 0x44, 0x05, 0x02, 0xb7,
+	0x06, 0x03, 0x26, 0x07, 0x00, 0x00, 0x03, 0x5e, 0xc2, 0x01, 0x12,
+	0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20,
+	0xe5, 0x08, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90,
+	0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f,
+	0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43,
+	0x12, 0x02, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12,
+	0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f,
+	0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43,
+	0x12, 0x08, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12,
+	0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12,
+	0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12,
+	0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20,
+	0xe5, 0x08, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90,
+	0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60,
+	0x1c, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03,
+	0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7,
+	0x80, 0x1f, 0x43, 0x12, 0x08, 0x80, 0x1a, 0xe5, 0x27, 0x30, 0xe6,
+	0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27,
+	0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7,
+	0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12,
+	0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0,
+	0xf5, 0x12, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0xe5, 0x26, 0x30,
+	0xe5, 0x5c, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26,
+	0x54, 0xc0, 0x60, 0x1c, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12,
+	0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05,
+	0x53, 0x12, 0xf7, 0x80, 0x30, 0x43, 0x12, 0x08, 0x80, 0x2b, 0xe5,
+	0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12,
+	0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03,
+	0x53, 0x12, 0xf7, 0xe5, 0x27, 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30,
+	0x34, 0xe0, 0x54, 0xe0, 0x4f, 0xf0, 0xe4, 0xf5, 0x2c, 0x90, 0x30,
+	0x3a, 0xe5, 0x12, 0xf0, 0x80, 0x15, 0x90, 0x34, 0x98, 0xe0, 0x54,
+	0xfe, 0xf0, 0xe5, 0x27, 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34,
+	0xe0, 0x54, 0xe0, 0x4f, 0xf0, 0x90, 0x30, 0x35, 0xe0, 0xf5, 0x12,
+	0x53, 0x12, 0xe0, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00,
+	0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x30, 0xe5,
+	0x3c, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x27, 0x30,
+	0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5,
+	0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12,
+	0x08, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x08, 0x43, 0x12, 0x01, 0x43,
+	0x12, 0x04, 0x80, 0x06, 0x53, 0x12, 0xfe, 0x43, 0x12, 0x04, 0x90,
+	0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54,
+	0xfe, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a,
+	0xe0, 0xf5, 0x12, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02,
+	0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43,
+	0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0xe5, 0x26, 0x54, 0xc0,
+	0x60, 0x08, 0x53, 0x12, 0xfe, 0x53, 0x12, 0xfb, 0x80, 0x06, 0x43,
+	0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01,
+	0xf0, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x20, 0x02, 0x13,
+	0x12, 0x1c, 0x9c, 0xaf, 0x29, 0x7e, 0x00, 0x12, 0x1c, 0xf2, 0xaf,
+	0x35, 0x7e, 0x00, 0x12, 0x1c, 0xf9, 0xd2, 0x02, 0x90, 0x30, 0x3a,
+	0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x0d, 0xc2, 0x01, 0x12,
+	0x00, 0x06, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90,
+	0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60,
+	0x2c, 0xc2, 0x01, 0x12, 0x00, 0x06, 0xe5, 0x27, 0x30, 0xe6, 0x05,
+	0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30,
+	0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0x43,
+	0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0,
+	0x22, 0x30, 0x01, 0x03, 0x02, 0x03, 0x5e, 0x12, 0x09, 0x81, 0xd2,
+	0x01, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0xe5, 0x26, 0x20, 0xe5,
+	0x09, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x80, 0x55, 0x90,
+	0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f,
+	0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43,
+	0x12, 0x02, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12,
+	0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f,
+	0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43,
+	0x12, 0x08, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12,
+	0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x53, 0x12,
+	0xfb, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x90, 0x30, 0x3a, 0xe0,
+	0xf5, 0x12, 0x22, 0xe5, 0x26, 0x30, 0xe5, 0x2c, 0x20, 0x03, 0x21,
+	0xd2, 0x03, 0x12, 0x1c, 0x9c, 0x75, 0x35, 0x06, 0x75, 0x29, 0x09,
+	0xaf, 0x29, 0x7e, 0x00, 0x12, 0x1c, 0xf2, 0x90, 0x30, 0x3a, 0xe0,
+	0xf5, 0x12, 0x53, 0x12, 0xfe, 0x43, 0x12, 0x04, 0xe5, 0x12, 0xf0,
+	0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x90, 0x34, 0x98,
+	0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x12, 0x1c, 0x72, 0x40, 0x03, 0x02,
+	0x05, 0x5f, 0x90, 0x21, 0x02, 0xe0, 0xf5, 0x2d, 0x90, 0x00, 0x03,
+	0xe0, 0x12, 0x0f, 0xe5, 0x03, 0xf1, 0x00, 0x04, 0x0f, 0x01, 0x03,
+	0x9f, 0x10, 0x03, 0xb0, 0x11, 0x04, 0x33, 0x20, 0x04, 0x8e, 0x21,
+	0x04, 0xb1, 0x22, 0x04, 0xc5, 0x30, 0x04, 0xd0, 0x31, 0x05, 0x16,
+	0x50, 0x04, 0xe0, 0x51, 0x05, 0x33, 0x52, 0x05, 0x47, 0x60, 0x00,
+	0x00, 0x05, 0x55, 0x90, 0x00, 0x0a, 0xe0, 0x20, 0xe5, 0x03, 0x30,
+	0x07, 0x03, 0xd2, 0x08, 0x22, 0x12, 0x18, 0xb6, 0x22, 0x90, 0x21,
+	0x00, 0xe0, 0xf5, 0x11, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24,
+	0x21, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe0, 0x44, 0x80,
+	0xf0, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24, 0x2c, 0xf5, 0x82,
+	0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x11, 0xf0, 0xc4, 0x33, 0x54,
+	0xe0, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5,
+	0x2d, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, 0x12, 0x08, 0xc7,
+	0x90, 0x21, 0x00, 0xe0, 0xf5, 0x31, 0x60, 0x05, 0x12, 0x09, 0x5c,
+	0x80, 0x03, 0x12, 0x09, 0x6d, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf,
+	0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x75, 0x31, 0xff, 0x90, 0x01, 0x00,
+	0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x54, 0xfe, 0xf0,
+	0x54, 0x3e, 0xf0, 0xe4, 0x90, 0x00, 0x0b, 0xf0, 0xf0, 0x90, 0x21,
+	0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x7e, 0x2b, 0x7f,
+	0x80, 0x7d, 0x03, 0x12, 0x0a, 0x4f, 0x90, 0x34, 0xcd, 0xe0, 0x20,
+	0xe3, 0xf9, 0x90, 0x21, 0x14, 0x12, 0x0f, 0xc1, 0x90, 0x34, 0xc0,
+	0x12, 0x0f, 0xcd, 0x90, 0x21, 0x18, 0x12, 0x0f, 0xc1, 0x90, 0x34,
+	0xc8, 0x12, 0x0f, 0xcd, 0x90, 0x21, 0x1c, 0x12, 0x0f, 0xc1, 0x90,
+	0x34, 0xc4, 0x12, 0x0f, 0xcd, 0x90, 0x34, 0xcc, 0x74, 0x01, 0xf0,
+	0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x01,
+	0xf0, 0x44, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x10, 0xf0,
+	0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22,
+	0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0,
+	0x54, 0xfe, 0xf0, 0x54, 0xbf, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54,
+	0xef, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c,
+	0xe0, 0x22, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0x4f,
+	0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22,
+	0xd2, 0x05, 0x85, 0x2d, 0x23, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22,
+	0x12, 0x1b, 0x23, 0xc2, 0x00, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf,
+	0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x85, 0x2d, 0x25, 0x90, 0x00, 0x0b,
+	0xe0, 0x54, 0xfb, 0xff, 0xf0, 0xe4, 0x90, 0x00, 0x07, 0xf0, 0x90,
+	0x00, 0x0a, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x00, 0x08, 0xf0, 0x90,
+	0x21, 0x00, 0xe0, 0x90, 0x00, 0x09, 0xf0, 0x90, 0x00, 0x07, 0x74,
+	0x71, 0xf0, 0xef, 0x44, 0x04, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90,
+	0x21, 0x03, 0xf0, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xff, 0x54, 0x1f,
+	0xf5, 0x30, 0xa3, 0xe0, 0xf5, 0x27, 0x8f, 0x26, 0x12, 0x00, 0x1e,
+	0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22,
+	0x90, 0x21, 0x00, 0xe0, 0xf5, 0x2c, 0x12, 0x18, 0xed, 0xe4, 0x90,
+	0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x12, 0x1a,
+	0x02, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0,
+	0x22, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0,
+	0x22, 0x8e, 0x15, 0x8f, 0x16, 0xca, 0xed, 0xca, 0xc9, 0xeb, 0xc9,
+	0x30, 0x0a, 0x04, 0x7f, 0x4a, 0x80, 0x02, 0x7f, 0x42, 0xcb, 0xef,
+	0xcb, 0xea, 0xc3, 0x94, 0x04, 0x50, 0x02, 0x80, 0x01, 0xc3, 0x40,
+	0x04, 0xcb, 0x44, 0x20, 0xcb, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83,
+	0xeb, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83,
+	0xa3, 0xa3, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0x85, 0x16, 0x82, 0x85,
+	0x15, 0x83, 0xa3, 0xa3, 0xa3, 0xf0, 0xe5, 0x16, 0x24, 0x04, 0xf5,
+	0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x0f, 0xf0, 0xe5, 0x16,
+	0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe4, 0xf0,
+	0xe5, 0x16, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83,
+	0xe4, 0xf0, 0xe5, 0x16, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x15,
+	0xf5, 0x83, 0x74, 0x10, 0xf0, 0xea, 0x90, 0x1b, 0x4b, 0x93, 0xfb,
+	0xea, 0x64, 0x01, 0x60, 0x08, 0xea, 0x64, 0x02, 0x60, 0x03, 0xba,
+	0x03, 0x04, 0xcb, 0x44, 0x08, 0xcb, 0xe5, 0x16, 0x24, 0x08, 0xf5,
+	0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xeb, 0xf0, 0xe5, 0x16, 0x24,
+	0x15, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0xff, 0xf0,
+	0xe5, 0x16, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83,
+	0xe9, 0xf0, 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15,
+	0xf5, 0x83, 0x74, 0x04, 0xf0, 0x25, 0x1a, 0xf5, 0x1a, 0xe4, 0x35,
+	0x19, 0xf5, 0x19, 0xea, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x02, 0x07,
+	0x17, 0xea, 0x60, 0x03, 0xba, 0x01, 0x1f, 0xea, 0x24, 0x01, 0xfd,
+	0xe4, 0x33, 0xfc, 0xe5, 0x1a, 0xae, 0x19, 0x78, 0x03, 0xc3, 0x33,
+	0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x12, 0x0f, 0x56, 0x8e, 0x19,
+	0x8f, 0x1a, 0x02, 0x06, 0xf7, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34,
+	0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x0f, 0x44, 0xcc, 0xee,
+	0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8,
+	0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x0f,
+	0x56, 0x8c, 0x1b, 0x8d, 0x1c, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34,
+	0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x0f, 0x44, 0xcc, 0xee,
+	0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8,
+	0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x0f,
+	0x56, 0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1c, 0x45, 0x1b, 0x60, 0x08,
+	0x05, 0x1a, 0xe5, 0x1a, 0x70, 0x02, 0x05, 0x19, 0xea, 0x24, 0xff,
+	0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x03, 0x12, 0x0f,
+	0x44, 0xd3, 0xe5, 0x1c, 0x9f, 0xe5, 0x1b, 0x9e, 0x50, 0x18, 0xe5,
+	0x1c, 0x45, 0x1b, 0x60, 0x12, 0xba, 0x03, 0x0f, 0xe5, 0x16, 0x24,
+	0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe0, 0x44, 0x80,
+	0xf0, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5,
+	0x83, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0xff, 0xe5, 0x16, 0x24, 0x0b,
+	0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x2d,
+	0xe5, 0x1a, 0x54, 0x3f, 0xff, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82,
+	0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x1a, 0xae, 0x19,
+	0x78, 0x06, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe5,
+	0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef,
+	0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xe0, 0x44, 0x01, 0xf0,
+	0x22, 0x90, 0x34, 0xcd, 0xe0, 0xf9, 0x20, 0xe3, 0xf8, 0xe5, 0x2b,
+	0xf4, 0x60, 0x66, 0x90, 0x34, 0xc0, 0x12, 0x0f, 0xc1, 0x85, 0x34,
+	0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x0f,
+	0xd9, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5,
+	0x83, 0x12, 0x0f, 0xcd, 0x90, 0x34, 0xc8, 0x12, 0x0f, 0xc1, 0x85,
+	0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12,
+	0x0f, 0xd9, 0xe5, 0x82, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83,
+	0xf5, 0x83, 0x12, 0x0f, 0xcd, 0x90, 0x34, 0xd0, 0x12, 0x0f, 0xc1,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b,
+	0x12, 0x0f, 0xd9, 0xe5, 0x82, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35,
+	0x83, 0xf5, 0x83, 0x12, 0x0f, 0xcd, 0xe5, 0x34, 0x24, 0xf0, 0xff,
+	0xe5, 0x33, 0x34, 0xde, 0xfe, 0xef, 0x78, 0x05, 0xce, 0xc3, 0x13,
+	0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x2b, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0x75, 0xf0, 0x20, 0x12, 0x0f, 0xd9, 0xe5, 0x82, 0x24, 0x04,
+	0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x0f, 0xc1, 0x90,
+	0x34, 0xc0, 0x12, 0x0f, 0xcd, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x0f, 0xd9, 0xe5, 0x82, 0x24,
+	0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x0f, 0xc1,
+	0x90, 0x34, 0xc8, 0x12, 0x0f, 0xcd, 0x85, 0x34, 0x82, 0x85, 0x33,
+	0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x0f, 0xd9, 0xe5, 0x82,
+	0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x0f,
+	0xc1, 0x90, 0x34, 0xc4, 0x12, 0x0f, 0xcd, 0x90, 0x01, 0x01, 0xe0,
+	0x44, 0x40, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0, 0xe9,
+	0x44, 0x04, 0x90, 0x34, 0xcd, 0xf0, 0x90, 0x34, 0xcc, 0xe0, 0x44,
+	0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01,
+	0xf0, 0x22, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83,
+	0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xed, 0x24, 0x1e, 0xf5, 0x82, 0xe4,
+	0x3c, 0xf5, 0x83, 0xea, 0xf0, 0xa3, 0xeb, 0xf0, 0xef, 0x24, 0x1e,
+	0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0,
+	0x22, 0x00, 0x00, 0x90, 0x00, 0x00, 0x74, 0x0e, 0xf0, 0x00, 0x00,
+	0x00, 0xe4, 0xf0, 0x12, 0x08, 0xc7, 0x12, 0x1d, 0x06, 0x90, 0x34,
+	0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x30, 0xb4, 0x05, 0x0a, 0x12,
+	0x1c, 0xca, 0x50, 0x0d, 0x12, 0x09, 0x81, 0x80, 0x08, 0xe5, 0x30,
+	0xb4, 0x07, 0x03, 0x12, 0x09, 0xd0, 0x12, 0x10, 0xd7, 0x80, 0xe4,
+	0x80, 0xfe, 0x22, 0xc2, 0xaf, 0xe4, 0xf5, 0x2f, 0xf5, 0x88, 0x75,
+	0xa8, 0x0f, 0x75, 0x89, 0x11, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90,
+	0x0f, 0x75, 0x31, 0xff, 0x75, 0x2b, 0xff, 0x90, 0x22, 0x2e, 0xf0,
+	0xa3, 0xf0, 0x90, 0x22, 0x4e, 0xf0, 0xa3, 0xf0, 0xc2, 0x05, 0xc2,
+	0x08, 0xc2, 0x00, 0xc2, 0x07, 0xc2, 0x04, 0x90, 0x00, 0x0a, 0x74,
+	0xff, 0xf0, 0x90, 0x00, 0x0b, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x03,
+	0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0x04, 0xf0, 0x90, 0x01, 0x05,
+	0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0x06, 0xf0, 0x90, 0x00, 0x04,
+	0xf0, 0x90, 0x30, 0xe8, 0x74, 0x10, 0xf0, 0x90, 0x01, 0x07, 0xf0,
+	0x90, 0x01, 0x08, 0x04, 0xf0, 0x90, 0x01, 0x09, 0x74, 0x48, 0xf0,
+	0x90, 0x01, 0x0a, 0x74, 0x7f, 0xf0, 0x90, 0x01, 0x02, 0x74, 0x1f,
+	0xf0, 0x90, 0x01, 0x00, 0x74, 0x14, 0xf0, 0x90, 0x01, 0x01, 0x74,
+	0x20, 0xf0, 0x90, 0x00, 0x00, 0xe0, 0x44, 0x80, 0xf0, 0x75, 0x49,
+	0x00, 0x75, 0x4a, 0x01, 0xc2, 0x01, 0xd2, 0xaf, 0x22, 0x75, 0x31,
+	0x01, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b, 0xe0,
+	0x44, 0x20, 0xf0, 0x22, 0xe4, 0xf5, 0x31, 0x90, 0x00, 0x0a, 0x74,
+	0xff, 0xf0, 0x90, 0x22, 0x2e, 0x74, 0x21, 0xf0, 0xa3, 0x74, 0x10,
+	0xf0, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xff, 0xe5, 0x27, 0x30, 0xe6,
+	0x12, 0x30, 0x0c, 0x06, 0xef, 0x54, 0xf5, 0xfe, 0x80, 0x04, 0xef,
+	0x44, 0x0a, 0xfe, 0xcf, 0xee, 0xcf, 0x80, 0x10, 0x30, 0x0c, 0x06,
+	0xef, 0x44, 0x0a, 0xfe, 0x80, 0x04, 0xef, 0x54, 0xf5, 0xfe, 0xcf,
+	0xee, 0xcf, 0xcf, 0x54, 0xfe, 0xcf, 0xcf, 0x44, 0x04, 0xcf, 0x90,
+	0x30, 0x3a, 0xef, 0xf0, 0x30, 0x0c, 0x09, 0x7f, 0x08, 0x7e, 0x00,
+	0x12, 0x1c, 0xf2, 0x80, 0x07, 0x7f, 0x22, 0x7e, 0x01, 0x12, 0x1c,
+	0xf2, 0xb2, 0x0c, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x10, 0x12,
+	0x1c, 0xd5, 0x50, 0x26, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x10,
+	0xfd, 0x80, 0x03, 0x43, 0x10, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05,
+	0x53, 0x10, 0xf7, 0x80, 0x03, 0x43, 0x10, 0x08, 0x53, 0x10, 0xfe,
+	0x43, 0x10, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0x12, 0x1c,
+	0xca, 0x50, 0x48, 0x90, 0x01, 0x03, 0xe0, 0xf5, 0x10, 0x54, 0x1c,
+	0x60, 0x3e, 0xe5, 0x10, 0x54, 0xe3, 0xf0, 0xa3, 0xe0, 0xf5, 0x10,
+	0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x10, 0x02, 0x80, 0x03,
+	0x53, 0x10, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x10, 0x08,
+	0x80, 0x03, 0x53, 0x10, 0xf7, 0x53, 0x10, 0xfe, 0x43, 0x10, 0x04,
+	0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0xaf, 0x29, 0x7e, 0x00, 0x12,
+	0x1c, 0xf2, 0xaf, 0x35, 0x7e, 0x00, 0x12, 0x1c, 0xf9, 0x22, 0x8e,
+	0x12, 0x8f, 0x13, 0x8d, 0x14, 0xe5, 0x14, 0xa2, 0xe1, 0x92, 0x09,
+	0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83,
+	0xe0, 0xfd, 0xe5, 0x34, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x33,
+	0xf5, 0x83, 0xe0, 0xfb, 0xa2, 0x09, 0x92, 0x0a, 0x75, 0x19, 0x00,
+	0x75, 0x1a, 0x1a, 0x12, 0x05, 0x60, 0x30, 0x09, 0x04, 0x7f, 0xc8,
+	0x80, 0x02, 0x7f, 0xe8, 0xe5, 0x13, 0x24, 0x18, 0xf5, 0x82, 0xe4,
+	0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x31, 0x60, 0x04, 0x7f,
+	0x02, 0x80, 0x02, 0x7f, 0x01, 0xe5, 0x13, 0x24, 0x19, 0xf5, 0x82,
+	0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x34, 0x24, 0x19,
+	0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x7d, 0x1a,
+	0x7c, 0x00, 0x12, 0x10, 0x11, 0xe5, 0x13, 0x24, 0x1a, 0xf5, 0x82,
+	0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x13, 0x24, 0x1b,
+	0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xee, 0xf0, 0xe5, 0x31,
+	0x60, 0x60, 0xe5, 0x13, 0x24, 0x1c, 0xff, 0xe4, 0x35, 0x12, 0xfe,
+	0xe5, 0x34, 0x24, 0x12, 0xfd, 0xe4, 0x35, 0x33, 0xfc, 0x75, 0x1b,
+	0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, 0x22, 0xff,
+	0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11,
+	0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4,
+	0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b,
+	0x06, 0x12, 0x15, 0xd0, 0xe5, 0x34, 0x24, 0x18, 0xf5, 0x82, 0xe4,
+	0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x13, 0x24, 0x2d, 0xf5,
+	0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x3f, 0xe5,
+	0x13, 0x24, 0x1c, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d,
+	0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13,
+	0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x08,
+	0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24,
+	0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75,
+	0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, 0x2e,
+	0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x13,
+	0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe4, 0xf0,
+	0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83,
+	0xe0, 0xff, 0xc3, 0x13, 0xff, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82,
+	0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x09, 0x41, 0xe5,
+	0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0,
+	0xff, 0xe5, 0x31, 0x60, 0x04, 0x7e, 0x00, 0x80, 0x02, 0x7e, 0x10,
+	0xef, 0x4e, 0xf0, 0xe5, 0x31, 0x60, 0x06, 0x7e, 0x00, 0x7f, 0x00,
+	0x80, 0x0f, 0xe5, 0x14, 0x30, 0xe0, 0x06, 0x7e, 0x00, 0x7f, 0xff,
+	0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, 0xf5,
+	0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, 0x13,
+	0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, 0x44,
+	0x40, 0xf0, 0xe5, 0x14, 0x30, 0xe0, 0x0f, 0xe5, 0x34, 0x24, 0x10,
+	0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x80, 0x02,
+	0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12,
+	0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82,
+	0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe7, 0x3b, 0xe5, 0x34,
+	0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x65,
+	0x2b, 0x70, 0x03, 0x75, 0x2b, 0xff, 0xe5, 0x34, 0x24, 0x1d, 0xf5,
+	0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x1c, 0xe0,
+	0x7e, 0x22, 0x7f, 0x10, 0x12, 0x19, 0x56, 0x8e, 0x33, 0x8f, 0x34,
+	0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34,
+	0xc3, 0x22, 0xd2, 0x0a, 0xe5, 0x34, 0x24, 0x1b, 0xf5, 0x82, 0xe4,
+	0x35, 0x33, 0xf5, 0x83, 0xe0, 0x70, 0x3a, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3,
+	0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xfe, 0xd0, 0x82,
+	0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xd3, 0x94, 0x00, 0xee, 0x64,
+	0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x0d, 0x68, 0x80, 0xc6, 0x85,
+	0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0xee,
+	0x64, 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x0d, 0x68, 0x12, 0x1c,
+	0xbf, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0,
+	0xfd, 0xc3, 0x9f, 0xee, 0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98,
+	0x40, 0x20, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0,
+	0x82, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xed, 0x9f, 0xff,
+	0xec, 0x9e, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xc2,
+	0x0a, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0,
+	0xff, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5,
+	0x83, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xfd, 0xee, 0x94, 0x00, 0xfc,
+	0x12, 0x17, 0x30, 0x50, 0x2c, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34,
+	0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd,
+	0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0,
+	0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x20, 0x0a, 0x03, 0x02, 0x0c, 0x78,
+	0x7e, 0x22, 0x7f, 0x10, 0x12, 0x19, 0x56, 0x8e, 0x33, 0x8f, 0x34,
+	0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xd3, 0x94, 0x00,
+	0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0d, 0x7e, 0x22, 0x7f, 0x10,
+	0xad, 0x34, 0xac, 0x33, 0x12, 0x16, 0x33, 0x80, 0x1a, 0x12, 0x1c,
+	0x35, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xee, 0x8f, 0xf0, 0x12,
+	0x0f, 0xab, 0x7e, 0x22, 0x7f, 0x30, 0xad, 0x34, 0xac, 0x33, 0x12,
+	0x16, 0x33, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x65,
+	0x34, 0x70, 0x03, 0xee, 0x65, 0x33, 0x70, 0x02, 0xd3, 0x22, 0x8e,
+	0x33, 0x8f, 0x34, 0xc3, 0x22, 0xe5, 0x31, 0x64, 0x01, 0x70, 0x41,
+	0x12, 0x1b, 0x83, 0x40, 0x03, 0x02, 0x0f, 0x43, 0x12, 0x1c, 0x00,
+	0x50, 0x20, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0x4f,
+	0x7f, 0x01, 0x12, 0x1a, 0x27, 0x40, 0x09, 0xd2, 0x09, 0x12, 0x11,
+	0x9b, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x07, 0x4f, 0x75, 0x2f, 0x01,
+	0x22, 0x7f, 0x01, 0x12, 0x1a, 0x27, 0x50, 0x04, 0x75, 0x2f, 0x02,
+	0x22, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, 0x22, 0x12,
+	0x1a, 0xcc, 0x50, 0x51, 0x12, 0x1c, 0x55, 0x90, 0x30, 0xf4, 0xe0,
+	0xf5, 0x2a, 0x7e, 0x30, 0x7f, 0xec, 0xa3, 0xe0, 0xfd, 0xe4, 0xfb,
+	0x12, 0x19, 0xda, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0xb4, 0x90, 0x00,
+	0x0a, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xff,
+	0xf0, 0xfd, 0x90, 0x01, 0x05, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06,
+	0xe0, 0x44, 0x20, 0xf0, 0xed, 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0,
+	0x90, 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01,
+	0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xd2, 0x04, 0x12, 0x1a, 0xe9,
+	0x50, 0x43, 0x12, 0x1b, 0x06, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x30,
+	0x7d, 0xec, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90,
+	0x30, 0xf5, 0xe0, 0x75, 0xf0, 0x20, 0xa4, 0xff, 0xae, 0xf0, 0x12,
+	0x1c, 0xb4, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd,
+	0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf,
+	0xf0, 0x90, 0x00, 0x0a, 0x74, 0x40, 0xf0, 0x4d, 0x90, 0x00, 0x0b,
+	0xf0, 0xc2, 0x04, 0x12, 0x1b, 0xad, 0x50, 0x38, 0x12, 0x1b, 0x06,
+	0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, 0x00, 0x75, 0x1b, 0x12,
+	0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0,
+	0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0xb4, 0x90,
+	0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0,
+	0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0x04, 0x12, 0x1b,
+	0xd7, 0x50, 0x25, 0x12, 0x1b, 0x06, 0x7f, 0x02, 0x12, 0x1a, 0x27,
+	0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0x90, 0x00, 0x0b, 0xe0,
+	0x54, 0xfd, 0xff, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xef, 0x54,
+	0xbf, 0x90, 0x00, 0x0b, 0xf0, 0xc2, 0x04, 0x12, 0x1b, 0x83, 0x50,
+	0x2d, 0x12, 0x1b, 0x06, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d,
+	0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00,
+	0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x90, 0x01, 0x06,
+	0xe0, 0x54, 0xdf, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0,
+	0xc2, 0x04, 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c,
+	0xf0, 0xa4, 0x28, 0xce, 0x8d, 0xf0, 0xa4, 0x2e, 0xfe, 0x22, 0xbc,
+	0x00, 0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad,
+	0xf0, 0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff,
+	0xee, 0x33, 0xfe, 0xec, 0x33, 0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40,
+	0x05, 0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce,
+	0xfd, 0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c,
+	0xfe, 0xad, 0xf0, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33,
+	0xfd, 0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, 0xc3,
+	0x98, 0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xc5, 0xf0, 0xf8, 0xa3,
+	0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70,
+	0x02, 0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22, 0xe0, 0xfc, 0xa3, 0xe0,
+	0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x22, 0xec, 0xf0, 0xa3,
+	0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22, 0xa4, 0x25,
+	0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xd0,
+	0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93,
+	0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82,
+	0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3,
+	0xa3, 0xa3, 0x80, 0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0x8f,
+	0x15, 0x8c, 0x16, 0x8d, 0x17, 0xe5, 0x15, 0xc3, 0x94, 0x04, 0x50,
+	0x56, 0xe5, 0x15, 0x94, 0x00, 0x40, 0x06, 0x7a, 0x00, 0x7b, 0x60,
+	0x80, 0x04, 0x7a, 0x00, 0x7b, 0xc0, 0xe5, 0x17, 0xc4, 0xf8, 0x54,
+	0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48, 0xfe,
+	0xe5, 0x15, 0x90, 0x1b, 0x3d, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x0f,
+	0x56, 0xef, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xc4, 0xf8,
+	0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48,
+	0xfe, 0xe5, 0x15, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x0f, 0x56, 0xed,
+	0x4c, 0x60, 0x63, 0x0b, 0xbb, 0x00, 0x01, 0x0a, 0x80, 0x5c, 0x7a,
+	0x00, 0x7b, 0x1a, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, 0xc3, 0x33,
+	0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, 0x3e, 0xfe,
+	0xe5, 0x15, 0x90, 0x1b, 0x3d, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x0f,
+	0x56, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9,
+	0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02,
+	0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4,
+	0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x3d, 0x93, 0xfd, 0x7c, 0x00,
+	0x12, 0x0f, 0x56, 0xed, 0x4c, 0x60, 0x07, 0x74, 0x04, 0x2b, 0xfb,
+	0xe4, 0x3a, 0xfa, 0xcf, 0xeb, 0xcf, 0xce, 0xea, 0xce, 0x22, 0xe5,
+	0x2e, 0x14, 0x60, 0x1d, 0x14, 0x60, 0x3d, 0x14, 0x60, 0x5d, 0x14,
+	0x70, 0x03, 0x02, 0x11, 0x84, 0x24, 0x04, 0x60, 0x03, 0x02, 0x11,
+	0x9a, 0x20, 0x0d, 0x03, 0x02, 0x11, 0x9a, 0x75, 0x2e, 0x01, 0x22,
+	0x90, 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x03, 0x44, 0x20, 0xf0,
+	0xe5, 0x40, 0x45, 0x3f, 0x60, 0x03, 0x02, 0x11, 0x9a, 0x75, 0x2e,
+	0x02, 0x12, 0x1a, 0x4a, 0x12, 0x1c, 0x13, 0xaf, 0x28, 0x12, 0x1b,
+	0x57, 0x22, 0x90, 0x01, 0x03, 0xe0, 0xff, 0x30, 0xe7, 0x76, 0xef,
+	0x44, 0x80, 0x90, 0x01, 0x03, 0xf0, 0x12, 0x18, 0x42, 0x12, 0x1a,
+	0x8d, 0x12, 0x1c, 0x45, 0x75, 0x2e, 0x03, 0xaf, 0x22, 0x7e, 0x00,
+	0x12, 0x1c, 0xa8, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, 0x21, 0x12,
+	0x15, 0x66, 0x12, 0x1c, 0x13, 0x12, 0x1a, 0x6d, 0x12, 0x1c, 0x45,
+	0x12, 0x1c, 0x8e, 0x30, 0x0d, 0x0b, 0x75, 0x2e, 0x01, 0xaf, 0x32,
+	0x7e, 0x00, 0x12, 0x1c, 0xa8, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90,
+	0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x2c, 0x44, 0x20, 0xf0, 0x12,
+	0x15, 0x66, 0x12, 0x1c, 0x13, 0x12, 0x1a, 0x6d, 0x12, 0x1c, 0x45,
+	0x12, 0x1c, 0x8e, 0x75, 0x2e, 0x04, 0x22, 0xe5, 0x40, 0x45, 0x3f,
+	0x70, 0x10, 0x30, 0x0d, 0x0a, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0xfe,
+	0x12, 0x1c, 0xa8, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, 0x00, 0x04,
+	0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x30, 0x09, 0x32, 0xe5,
+	0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff,
+	0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3,
+	0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0,
+	0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02,
+	0xc3, 0x22, 0x12, 0x0c, 0x2e, 0x50, 0xf3, 0x90, 0x00, 0x0a, 0xe0,
+	0x20, 0xe5, 0x03, 0x30, 0x07, 0x41, 0xe5, 0x34, 0x45, 0x33, 0x70,
+	0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83,
+	0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85,
+	0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef,
+	0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef,
+	0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x12, 0x0c,
+	0x2e, 0x50, 0xf3, 0x80, 0xb5, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83,
+	0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x17, 0xc0, 0xd3, 0x22, 0x12,
+	0x1b, 0xad, 0x40, 0x05, 0x12, 0x1b, 0x83, 0x50, 0x44, 0x7e, 0x30,
+	0x7f, 0xe0, 0x7c, 0x1d, 0x7d, 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06,
+	0x12, 0x15, 0xd0, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00,
+	0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0xb4, 0x90, 0x00, 0x0b,
+	0xe0, 0x54, 0xbf, 0xf0, 0x54, 0x7f, 0xff, 0xf0, 0xe4, 0x90, 0x30,
+	0xe9, 0xf0, 0xef, 0x54, 0xfd, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90,
+	0x00, 0x04, 0xf0, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f,
+	0x12, 0x1b, 0xc2, 0x50, 0x48, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d,
+	0x7d, 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90,
+	0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff,
+	0xfe, 0x12, 0x1c, 0xb4, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0,
+	0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xff, 0x12, 0x1a,
+	0x27, 0x50, 0x04, 0x75, 0x2f, 0x07, 0x22, 0x90, 0x01, 0x04, 0xe0,
+	0x54, 0x7f, 0xf0, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f,
+	0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x4c, 0x02,
+	0x13, 0x25, 0x02, 0x08, 0x90, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93,
+	0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80,
+	0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3,
+	0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4,
+	0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02,
+	0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x00, 0x0a, 0xe4, 0x7e,
+	0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09,
+	0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54,
+	0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa,
+	0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8,
+	0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca,
+	0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x12, 0x1b,
+	0x83, 0x50, 0x2d, 0x12, 0x19, 0x22, 0x90, 0x01, 0x06, 0xe0, 0x54,
+	0xdf, 0xf0, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, 0x00, 0x75,
+	0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00, 0x04, 0x74,
+	0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x11, 0x9b,
+	0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x1b, 0xd7, 0x50, 0x50, 0x12, 0x19,
+	0x22, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00,
+	0x04, 0xf0, 0x90, 0x01, 0x03, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04,
+	0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x02, 0x12, 0x1a, 0x27, 0x50, 0x04,
+	0x75, 0x2f, 0x05, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d,
+	0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00,
+	0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12,
+	0x11, 0x9b, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5,
+	0x2f, 0x22, 0x90, 0x30, 0x30, 0x74, 0x02, 0xf0, 0x75, 0x11, 0x07,
+	0x75, 0x12, 0xd0, 0x90, 0x30, 0x30, 0xe0, 0x30, 0xe0, 0x0e, 0xe5,
+	0x12, 0x15, 0x12, 0x70, 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11,
+	0x70, 0xeb, 0xe5, 0x12, 0x45, 0x11, 0x70, 0x12, 0x12, 0x1b, 0x23,
+	0x90, 0x21, 0x00, 0xe0, 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44,
+	0x04, 0xf0, 0xc3, 0x22, 0xe4, 0x90, 0x34, 0x58, 0xf0, 0x90, 0x34,
+	0x32, 0x74, 0x1f, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90,
+	0x34, 0x81, 0xe0, 0x64, 0x03, 0x60, 0x0e, 0xe5, 0x12, 0x15, 0x12,
+	0x70, 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xea, 0xe5,
+	0x12, 0x45, 0x11, 0x70, 0x12, 0x12, 0x1b, 0x23, 0x90, 0x21, 0x00,
+	0xe0, 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3,
+	0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe4, 0x90, 0x00,
+	0x01, 0xf0, 0xd3, 0x22, 0x12, 0x1b, 0x6e, 0x50, 0x72, 0x12, 0x1c,
+	0xbf, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0,
+	0xc3, 0x9f, 0xf5, 0x12, 0xec, 0x9e, 0xf5, 0x11, 0xd3, 0xe5, 0x12,
+	0x94, 0x00, 0xe5, 0x11, 0x64, 0x80, 0x94, 0x80, 0x40, 0x06, 0xae,
+	0x11, 0xaf, 0x12, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x8e, 0x11,
+	0x8f, 0x12, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33,
+	0xf5, 0x83, 0xe0, 0xc3, 0x95, 0x12, 0xf5, 0x12, 0xe4, 0x95, 0x11,
+	0xf5, 0x11, 0xc3, 0x64, 0x80, 0x94, 0x80, 0x50, 0x05, 0xe4, 0xf5,
+	0x11, 0xf5, 0x12, 0xe5, 0x34, 0x24, 0x12, 0xff, 0xe4, 0x35, 0x33,
+	0xfe, 0xad, 0x12, 0x7b, 0x01, 0x12, 0x19, 0xda, 0x90, 0x01, 0x05,
+	0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x44, 0x20, 0xf0, 0x75,
+	0x2f, 0x03, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82,
+	0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, 0x90, 0x22, 0x2e, 0xe0,
+	0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, 0xe5, 0x2f, 0x25, 0xe0,
+	0x24, 0x25, 0xf5, 0x82, 0xe4, 0x34, 0x1c, 0xf5, 0x83, 0xe4, 0x93,
+	0xfe, 0x74, 0x01, 0x93, 0xca, 0xee, 0xca, 0xf9, 0x12, 0x10, 0x0b,
+	0x12, 0x1c, 0x80, 0x50, 0x02, 0xd2, 0x07, 0x12, 0x18, 0x02, 0x12,
+	0x03, 0x5f, 0x12, 0x1b, 0x98, 0x50, 0x05, 0xaf, 0x25, 0x12, 0x1c,
+	0xe0, 0x30, 0x05, 0x1b, 0xe5, 0x2f, 0x70, 0x17, 0x20, 0x04, 0x14,
+	0x12, 0x13, 0xf2, 0x92, 0x00, 0xc2, 0x05, 0xd2, 0x0b, 0xa2, 0x00,
+	0xe4, 0x33, 0xf5, 0x14, 0xaf, 0x23, 0x12, 0x17, 0x78, 0xd2, 0xaf,
+	0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32,
+	0x90, 0x29, 0xa0, 0xe0, 0x70, 0x63, 0x90, 0x30, 0x8c, 0xe4, 0xf0,
+	0xa3, 0x74, 0xc2, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0,
+	0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa0, 0xf0, 0x90, 0x30,
+	0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc5, 0xf0, 0xa3, 0x74, 0x01, 0xf0,
+	0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa1,
+	0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc4, 0xf0, 0xa3,
+	0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff,
+	0x90, 0x29, 0xa2, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74,
+	0xc3, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30,
+	0x8c, 0xe0, 0x90, 0x29, 0xa3, 0xf0, 0x22, 0x8e, 0x16, 0x8f, 0x17,
+	0x8c, 0x18, 0x8d, 0x19, 0xe4, 0xff, 0xef, 0xc3, 0x9b, 0x50, 0x53,
+	0xe5, 0x1b, 0x30, 0xe0, 0x12, 0xef, 0x7c, 0x00, 0x25, 0x19, 0xfd,
+	0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x1c, 0x80,
+	0x1f, 0xe5, 0x1b, 0x30, 0xe1, 0x13, 0xef, 0x7c, 0x00, 0x25, 0x19,
+	0xfd, 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, 0x83, 0xe4, 0x93, 0xf5,
+	0x1c, 0x80, 0x07, 0xe5, 0x19, 0x2f, 0xf8, 0xe6, 0xf5, 0x1c, 0xe5,
+	0x1b, 0x30, 0xe4, 0x0f, 0xe5, 0x17, 0x2f, 0xf5, 0x82, 0xe4, 0x35,
+	0x16, 0xf5, 0x83, 0xe5, 0x1c, 0xf0, 0x80, 0x06, 0xe5, 0x17, 0x2f,
+	0xf8, 0xa6, 0x1c, 0x0f, 0x80, 0xa8, 0x22, 0x8c, 0x13, 0x8d, 0x14,
+	0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc,
+	0xa3, 0xe0, 0x4c, 0x60, 0x41, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4,
+	0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83,
+	0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x85, 0x14, 0x82, 0x85, 0x13, 0x83,
+	0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xd3, 0xed, 0x9b, 0xea, 0x64, 0x80,
+	0xf8, 0xec, 0x64, 0x80, 0x98, 0x40, 0x13, 0xef, 0x24, 0x1e, 0xf5,
+	0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xce, 0xec,
+	0xce, 0xff, 0x80, 0xaf, 0xad, 0x14, 0xac, 0x13, 0x12, 0x08, 0x63,
+	0x22, 0x12, 0x1b, 0x6e, 0x50, 0x4f, 0xe5, 0x34, 0x24, 0x12, 0xff,
+	0xe4, 0x35, 0x33, 0xfe, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4,
+	0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, 0x19, 0xda,
+	0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83,
+	0xe0, 0xff, 0x7e, 0x00, 0x12, 0x1c, 0xb4, 0x90, 0x00, 0x0a, 0x74,
+	0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x40, 0xff, 0xf0, 0x90,
+	0x00, 0x0a, 0x74, 0x80, 0xf0, 0x4f, 0x90, 0x00, 0x0b, 0xf0, 0x90,
+	0x30, 0xe9, 0x74, 0x01, 0xf0, 0x75, 0x2f, 0x06, 0x22, 0xc0, 0xe0,
+	0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08,
+	0xc2, 0xaf, 0xc2, 0x8c, 0xc2, 0x8d, 0xd3, 0xe5, 0x4a, 0x94, 0x00,
+	0xe5, 0x49, 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4a, 0x15, 0x4a, 0x70,
+	0x02, 0x15, 0x49, 0xd3, 0xe5, 0x4c, 0x94, 0x00, 0xe5, 0x4b, 0x94,
+	0x00, 0x40, 0x08, 0xe5, 0x4c, 0x15, 0x4c, 0x70, 0x02, 0x15, 0x4b,
+	0x12, 0x00, 0x0e, 0xd2, 0x8c, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82,
+	0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc3, 0xef, 0x94, 0x04,
+	0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0x04,
+	0xec, 0x64, 0x80, 0x94, 0x80, 0x50, 0x01, 0x22, 0xc3, 0xef, 0x94,
+	0xfc, 0xee, 0x64, 0x80, 0x94, 0x7f, 0x40, 0x0c, 0xd3, 0xed, 0x94,
+	0xfc, 0xec, 0x64, 0x80, 0x94, 0x7f, 0x50, 0x01, 0x22, 0xd3, 0xef,
+	0x94, 0x04, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x0d, 0xc3, 0xed,
+	0x94, 0xfc, 0xec, 0x64, 0x80, 0x94, 0x7f, 0x40, 0x02, 0xd3, 0x22,
+	0xc3, 0x22, 0xe4, 0xfe, 0xef, 0xf4, 0x60, 0x41, 0x74, 0x04, 0x2e,
+	0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x23,
+	0x74, 0x04, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xef,
+	0xf0, 0x30, 0x0b, 0x0d, 0x74, 0x08, 0x2e, 0xf5, 0x82, 0xe4, 0x34,
+	0x21, 0xf5, 0x83, 0xe5, 0x14, 0xf0, 0x90, 0x00, 0x02, 0x74, 0x01,
+	0xf0, 0x22, 0xbe, 0x03, 0x0a, 0x90, 0x00, 0x02, 0x74, 0x01, 0xf0,
+	0xe4, 0xfe, 0x80, 0xc2, 0x0e, 0x80, 0xbf, 0x22, 0x8e, 0x13, 0x8f,
+	0x14, 0x12, 0x1c, 0xbf, 0xc3, 0xef, 0x95, 0x14, 0xff, 0xee, 0x95,
+	0x13, 0xcd, 0xef, 0xcd, 0xfc, 0xd3, 0xed, 0x94, 0x00, 0xec, 0x64,
+	0x80, 0x94, 0x80, 0x40, 0x05, 0xce, 0xec, 0xce, 0x80, 0x04, 0x7e,
+	0x00, 0x7f, 0x01, 0xcc, 0xee, 0xcc, 0xec, 0x90, 0x00, 0x05, 0xf0,
+	0x90, 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0,
+	0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x30, 0x07, 0x3c,
+	0xe5, 0x2f, 0x70, 0x38, 0xc2, 0x07, 0x90, 0x22, 0x2e, 0xe0, 0xfe,
+	0xa3, 0xe0, 0x8e, 0x11, 0xf5, 0x12, 0x90, 0x22, 0x4e, 0xe0, 0xfe,
+	0xa3, 0xe0, 0xff, 0x90, 0x22, 0x2e, 0xee, 0xf0, 0xa3, 0xef, 0xf0,
+	0x90, 0x22, 0x4e, 0xe5, 0x11, 0xf0, 0xa3, 0xe5, 0x12, 0xf0, 0x8e,
+	0x33, 0x8f, 0x34, 0x30, 0x08, 0x05, 0x12, 0x18, 0xb6, 0xc2, 0x08,
+	0xc2, 0x09, 0x12, 0x11, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0x30, 0x8c,
+	0xe4, 0xf0, 0xef, 0x90, 0x1b, 0xec, 0x93, 0x44, 0x80, 0x90, 0x30,
+	0x8d, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30,
+	0x8c, 0xe0, 0xfe, 0x74, 0x36, 0x2f, 0xf8, 0xc6, 0xee, 0xc6, 0xa3,
+	0xe0, 0xfe, 0xef, 0x90, 0x1b, 0xec, 0x93, 0x44, 0x80, 0x6e, 0x60,
+	0x01, 0x1f, 0x0f, 0xef, 0xc3, 0x94, 0x09, 0x40, 0xc8, 0x22, 0x7f,
+	0x80, 0x7e, 0x29, 0xe4, 0xfd, 0xfc, 0x8f, 0x82, 0x8e, 0x83, 0xe0,
+	0xfb, 0x74, 0x45, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x04, 0x2f,
+	0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfb, 0x74, 0x41, 0x2d,
+	0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x08, 0x2f, 0xff, 0xe4, 0x3e, 0xfe,
+	0x0d, 0xbd, 0x00, 0x01, 0x0c, 0xed, 0x64, 0x04, 0x4c, 0x70, 0xcf,
+	0x22, 0x90, 0x21, 0x00, 0xe0, 0xc4, 0x33, 0x54, 0xe0, 0x24, 0x10,
+	0xf5, 0x82, 0xe4, 0x34, 0x21, 0xab, 0x82, 0xfa, 0x12, 0x1c, 0x35,
+	0x8b, 0x82, 0x8a, 0x83, 0xee, 0x8f, 0xf0, 0x12, 0x0f, 0xab, 0x7e,
+	0x22, 0x7f, 0x30, 0xcd, 0xeb, 0xcd, 0xcc, 0xea, 0xcc, 0x12, 0x16,
+	0x33, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0,
+	0x22, 0xe4, 0xff, 0xe5, 0x30, 0x24, 0xfe, 0x70, 0x2c, 0xe4, 0xfe,
+	0xee, 0xc3, 0x95, 0x2c, 0x50, 0x12, 0x74, 0x01, 0xc8, 0xee, 0xc8,
+	0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xcf, 0x4f, 0xcf, 0x0e,
+	0x80, 0xe8, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0xfe, 0xe5, 0x27,
+	0x54, 0x1f, 0x6f, 0xf4, 0xce, 0x4e, 0xce, 0xee, 0xf0, 0x22, 0x90,
+	0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54,
+	0xfe, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x01,
+	0x11, 0xe0, 0x54, 0x22, 0xff, 0xbf, 0x22, 0x03, 0xd3, 0x80, 0x01,
+	0xc3, 0x50, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90,
+	0x01, 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0xef, 0x24, 0x1e, 0xf5,
+	0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb, 0xca,
+	0xec, 0xca, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0,
+	0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e,
+	0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xce, 0xea, 0xce, 0xcf,
+	0xeb, 0xcf, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc2, 0xaf, 0xc2, 0x8e,
+	0xc2, 0x8f, 0xd3, 0xe5, 0x40, 0x94, 0x00, 0xe5, 0x3f, 0x94, 0x00,
+	0x40, 0x0d, 0xe5, 0x40, 0x15, 0x40, 0x70, 0x02, 0x15, 0x3f, 0x12,
+	0x1c, 0xe9, 0xd2, 0x8e, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0xe0, 0x32,
+	0x12, 0x1b, 0x6e, 0x50, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d,
+	0x7d, 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90,
+	0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09,
+	0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, 0x22, 0x8e, 0x13, 0x8f, 0x14,
+	0x8d, 0x15, 0xeb, 0x60, 0x09, 0x14, 0x70, 0x1b, 0xaf, 0x15, 0x12,
+	0x1a, 0xad, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0xac, 0x13, 0xad, 0x14,
+	0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xaf, 0x15, 0x12,
+	0x1a, 0xad, 0x22, 0x12, 0x18, 0x7d, 0x90, 0x21, 0x01, 0xe0, 0xf5,
+	0x28, 0x74, 0x41, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x32, 0x74, 0x45,
+	0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x22, 0x90, 0x21, 0x00, 0xe0, 0x60,
+	0x03, 0xd2, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0xcd, 0xef, 0xcd, 0x90,
+	0x01, 0x02, 0xe0, 0x30, 0xe7, 0x02, 0xc3, 0x22, 0x7e, 0x2a, 0x7f,
+	0x00, 0x12, 0x0a, 0x4f, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, 0xf0,
+	0x90, 0x01, 0x02, 0xe0, 0x44, 0x80, 0xf0, 0xd3, 0x22, 0x90, 0x34,
+	0x30, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x1f, 0xf0, 0xa3, 0xe4,
+	0xf0, 0x90, 0x01, 0x10, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, 0xf6,
+	0x90, 0x01, 0x12, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, 0xf6, 0x22,
+	0xe4, 0xff, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x90, 0x30, 0x8c, 0xf0,
+	0xef, 0x90, 0x1b, 0xec, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74,
+	0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, 0xe4,
+	0xff, 0xef, 0x90, 0x1b, 0xf6, 0x93, 0x90, 0x30, 0x8c, 0xf0, 0xef,
+	0x90, 0x1b, 0xec, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74, 0x01,
+	0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, 0xe4, 0x90,
+	0x00, 0x05, 0xf0, 0xef, 0x60, 0x02, 0x80, 0x02, 0x7f, 0x01, 0x90,
+	0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, 0x90,
+	0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x90, 0x30, 0xf0, 0xe0,
+	0xf5, 0x2a, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30,
+	0xf2, 0xe0, 0x60, 0x08, 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3,
+	0x22, 0xc3, 0x22, 0x90, 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, 0x00,
+	0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x70, 0x08,
+	0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90,
+	0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54,
+	0xfe, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01,
+	0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0x90, 0x00, 0x01, 0x74, 0x0e,
+	0xf0, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x34, 0x58,
+	0x74, 0x01, 0xf0, 0x90, 0x30, 0x30, 0x74, 0x04, 0xf0, 0x22, 0x02,
+	0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c,
+	0x90, 0xc8, 0x00, 0x01, 0x02, 0x03, 0x0b, 0x0f, 0x0a, 0x0e, 0x09,
+	0x0d, 0x08, 0x0c, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0x90,
+	0x01, 0x00, 0xe0, 0x54, 0x3f, 0x4f, 0xf0, 0x90, 0x01, 0x02, 0xe0,
+	0x44, 0x80, 0xf0, 0x22, 0x90, 0x01, 0x03, 0xe0, 0x30, 0xe7, 0x0c,
+	0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0xd3,
+	0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe1, 0x0c, 0x74,
+	0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xd3, 0x22,
+	0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe2, 0x0c, 0x74, 0x04,
+	0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xf0, 0xd3, 0x22, 0xc3,
+	0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe6, 0x0c, 0x74, 0x40, 0xf0,
+	0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xd3, 0x22, 0xc3, 0x22,
+	0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe7, 0x0c, 0x74, 0x80, 0xf0, 0x90,
+	0x00, 0x0b, 0xe0, 0x54, 0x7f, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90,
+	0x01, 0x05, 0xe0, 0x30, 0xe5, 0x0c, 0x74, 0x20, 0xf0, 0x90, 0x01,
+	0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x52, 0x53,
+	0x54, 0x12, 0x15, 0x16, 0x10, 0x11, 0x40, 0x00, 0x20, 0x00, 0x40,
+	0xff, 0x3f, 0x3f, 0xbd, 0x28, 0x21, 0x00, 0xe5, 0x34, 0x24, 0x11,
+	0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe6, 0x02,
+	0xd3, 0x22, 0xc3, 0x22, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3,
+	0x74, 0xb0, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x22,
+	0x0d, 0xc5, 0x14, 0x78, 0x16, 0x90, 0x13, 0x6a, 0x00, 0x09, 0x19,
+	0xb2, 0x12, 0x42, 0x1c, 0x64, 0x90, 0x30, 0x64, 0xe0, 0xfd, 0xa3,
+	0xe0, 0xfe, 0xed, 0x25, 0xe0, 0xff, 0xee, 0x33, 0xfe, 0x22, 0x90,
+	0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, 0x74, 0xb0, 0xf0, 0xa3, 0xe4,
+	0xf0, 0xa3, 0xf0, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0,
+	0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0x22, 0x12, 0x1b, 0x6e,
+	0x50, 0x08, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, 0x22,
+	0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe0, 0x05, 0x74, 0x01, 0xf0, 0xd3,
+	0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe5, 0x05, 0x74,
+	0x20, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x34, 0x30, 0x74, 0x1f,
+	0xf0, 0xa3, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0x22, 0xc2, 0xaf,
+	0xc2, 0x8c, 0xc2, 0x8d, 0x12, 0x00, 0x0e, 0xd2, 0xaf, 0x22, 0xc2,
+	0x8e, 0x8e, 0x3f, 0x8f, 0x40, 0x12, 0x1c, 0xe9, 0xd2, 0x8e, 0x22,
+	0x90, 0x30, 0x3c, 0xef, 0xf0, 0xee, 0x44, 0x80, 0xa3, 0xf0, 0x22,
+	0x90, 0x30, 0x78, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0xff, 0x22,
+	0xe5, 0x4a, 0x45, 0x49, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22,
+	0xe5, 0x4c, 0x45, 0x4b, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22,
+	0xc2, 0x0b, 0xe4, 0xf5, 0x14, 0x12, 0x17, 0x78, 0x22, 0xc2, 0x8f,
+	0x75, 0x8d, 0xf5, 0x75, 0x8b, 0x41, 0x22, 0x8e, 0x49, 0x8f, 0x4a,
+	0xd2, 0x8c, 0x22, 0x8e, 0x4b, 0x8f, 0x4c, 0xd2, 0x8c, 0x22, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x0d, 0xe4, 0xf5, 0x2e, 0x22,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
+	0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43, 0xcf
+};
--- /dev/null
+++ sys/dev/ral/rt2661var.h
@@ -0,0 +1,178 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2661var.h,v 1.3 2007/06/11 03:36:52 sam Exp $	*/
+
+/*-
+ * Copyright (c) 2005
+ *	Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct rt2661_rx_radiotap_header {
+	struct ieee80211_radiotap_header wr_ihdr;
+	uint64_t	wr_tsf;
+	uint8_t		wr_flags;
+	uint8_t		wr_rate;
+	uint16_t	wr_chan_freq;
+	uint16_t	wr_chan_flags;
+	uint8_t		wr_antsignal;
+} __packed;
+
+#define RT2661_RX_RADIOTAP_PRESENT					\
+	((1 << IEEE80211_RADIOTAP_TSFT) |				\
+	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
+	 (1 << IEEE80211_RADIOTAP_RATE) |				\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
+	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+
+struct rt2661_tx_radiotap_header {
+	struct ieee80211_radiotap_header wt_ihdr;
+	uint8_t		wt_flags;
+	uint8_t		wt_rate;
+	uint16_t	wt_chan_freq;
+	uint16_t	wt_chan_flags;
+} __packed;
+
+#define RT2661_TX_RADIOTAP_PRESENT					\
+	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
+	 (1 << IEEE80211_RADIOTAP_RATE) |				\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL))
+
+struct rt2661_tx_data {
+	bus_dmamap_t		map;
+	struct mbuf		*m;
+	struct ieee80211_node	*ni;
+	struct ral_rssdesc	id;
+};
+
+struct rt2661_tx_ring {
+	bus_dma_tag_t		desc_dmat;
+	bus_dma_tag_t		data_dmat;
+	bus_dmamap_t		desc_map;
+	bus_addr_t		physaddr;
+	struct rt2661_tx_desc	*desc;
+	struct rt2661_tx_data	*data;
+	int			count;
+	int			queued;
+	int			cur;
+	int			next;
+	int			stat;
+};
+
+struct rt2661_rx_data {
+	bus_dmamap_t	map;
+	struct mbuf	*m;
+};
+
+struct rt2661_rx_ring {
+	bus_dma_tag_t		desc_dmat;
+	bus_dma_tag_t		data_dmat;
+	bus_dmamap_t		desc_map;
+	bus_addr_t		physaddr;
+	struct rt2661_rx_desc	*desc;
+	struct rt2661_rx_data	*data;
+	int			count;
+	int			cur;
+	int			next;
+};
+
+struct rt2661_node {
+	struct ieee80211_node	ni;
+	struct ral_rssadapt	rssadapt;
+};
+
+struct rt2661_softc {
+	struct ifnet			*sc_ifp;
+	struct ieee80211com		sc_ic;
+	int				(*sc_newstate)(struct ieee80211com *,
+					    enum ieee80211_state, int);
+	device_t			sc_dev;
+	bus_space_tag_t			sc_st;
+	bus_space_handle_t		sc_sh;
+
+	struct mtx			sc_mtx;
+
+	struct callout			watchdog_ch;
+	struct callout			rssadapt_ch;
+
+	int				sc_tx_timer;
+	int                             sc_invalid;
+/*
+ * The same in both up to here
+ * ------------------------------------------------
+ */
+	
+	struct ieee80211_channel	*sc_curchan;
+
+	uint8_t				rf_rev;
+
+	uint8_t				rfprog;
+	uint8_t				rffreq;
+
+	struct rt2661_tx_ring		txq[4];
+	struct rt2661_tx_ring		mgtq;
+	struct rt2661_rx_ring		rxq;
+
+	uint32_t			rf_regs[4];
+	int8_t				txpow[38];
+
+	struct {
+		uint8_t	reg;
+		uint8_t	val;
+	}				bbp_prom[16];
+
+	int				hw_radio;
+	int				rx_ant;
+	int				tx_ant;
+	int				nb_ant;
+	int				ext_2ghz_lna;
+	int				ext_5ghz_lna;
+	int				rssi_2ghz_corr;
+	int				rssi_5ghz_corr;
+
+	uint8_t				bbp18;
+	uint8_t				bbp21;
+	uint8_t				bbp22;
+	uint8_t				bbp16;
+	uint8_t				bbp17;
+	uint8_t				bbp64;
+
+	int				dwelltime;
+
+	struct bpf_if			*sc_drvbpf;
+
+	union {
+		struct rt2661_rx_radiotap_header th;
+		uint8_t	pad[64];
+	}				sc_rxtapu;
+#define sc_rxtap	sc_rxtapu.th
+	int				sc_rxtap_len;
+
+	union {
+		struct rt2661_tx_radiotap_header th;
+		uint8_t	pad[64];
+	}				sc_txtapu;
+#define sc_txtap	sc_txtapu.th
+	int				sc_txtap_len;
+#define                 RAL_INPUT_RUNNING       1
+	int                             sc_flags;
+};
+
+int	rt2661_attach(device_t, int);
+int	rt2661_detach(void *);
+void	rt2661_shutdown(void *);
+void	rt2661_suspend(void *);
+void	rt2661_resume(void *);
+void	rt2661_intr(void *);
+
+#define RAL_LOCK(sc)	mtx_lock(&(sc)->sc_mtx)
+#define RAL_UNLOCK(sc)	mtx_unlock(&(sc)->sc_mtx)
Index: if_ral_pci.c
===================================================================
RCS file: /home/cvs/src/sys/dev/ral/if_ral_pci.c,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -L sys/dev/ral/if_ral_pci.c -L sys/dev/ral/if_ral_pci.c -u -r1.1.1.1 -r1.2
--- sys/dev/ral/if_ral_pci.c
+++ sys/dev/ral/if_ral_pci.c
@@ -1,7 +1,7 @@
-/*	$FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.1.2.1 2005/08/25 05:01:14 rwatson Exp $	*/
+/*	$FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.7 2007/06/11 03:36:52 sam Exp $	*/
 
 /*-
- * Copyright (c) 2005
+ * Copyright (c) 2005, 2006
  *	Damien Bergamini <damien.bergamini at free.fr>
  *
  * Permission to use, copy, modify, and distribute this software for any
@@ -18,10 +18,10 @@
  */
 
 #include <sys/cdefs.h>
-__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.1.2.1 2005/08/25 05:01:14 rwatson Exp $");
+__FBSDID("$FreeBSD: src/sys/dev/ral/if_ral_pci.c,v 1.7 2007/06/11 03:36:52 sam Exp $");
 
 /*
- * PCI front-end for the Ralink RT2500 driver.
+ * PCI/Cardbus front-end for the Ralink RT2560/RT2561/RT2561S/RT2661 driver.
  */
 
 #include <sys/param.h>
@@ -38,7 +38,6 @@
 
 #include <machine/bus.h>
 #include <machine/resource.h>
-#include <machine/clock.h>
 #include <sys/rman.h>
 
 #include <net/bpf.h>
@@ -56,8 +55,8 @@
 #include <dev/pci/pcivar.h>
 
 #include <dev/ral/if_ralrate.h>
-#include <dev/ral/if_ralreg.h>
-#include <dev/ral/if_ralvar.h>
+#include <dev/ral/rt2560var.h>
+#include <dev/ral/rt2661var.h>
 
 MODULE_DEPEND(ral, pci, 1, 1, 1);
 MODULE_DEPEND(ral, wlan, 1, 1, 1);
@@ -69,13 +68,57 @@
 };
 
 static const struct ral_pci_ident ral_pci_ids[] = {
-	{ 0x1814, 0x0201, "Ralink Technology RT2500" },
+	{ 0x1814, 0x0201, "Ralink Technology RT2560" },
+	{ 0x1814, 0x0301, "Ralink Technology RT2561S" },
+	{ 0x1814, 0x0302, "Ralink Technology RT2561" },
+	{ 0x1814, 0x0401, "Ralink Technology RT2661" },
 
 	{ 0, 0, NULL }
 };
 
+static struct ral_opns {
+	int	(*attach)(device_t, int);
+	int	(*detach)(void *);
+	void	(*shutdown)(void *);
+	void	(*suspend)(void *);
+	void	(*resume)(void *);
+	void	(*intr)(void *);
+
+}  ral_rt2560_opns = {
+	rt2560_attach,
+	rt2560_detach,
+	rt2560_stop,
+	rt2560_stop,
+	rt2560_resume,
+	rt2560_intr
+
+}, ral_rt2661_opns = {
+	rt2661_attach,
+	rt2661_detach,
+	rt2661_shutdown,
+	rt2661_suspend,
+	rt2661_resume,
+	rt2661_intr
+};
+
+struct ral_pci_softc {
+	union {
+		struct rt2560_softc sc_rt2560;
+		struct rt2661_softc sc_rt2661;
+	} u;
+
+	struct ral_opns		*sc_opns;
+	int			irq_rid;
+	int			mem_rid;
+	struct resource		*irq;
+	struct resource		*mem;
+	void			*sc_ih;
+};
+
 static int ral_pci_probe(device_t);
 static int ral_pci_attach(device_t);
+static int ral_pci_detach(device_t);
+static int ral_pci_shutdown(device_t);
 static int ral_pci_suspend(device_t);
 static int ral_pci_resume(device_t);
 
@@ -83,7 +126,8 @@
 	/* Device interface */
 	DEVMETHOD(device_probe,		ral_pci_probe),
 	DEVMETHOD(device_attach,	ral_pci_attach),
-	DEVMETHOD(device_detach,	ral_detach),
+	DEVMETHOD(device_detach,	ral_pci_detach),
+	DEVMETHOD(device_shutdown,	ral_pci_shutdown),
 	DEVMETHOD(device_suspend,	ral_pci_suspend),
 	DEVMETHOD(device_resume,	ral_pci_resume),
 
@@ -93,9 +137,11 @@
 static driver_t ral_pci_driver = {
 	"ral",
 	ral_pci_methods,
-	sizeof (struct ral_softc)
+	sizeof (struct ral_pci_softc)
 };
 
+static devclass_t ral_devclass;
+
 DRIVER_MODULE(ral, pci, ral_pci_driver, ral_devclass, 0, 0);
 DRIVER_MODULE(ral, cardbus, ral_pci_driver, ral_devclass, 0, 0);
 
@@ -120,6 +166,8 @@
 static int
 ral_pci_attach(device_t dev)
 {
+	struct ral_pci_softc *psc = device_get_softc(dev);
+	struct rt2560_softc *sc = &psc->u.sc_rt2560;
 	int error;
 
 	if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) {
@@ -131,23 +179,83 @@
 	/* enable bus-mastering */
 	pci_enable_busmaster(dev);
 
-	error = ral_alloc(dev, RAL_PCI_BAR0);
+	psc->sc_opns = (pci_get_device(dev) == 0x0201) ? &ral_rt2560_opns :
+	    &ral_rt2661_opns;
+
+	psc->mem_rid = RAL_PCI_BAR0;
+	psc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &psc->mem_rid,
+	    RF_ACTIVE);
+	if (psc->mem == NULL) {
+		device_printf(dev, "could not allocate memory resource\n");
+		return ENXIO;
+	}
+
+	sc->sc_st = rman_get_bustag(psc->mem);
+	sc->sc_sh = rman_get_bushandle(psc->mem);
+	sc->sc_invalid = 1;
+	
+	psc->irq_rid = 0;
+	psc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &psc->irq_rid,
+	    RF_ACTIVE | RF_SHAREABLE);
+	if (psc->irq == NULL) {
+		device_printf(dev, "could not allocate interrupt resource\n");
+		return ENXIO;
+	}
+
+	error = (*psc->sc_opns->attach)(dev, pci_get_device(dev));
 	if (error != 0)
 		return error;
 
-	error = ral_attach(dev);
-	if (error != 0)
-		ral_free(dev);
+	/*
+	 * Hook our interrupt after all initialization is complete.
+	 */
+	error = bus_setup_intr(dev, psc->irq, INTR_TYPE_NET | INTR_MPSAFE,
+	    NULL, psc->sc_opns->intr, psc, &psc->sc_ih);
+	if (error != 0) {
+		device_printf(dev, "could not set up interrupt\n");
+		return error;
+	}
+	sc->sc_invalid = 0;
+	
+	return 0;
+}
+
+static int
+ral_pci_detach(device_t dev)
+{
+	struct ral_pci_softc *psc = device_get_softc(dev);
+	struct rt2560_softc *sc = &psc->u.sc_rt2560;
+	
+	/* check if device was removed */
+	sc->sc_invalid = !bus_child_present(dev);
+	
+	(*psc->sc_opns->detach)(psc);
+
+	bus_generic_detach(dev);
+	bus_teardown_intr(dev, psc->irq, psc->sc_ih);
+	bus_release_resource(dev, SYS_RES_IRQ, psc->irq_rid, psc->irq);
+
+	bus_release_resource(dev, SYS_RES_MEMORY, psc->mem_rid, psc->mem);
+
+	return 0;
+}
+
+static int
+ral_pci_shutdown(device_t dev)
+{
+	struct ral_pci_softc *psc = device_get_softc(dev);
 
-	return error;
+	(*psc->sc_opns->shutdown)(psc);
+
+	return 0;
 }
 
 static int
 ral_pci_suspend(device_t dev)
 {
-	struct ral_softc *sc = device_get_softc(dev);
+	struct ral_pci_softc *psc = device_get_softc(dev);
 
-	ral_stop(sc);
+	(*psc->sc_opns->suspend)(psc);
 
 	return 0;
 }
@@ -155,14 +263,9 @@
 static int
 ral_pci_resume(device_t dev)
 {
-	struct ral_softc *sc = device_get_softc(dev);
-	struct ifnet *ifp = sc->sc_ic.ic_ifp;
+	struct ral_pci_softc *psc = device_get_softc(dev);
 
-	if (ifp->if_flags & IFF_UP) {
-		ifp->if_init(ifp->if_softc);
-		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
-			ifp->if_start(ifp);
-	}
+	(*psc->sc_opns->resume)(psc);
 
 	return 0;
 }
--- /dev/null
+++ sys/dev/ral/rt2560.c
@@ -0,0 +1,2894 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2560.c,v 1.17 2007/09/17 19:07:23 sam Exp $	*/
+
+/*-
+ * Copyright (c) 2005, 2006
+ *	Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/ral/rt2560.c,v 1.17 2007/09/17 19:07:23 sam Exp $");
+
+/*-
+ * Ralink Technology RT2560 chipset driver
+ * http://www.ralinktech.com/
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_regdomain.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+
+#include <dev/ral/if_ralrate.h>
+#include <dev/ral/rt2560reg.h>
+#include <dev/ral/rt2560var.h>
+
+#define RT2560_RSSI(sc, rssi)					\
+	((rssi) > (RT2560_NOISE_FLOOR + (sc)->rssi_corr) ?	\
+	 ((rssi) - RT2560_NOISE_FLOOR - (sc)->rssi_corr) : 0)
+
+#ifdef RAL_DEBUG
+#define DPRINTF(x)	do { if (ral_debug > 0) printf x; } while (0)
+#define DPRINTFN(n, x)	do { if (ral_debug >= (n)) printf x; } while (0)
+extern int ral_debug;
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n, x)
+#endif
+
+static void		rt2560_dma_map_addr(void *, bus_dma_segment_t *, int,
+			    int);
+static int		rt2560_alloc_tx_ring(struct rt2560_softc *,
+			    struct rt2560_tx_ring *, int);
+static void		rt2560_reset_tx_ring(struct rt2560_softc *,
+			    struct rt2560_tx_ring *);
+static void		rt2560_free_tx_ring(struct rt2560_softc *,
+			    struct rt2560_tx_ring *);
+static int		rt2560_alloc_rx_ring(struct rt2560_softc *,
+			    struct rt2560_rx_ring *, int);
+static void		rt2560_reset_rx_ring(struct rt2560_softc *,
+			    struct rt2560_rx_ring *);
+static void		rt2560_free_rx_ring(struct rt2560_softc *,
+			    struct rt2560_rx_ring *);
+static struct		ieee80211_node *rt2560_node_alloc(
+			    struct ieee80211_node_table *);
+static int		rt2560_media_change(struct ifnet *);
+static void		rt2560_iter_func(void *, struct ieee80211_node *);
+static void		rt2560_update_rssadapt(void *);
+static int		rt2560_newstate(struct ieee80211com *,
+			    enum ieee80211_state, int);
+static uint16_t		rt2560_eeprom_read(struct rt2560_softc *, uint8_t);
+static void		rt2560_encryption_intr(struct rt2560_softc *);
+static void		rt2560_tx_intr(struct rt2560_softc *);
+static void		rt2560_prio_intr(struct rt2560_softc *);
+static void		rt2560_decryption_intr(struct rt2560_softc *);
+static void		rt2560_rx_intr(struct rt2560_softc *);
+static void		rt2560_beacon_update(struct ieee80211com *, int item);
+static void		rt2560_beacon_expire(struct rt2560_softc *);
+static void		rt2560_wakeup_expire(struct rt2560_softc *);
+static uint8_t		rt2560_rxrate(struct rt2560_rx_desc *);
+static int		rt2560_ack_rate(struct ieee80211com *, int);
+static void		rt2560_scan_start(struct ieee80211com *);
+static void		rt2560_scan_end(struct ieee80211com *);
+static void		rt2560_set_channel(struct ieee80211com *);
+static uint16_t		rt2560_txtime(int, int, uint32_t);
+static uint8_t		rt2560_plcp_signal(int);
+static void		rt2560_setup_tx_desc(struct rt2560_softc *,
+			    struct rt2560_tx_desc *, uint32_t, int, int, int,
+			    bus_addr_t);
+static int		rt2560_tx_bcn(struct rt2560_softc *, struct mbuf *,
+			    struct ieee80211_node *);
+static int		rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *,
+			    struct ieee80211_node *);
+static struct		mbuf *rt2560_get_rts(struct rt2560_softc *,
+			    struct ieee80211_frame *, uint16_t);
+static int		rt2560_tx_data(struct rt2560_softc *, struct mbuf *,
+			    struct ieee80211_node *);
+static void		rt2560_start(struct ifnet *);
+static void		rt2560_watchdog(void *);
+static int		rt2560_reset(struct ifnet *);
+static int		rt2560_ioctl(struct ifnet *, u_long, caddr_t);
+static void		rt2560_bbp_write(struct rt2560_softc *, uint8_t,
+			    uint8_t);
+static uint8_t		rt2560_bbp_read(struct rt2560_softc *, uint8_t);
+static void		rt2560_rf_write(struct rt2560_softc *, uint8_t,
+			    uint32_t);
+static void		rt2560_set_chan(struct rt2560_softc *,
+			    struct ieee80211_channel *);
+#if 0
+static void		rt2560_disable_rf_tune(struct rt2560_softc *);
+#endif
+static void		rt2560_enable_tsf_sync(struct rt2560_softc *);
+static void		rt2560_update_plcp(struct rt2560_softc *);
+static void		rt2560_update_slot(struct ifnet *);
+static void		rt2560_set_basicrates(struct rt2560_softc *);
+static void		rt2560_update_led(struct rt2560_softc *, int, int);
+static void		rt2560_set_bssid(struct rt2560_softc *, const uint8_t *);
+static void		rt2560_set_macaddr(struct rt2560_softc *, uint8_t *);
+static void		rt2560_get_macaddr(struct rt2560_softc *, uint8_t *);
+static void		rt2560_update_promisc(struct rt2560_softc *);
+static const char	*rt2560_get_rf(int);
+static void		rt2560_read_eeprom(struct rt2560_softc *);
+static int		rt2560_bbp_init(struct rt2560_softc *);
+static void		rt2560_set_txantenna(struct rt2560_softc *, int);
+static void		rt2560_set_rxantenna(struct rt2560_softc *, int);
+static void		rt2560_init(void *);
+static int		rt2560_raw_xmit(struct ieee80211_node *, struct mbuf *,
+				const struct ieee80211_bpf_params *);
+
+static const struct {
+	uint32_t	reg;
+	uint32_t	val;
+} rt2560_def_mac[] = {
+	RT2560_DEF_MAC
+};
+
+static const struct {
+	uint8_t	reg;
+	uint8_t	val;
+} rt2560_def_bbp[] = {
+	RT2560_DEF_BBP
+};
+
+static const uint32_t rt2560_rf2522_r2[]    = RT2560_RF2522_R2;
+static const uint32_t rt2560_rf2523_r2[]    = RT2560_RF2523_R2;
+static const uint32_t rt2560_rf2524_r2[]    = RT2560_RF2524_R2;
+static const uint32_t rt2560_rf2525_r2[]    = RT2560_RF2525_R2;
+static const uint32_t rt2560_rf2525_hi_r2[] = RT2560_RF2525_HI_R2;
+static const uint32_t rt2560_rf2525e_r2[]   = RT2560_RF2525E_R2;
+static const uint32_t rt2560_rf2526_r2[]    = RT2560_RF2526_R2;
+static const uint32_t rt2560_rf2526_hi_r2[] = RT2560_RF2526_HI_R2;
+
+static const struct {
+	uint8_t		chan;
+	uint32_t	r1, r2, r4;
+} rt2560_rf5222[] = {
+	RT2560_RF5222
+};
+
+int
+rt2560_attach(device_t dev, int id)
+{
+	struct rt2560_softc *sc = device_get_softc(dev);
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp;
+	int error, bands;
+
+	sc->sc_dev = dev;
+
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF | MTX_RECURSE);
+
+	callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+	callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE);
+
+	/* retrieve RT2560 rev. no */
+	sc->asic_rev = RAL_READ(sc, RT2560_CSR0);
+
+	/* retrieve MAC address */
+	rt2560_get_macaddr(sc, ic->ic_myaddr);
+
+	/* retrieve RF rev. no and various other things from EEPROM */
+	rt2560_read_eeprom(sc);
+
+	device_printf(dev, "MAC/BBP RT2560 (rev 0x%02x), RF %s\n",
+	    sc->asic_rev, rt2560_get_rf(sc->rf_rev));
+
+	/*
+	 * Allocate Tx and Rx rings.
+	 */
+	error = rt2560_alloc_tx_ring(sc, &sc->txq, RT2560_TX_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Tx ring\n");
+		goto fail1;
+	}
+
+	error = rt2560_alloc_tx_ring(sc, &sc->atimq, RT2560_ATIM_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate ATIM ring\n");
+		goto fail2;
+	}
+
+	error = rt2560_alloc_tx_ring(sc, &sc->prioq, RT2560_PRIO_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Prio ring\n");
+		goto fail3;
+	}
+
+	error = rt2560_alloc_tx_ring(sc, &sc->bcnq, RT2560_BEACON_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Beacon ring\n");
+		goto fail4;
+	}
+
+	error = rt2560_alloc_rx_ring(sc, &sc->rxq, RT2560_RX_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Rx ring\n");
+		goto fail5;
+	}
+
+	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {
+		device_printf(sc->sc_dev, "can not if_alloc()\n");
+		goto fail6;
+	}
+
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_init = rt2560_init;
+	ifp->if_ioctl = rt2560_ioctl;
+	ifp->if_start = rt2560_start;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
+
+	ic->ic_ifp = ifp;
+	ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+	ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
+	ic->ic_state = IEEE80211_S_INIT;
+
+	/* set device capabilities */
+	ic->ic_caps =
+	    IEEE80211_C_IBSS |		/* IBSS mode supported */
+	    IEEE80211_C_MONITOR |	/* monitor mode supported */
+	    IEEE80211_C_HOSTAP |	/* HostAp mode supported */
+	    IEEE80211_C_TXPMGT |	/* tx power management */
+	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
+	    IEEE80211_C_SHSLOT |	/* short slot time supported */
+	    IEEE80211_C_BGSCAN |	/* bg scanning support */
+	    IEEE80211_C_WPA;		/* 802.11i */
+
+	bands = 0;
+	setbit(&bands, IEEE80211_MODE_11B);
+	setbit(&bands, IEEE80211_MODE_11G);
+	if (sc->rf_rev == RT2560_RF_5222)
+		setbit(&bands, IEEE80211_MODE_11A);
+	ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1);
+
+	ieee80211_ifattach(ic);
+	ic->ic_scan_start = rt2560_scan_start;
+	ic->ic_scan_end = rt2560_scan_end;
+	ic->ic_set_channel = rt2560_set_channel;
+	ic->ic_node_alloc = rt2560_node_alloc;
+	ic->ic_updateslot = rt2560_update_slot;
+	ic->ic_reset = rt2560_reset;
+	/* enable s/w bmiss handling in sta mode */
+	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
+
+	/* override state transition machine */
+	sc->sc_newstate = ic->ic_newstate;
+	ic->ic_newstate = rt2560_newstate;
+	ic->ic_raw_xmit = rt2560_raw_xmit;
+	ic->ic_update_beacon = rt2560_beacon_update;
+	ieee80211_media_init(ic, rt2560_media_change, ieee80211_media_status);
+
+	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
+	    sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), 
+	    &sc->sc_drvbpf);
+
+	sc->sc_rxtap_len = sizeof sc->sc_rxtap;
+	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
+	sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2560_RX_RADIOTAP_PRESENT);
+
+	sc->sc_txtap_len = sizeof sc->sc_txtap;
+	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
+	sc->sc_txtap.wt_ihdr.it_present = htole32(RT2560_TX_RADIOTAP_PRESENT);
+
+	/*
+	 * Add a few sysctl knobs.
+	 */
+	sc->dwelltime = 200;
+
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "txantenna", CTLFLAG_RW, &sc->tx_ant, 0, "tx antenna (0=auto)");
+
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO,
+	    "rxantenna", CTLFLAG_RW, &sc->rx_ant, 0, "rx antenna (0=auto)");
+
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
+	    CTLFLAG_RW, &sc->dwelltime, 0,
+	    "channel dwell time (ms) for AP/station scanning");
+
+	if (bootverbose)
+		ieee80211_announce(ic);
+
+	return 0;
+
+fail6:	rt2560_free_rx_ring(sc, &sc->rxq);
+fail5:	rt2560_free_tx_ring(sc, &sc->bcnq);
+fail4:	rt2560_free_tx_ring(sc, &sc->prioq);
+fail3:	rt2560_free_tx_ring(sc, &sc->atimq);
+fail2:	rt2560_free_tx_ring(sc, &sc->txq);
+fail1:	mtx_destroy(&sc->sc_mtx);
+
+	return ENXIO;
+}
+
+int
+rt2560_detach(void *xsc)
+{
+	struct rt2560_softc *sc = xsc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	
+	rt2560_stop(sc);
+	callout_stop(&sc->watchdog_ch);
+	callout_stop(&sc->rssadapt_ch);
+
+	bpfdetach(ifp);
+	ieee80211_ifdetach(ic);
+
+	rt2560_free_tx_ring(sc, &sc->txq);
+	rt2560_free_tx_ring(sc, &sc->atimq);
+	rt2560_free_tx_ring(sc, &sc->prioq);
+	rt2560_free_tx_ring(sc, &sc->bcnq);
+	rt2560_free_rx_ring(sc, &sc->rxq);
+
+	if_free(ifp);
+
+	mtx_destroy(&sc->sc_mtx);
+
+	return 0;
+}
+
+void
+rt2560_resume(void *xsc)
+{
+	struct rt2560_softc *sc = xsc;
+	struct ifnet *ifp = sc->sc_ic.ic_ifp;
+
+	if (ifp->if_flags & IFF_UP) {
+		ifp->if_init(ifp->if_softc);
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			ifp->if_start(ifp);
+	}
+}
+
+static void
+rt2560_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	if (error != 0)
+		return;
+
+	KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
+
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+rt2560_alloc_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring,
+    int count)
+{
+	int i, error;
+
+	ring->count = count;
+	ring->queued = 0;
+	ring->cur = ring->next = 0;
+	ring->cur_encrypt = ring->next_encrypt = 0;
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    count * RT2560_TX_DESC_SIZE, 1, count * RT2560_TX_DESC_SIZE,
+	    0, NULL, NULL, &ring->desc_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create desc DMA tag\n");
+		goto fail;
+	}
+
+	error = bus_dmamem_alloc(ring->desc_dmat, (void **)&ring->desc,
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_map);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate DMA memory\n");
+		goto fail;
+	}
+
+	error = bus_dmamap_load(ring->desc_dmat, ring->desc_map, ring->desc,
+	    count * RT2560_TX_DESC_SIZE, rt2560_dma_map_addr, &ring->physaddr,
+	    0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not load desc DMA map\n");
+		goto fail;
+	}
+
+	ring->data = malloc(count * sizeof (struct rt2560_tx_data), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (ring->data == NULL) {
+		device_printf(sc->sc_dev, "could not allocate soft data\n");
+		error = ENOMEM;
+		goto fail;
+	}
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    MCLBYTES, RT2560_MAX_SCATTER, MCLBYTES, 0, NULL, NULL,
+	    &ring->data_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create data DMA tag\n");
+		goto fail;
+	}
+
+	for (i = 0; i < count; i++) {
+		error = bus_dmamap_create(ring->data_dmat, 0,
+		    &ring->data[i].map);
+		if (error != 0) {
+			device_printf(sc->sc_dev, "could not create DMA map\n");
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:	rt2560_free_tx_ring(sc, ring);
+	return error;
+}
+
+static void
+rt2560_reset_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring)
+{
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	int i;
+
+	for (i = 0; i < ring->count; i++) {
+		desc = &ring->desc[i];
+		data = &ring->data[i];
+
+		if (data->m != NULL) {
+			bus_dmamap_sync(ring->data_dmat, data->map,
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(ring->data_dmat, data->map);
+			m_freem(data->m);
+			data->m = NULL;
+		}
+
+		if (data->ni != NULL) {
+			ieee80211_free_node(data->ni);
+			data->ni = NULL;
+		}
+
+		desc->flags = 0;
+	}
+
+	bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE);
+
+	ring->queued = 0;
+	ring->cur = ring->next = 0;
+	ring->cur_encrypt = ring->next_encrypt = 0;
+}
+
+static void
+rt2560_free_tx_ring(struct rt2560_softc *sc, struct rt2560_tx_ring *ring)
+{
+	struct rt2560_tx_data *data;
+	int i;
+
+	if (ring->desc != NULL) {
+		bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(ring->desc_dmat, ring->desc_map);
+		bus_dmamem_free(ring->desc_dmat, ring->desc, ring->desc_map);
+	}
+
+	if (ring->desc_dmat != NULL)
+		bus_dma_tag_destroy(ring->desc_dmat);
+
+	if (ring->data != NULL) {
+		for (i = 0; i < ring->count; i++) {
+			data = &ring->data[i];
+
+			if (data->m != NULL) {
+				bus_dmamap_sync(ring->data_dmat, data->map,
+				    BUS_DMASYNC_POSTWRITE);
+				bus_dmamap_unload(ring->data_dmat, data->map);
+				m_freem(data->m);
+			}
+
+			if (data->ni != NULL)
+				ieee80211_free_node(data->ni);
+
+			if (data->map != NULL)
+				bus_dmamap_destroy(ring->data_dmat, data->map);
+		}
+
+		free(ring->data, M_DEVBUF);
+	}
+
+	if (ring->data_dmat != NULL)
+		bus_dma_tag_destroy(ring->data_dmat);
+}
+
+static int
+rt2560_alloc_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring,
+    int count)
+{
+	struct rt2560_rx_desc *desc;
+	struct rt2560_rx_data *data;
+	bus_addr_t physaddr;
+	int i, error;
+
+	ring->count = count;
+	ring->cur = ring->next = 0;
+	ring->cur_decrypt = 0;
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    count * RT2560_RX_DESC_SIZE, 1, count * RT2560_RX_DESC_SIZE,
+	    0, NULL, NULL, &ring->desc_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create desc DMA tag\n");
+		goto fail;
+	}
+
+	error = bus_dmamem_alloc(ring->desc_dmat, (void **)&ring->desc,
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_map);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate DMA memory\n");
+		goto fail;
+	}
+
+	error = bus_dmamap_load(ring->desc_dmat, ring->desc_map, ring->desc,
+	    count * RT2560_RX_DESC_SIZE, rt2560_dma_map_addr, &ring->physaddr,
+	    0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not load desc DMA map\n");
+		goto fail;
+	}
+
+	ring->data = malloc(count * sizeof (struct rt2560_rx_data), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (ring->data == NULL) {
+		device_printf(sc->sc_dev, "could not allocate soft data\n");
+		error = ENOMEM;
+		goto fail;
+	}
+
+	/*
+	 * Pre-allocate Rx buffers and populate Rx ring.
+	 */
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
+	    1, MCLBYTES, 0, NULL, NULL, &ring->data_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create data DMA tag\n");
+		goto fail;
+	}
+
+	for (i = 0; i < count; i++) {
+		desc = &sc->rxq.desc[i];
+		data = &sc->rxq.data[i];
+
+		error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
+		if (error != 0) {
+			device_printf(sc->sc_dev, "could not create DMA map\n");
+			goto fail;
+		}
+
+		data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (data->m == NULL) {
+			device_printf(sc->sc_dev,
+			    "could not allocate rx mbuf\n");
+			error = ENOMEM;
+			goto fail;
+		}
+
+		error = bus_dmamap_load(ring->data_dmat, data->map,
+		    mtod(data->m, void *), MCLBYTES, rt2560_dma_map_addr,
+		    &physaddr, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not load rx buf DMA map");
+			goto fail;
+		}
+
+		desc->flags = htole32(RT2560_RX_BUSY);
+		desc->physaddr = htole32(physaddr);
+	}
+
+	bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE);
+
+	return 0;
+
+fail:	rt2560_free_rx_ring(sc, ring);
+	return error;
+}
+
+static void
+rt2560_reset_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
+{
+	int i;
+
+	for (i = 0; i < ring->count; i++) {
+		ring->desc[i].flags = htole32(RT2560_RX_BUSY);
+		ring->data[i].drop = 0;
+	}
+
+	bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE);
+
+	ring->cur = ring->next = 0;
+	ring->cur_decrypt = 0;
+}
+
+static void
+rt2560_free_rx_ring(struct rt2560_softc *sc, struct rt2560_rx_ring *ring)
+{
+	struct rt2560_rx_data *data;
+	int i;
+
+	if (ring->desc != NULL) {
+		bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(ring->desc_dmat, ring->desc_map);
+		bus_dmamem_free(ring->desc_dmat, ring->desc, ring->desc_map);
+	}
+
+	if (ring->desc_dmat != NULL)
+		bus_dma_tag_destroy(ring->desc_dmat);
+
+	if (ring->data != NULL) {
+		for (i = 0; i < ring->count; i++) {
+			data = &ring->data[i];
+
+			if (data->m != NULL) {
+				bus_dmamap_sync(ring->data_dmat, data->map,
+				    BUS_DMASYNC_POSTREAD);
+				bus_dmamap_unload(ring->data_dmat, data->map);
+				m_freem(data->m);
+			}
+
+			if (data->map != NULL)
+				bus_dmamap_destroy(ring->data_dmat, data->map);
+		}
+
+		free(ring->data, M_DEVBUF);
+	}
+
+	if (ring->data_dmat != NULL)
+		bus_dma_tag_destroy(ring->data_dmat);
+}
+
+static struct ieee80211_node *
+rt2560_node_alloc(struct ieee80211_node_table *nt)
+{
+	struct rt2560_node *rn;
+
+	rn = malloc(sizeof (struct rt2560_node), M_80211_NODE,
+	    M_NOWAIT | M_ZERO);
+
+	return (rn != NULL) ? &rn->ni : NULL;
+}
+
+static int
+rt2560_media_change(struct ifnet *ifp)
+{
+	struct rt2560_softc *sc = ifp->if_softc;
+	int error;
+
+	error = ieee80211_media_change(ifp);
+
+	if (error == ENETRESET) {
+		if ((ifp->if_flags & IFF_UP) &&
+		    (ifp->if_drv_flags & IFF_DRV_RUNNING))
+		        rt2560_init(sc);
+	}
+	return error;
+}
+
+/*
+ * This function is called for each node present in the node station table.
+ */
+static void
+rt2560_iter_func(void *arg, struct ieee80211_node *ni)
+{
+	struct rt2560_node *rn = (struct rt2560_node *)ni;
+
+	ral_rssadapt_updatestats(&rn->rssadapt);
+}
+
+/*
+ * This function is called periodically (every 100ms) in RUN state to update
+ * the rate adaptation statistics.
+ */
+static void
+rt2560_update_rssadapt(void *arg)
+{
+	struct rt2560_softc *sc = arg;
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	RAL_LOCK(sc);
+
+	ieee80211_iterate_nodes(&ic->ic_sta, rt2560_iter_func, arg);
+	callout_reset(&sc->rssadapt_ch, hz / 10, rt2560_update_rssadapt, sc);
+
+	RAL_UNLOCK(sc);
+}
+
+static int
+rt2560_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
+{
+	struct rt2560_softc *sc = ic->ic_ifp->if_softc;
+	enum ieee80211_state ostate;
+	struct ieee80211_node *ni;
+	struct mbuf *m;
+	int error = 0;
+
+	ostate = ic->ic_state;
+
+	switch (nstate) {
+	case IEEE80211_S_INIT:
+		callout_stop(&sc->rssadapt_ch);
+
+		if (ostate == IEEE80211_S_RUN) {
+			/* abort TSF synchronization */
+			RAL_WRITE(sc, RT2560_CSR14, 0);
+
+			/* turn association led off */
+			rt2560_update_led(sc, 0, 0);
+		}
+		break;
+	case IEEE80211_S_RUN:
+		ni = ic->ic_bss;
+
+		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+			rt2560_update_plcp(sc);
+			rt2560_set_basicrates(sc);
+			rt2560_set_bssid(sc, ni->ni_bssid);
+		}
+
+		if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+		    ic->ic_opmode == IEEE80211_M_IBSS) {
+			m = ieee80211_beacon_alloc(ni, &sc->sc_bo);
+			if (m == NULL) {
+				device_printf(sc->sc_dev,
+				    "could not allocate beacon\n");
+				error = ENOBUFS;
+				break;
+			}
+
+			ieee80211_ref_node(ni);
+			error = rt2560_tx_bcn(sc, m, ni);
+			if (error != 0)
+				break;
+		}
+
+		/* turn assocation led on */
+		rt2560_update_led(sc, 1, 0);
+
+		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+			callout_reset(&sc->rssadapt_ch, hz / 10,
+			    rt2560_update_rssadapt, sc);
+
+			rt2560_enable_tsf_sync(sc);
+		}
+		break;
+	case IEEE80211_S_SCAN:
+	case IEEE80211_S_AUTH:
+	case IEEE80211_S_ASSOC:
+	default:
+		break;
+	}
+
+	return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg);
+}
+
+/*
+ * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
+ * 93C66).
+ */
+static uint16_t
+rt2560_eeprom_read(struct rt2560_softc *sc, uint8_t addr)
+{
+	uint32_t tmp;
+	uint16_t val;
+	int n;
+
+	/* clock C once before the first command */
+	RT2560_EEPROM_CTL(sc, 0);
+
+	RT2560_EEPROM_CTL(sc, RT2560_S);
+	RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_C);
+	RT2560_EEPROM_CTL(sc, RT2560_S);
+
+	/* write start bit (1) */
+	RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D);
+	RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D | RT2560_C);
+
+	/* write READ opcode (10) */
+	RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D);
+	RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_D | RT2560_C);
+	RT2560_EEPROM_CTL(sc, RT2560_S);
+	RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_C);
+
+	/* write address (A5-A0 or A7-A0) */
+	n = (RAL_READ(sc, RT2560_CSR21) & RT2560_93C46) ? 5 : 7;
+	for (; n >= 0; n--) {
+		RT2560_EEPROM_CTL(sc, RT2560_S |
+		    (((addr >> n) & 1) << RT2560_SHIFT_D));
+		RT2560_EEPROM_CTL(sc, RT2560_S |
+		    (((addr >> n) & 1) << RT2560_SHIFT_D) | RT2560_C);
+	}
+
+	RT2560_EEPROM_CTL(sc, RT2560_S);
+
+	/* read data Q15-Q0 */
+	val = 0;
+	for (n = 15; n >= 0; n--) {
+		RT2560_EEPROM_CTL(sc, RT2560_S | RT2560_C);
+		tmp = RAL_READ(sc, RT2560_CSR21);
+		val |= ((tmp & RT2560_Q) >> RT2560_SHIFT_Q) << n;
+		RT2560_EEPROM_CTL(sc, RT2560_S);
+	}
+
+	RT2560_EEPROM_CTL(sc, 0);
+
+	/* clear Chip Select and clock C */
+	RT2560_EEPROM_CTL(sc, RT2560_S);
+	RT2560_EEPROM_CTL(sc, 0);
+	RT2560_EEPROM_CTL(sc, RT2560_C);
+
+	return val;
+}
+
+/*
+ * Some frames were processed by the hardware cipher engine and are ready for
+ * transmission.
+ */
+static void
+rt2560_encryption_intr(struct rt2560_softc *sc)
+{
+	struct rt2560_tx_desc *desc;
+	int hw;
+
+	/* retrieve last descriptor index processed by cipher engine */
+	hw = RAL_READ(sc, RT2560_SECCSR1) - sc->txq.physaddr;
+	hw /= RT2560_TX_DESC_SIZE;
+
+	bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
+	    BUS_DMASYNC_POSTREAD);
+
+	for (; sc->txq.next_encrypt != hw;) {
+		desc = &sc->txq.desc[sc->txq.next_encrypt];
+
+		if ((le32toh(desc->flags) & RT2560_TX_BUSY) ||
+		    (le32toh(desc->flags) & RT2560_TX_CIPHER_BUSY))
+			break;
+
+		/* for TKIP, swap eiv field to fix a bug in ASIC */
+		if ((le32toh(desc->flags) & RT2560_TX_CIPHER_MASK) ==
+		    RT2560_TX_CIPHER_TKIP)
+			desc->eiv = bswap32(desc->eiv);
+
+		/* mark the frame ready for transmission */
+		desc->flags |= htole32(RT2560_TX_BUSY | RT2560_TX_VALID);
+
+		DPRINTFN(15, ("encryption done idx=%u\n",
+		    sc->txq.next_encrypt));
+
+		sc->txq.next_encrypt =
+		    (sc->txq.next_encrypt + 1) % RT2560_TX_RING_COUNT;
+	}
+
+	bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	/* kick Tx */
+	RAL_WRITE(sc, RT2560_TXCSR0, RT2560_KICK_TX);
+}
+
+static void
+rt2560_tx_intr(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	struct rt2560_node *rn;
+
+	bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
+	    BUS_DMASYNC_POSTREAD);
+
+	for (;;) {
+		desc = &sc->txq.desc[sc->txq.next];
+		data = &sc->txq.data[sc->txq.next];
+
+		if ((le32toh(desc->flags) & RT2560_TX_BUSY) ||
+		    (le32toh(desc->flags) & RT2560_TX_CIPHER_BUSY) ||
+		    !(le32toh(desc->flags) & RT2560_TX_VALID))
+			break;
+
+		rn = (struct rt2560_node *)data->ni;
+
+		switch (le32toh(desc->flags) & RT2560_TX_RESULT_MASK) {
+		case RT2560_TX_SUCCESS:
+			DPRINTFN(10, ("data frame sent successfully\n"));
+			if (data->id.id_node != NULL) {
+				ral_rssadapt_raise_rate(ic, &rn->rssadapt,
+				    &data->id);
+			}
+			ifp->if_opackets++;
+			break;
+
+		case RT2560_TX_SUCCESS_RETRY:
+			DPRINTFN(9, ("data frame sent after %u retries\n",
+			    (le32toh(desc->flags) >> 5) & 0x7));
+			ifp->if_opackets++;
+			break;
+
+		case RT2560_TX_FAIL_RETRY:
+			DPRINTFN(9, ("sending data frame failed (too much "
+			    "retries)\n"));
+			if (data->id.id_node != NULL) {
+				ral_rssadapt_lower_rate(ic, data->ni,
+				    &rn->rssadapt, &data->id);
+			}
+			ifp->if_oerrors++;
+			break;
+
+		case RT2560_TX_FAIL_INVALID:
+		case RT2560_TX_FAIL_OTHER:
+		default:
+			device_printf(sc->sc_dev, "sending data frame failed "
+			    "0x%08x\n", le32toh(desc->flags));
+			ifp->if_oerrors++;
+		}
+
+		bus_dmamap_sync(sc->txq.data_dmat, data->map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(sc->txq.data_dmat, data->map);
+		m_freem(data->m);
+		data->m = NULL;
+		ieee80211_free_node(data->ni);
+		data->ni = NULL;
+
+		/* descriptor is no longer valid */
+		desc->flags &= ~htole32(RT2560_TX_VALID);
+
+		DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next));
+
+		sc->txq.queued--;
+		sc->txq.next = (sc->txq.next + 1) % RT2560_TX_RING_COUNT;
+	}
+
+	bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	sc->sc_tx_timer = 0;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	rt2560_start(ifp);
+}
+
+static void
+rt2560_prio_intr(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	struct ieee80211_node *ni;
+	struct mbuf *m;
+	int flags;
+
+	bus_dmamap_sync(sc->prioq.desc_dmat, sc->prioq.desc_map,
+	    BUS_DMASYNC_POSTREAD);
+
+	for (;;) {
+		desc = &sc->prioq.desc[sc->prioq.next];
+		data = &sc->prioq.data[sc->prioq.next];
+
+		flags = le32toh(desc->flags);
+		if ((flags & RT2560_TX_BUSY) || (flags & RT2560_TX_VALID) == 0)
+			break;
+
+		switch (flags & RT2560_TX_RESULT_MASK) {
+		case RT2560_TX_SUCCESS:
+			DPRINTFN(10, ("mgt frame sent successfully\n"));
+			break;
+
+		case RT2560_TX_SUCCESS_RETRY:
+			DPRINTFN(9, ("mgt frame sent after %u retries\n",
+			    (flags >> 5) & 0x7));
+			break;
+
+		case RT2560_TX_FAIL_RETRY:
+			DPRINTFN(9, ("sending mgt frame failed (too much "
+			    "retries)\n"));
+			break;
+
+		case RT2560_TX_FAIL_INVALID:
+		case RT2560_TX_FAIL_OTHER:
+		default:
+			device_printf(sc->sc_dev, "sending mgt frame failed "
+			    "0x%08x\n", flags);
+			break;
+		}
+
+		bus_dmamap_sync(sc->prioq.data_dmat, data->map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(sc->prioq.data_dmat, data->map);
+
+		m = data->m;
+		data->m = NULL;
+		ni = data->ni;
+		data->ni = NULL;
+
+		/* descriptor is no longer valid */
+		desc->flags &= ~htole32(RT2560_TX_VALID);
+
+		DPRINTFN(15, ("prio done idx=%u\n", sc->prioq.next));
+
+		sc->prioq.queued--;
+		sc->prioq.next = (sc->prioq.next + 1) % RT2560_PRIO_RING_COUNT;
+
+		if (m->m_flags & M_TXCB)
+			ieee80211_process_callback(ni, m,
+				(flags & RT2560_TX_RESULT_MASK) &~
+				(RT2560_TX_SUCCESS | RT2560_TX_SUCCESS_RETRY));
+		m_freem(m);
+		ieee80211_free_node(ni);
+	}
+
+	bus_dmamap_sync(sc->prioq.desc_dmat, sc->prioq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	sc->sc_tx_timer = 0;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	rt2560_start(ifp);
+}
+
+/*
+ * Some frames were processed by the hardware cipher engine and are ready for
+ * transmission to the IEEE802.11 layer.
+ */
+static void
+rt2560_decryption_intr(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_rx_desc *desc;
+	struct rt2560_rx_data *data;
+	bus_addr_t physaddr;
+	struct ieee80211_frame *wh;
+	struct ieee80211_node *ni;
+	struct rt2560_node *rn;
+	struct mbuf *mnew, *m;
+	int hw, error;
+
+	/* retrieve last decriptor index processed by cipher engine */
+	hw = RAL_READ(sc, RT2560_SECCSR0) - sc->rxq.physaddr;
+	hw /= RT2560_RX_DESC_SIZE;
+
+	bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map,
+	    BUS_DMASYNC_POSTREAD);
+
+	for (; sc->rxq.cur_decrypt != hw;) {
+		desc = &sc->rxq.desc[sc->rxq.cur_decrypt];
+		data = &sc->rxq.data[sc->rxq.cur_decrypt];
+
+		if ((le32toh(desc->flags) & RT2560_RX_BUSY) ||
+		    (le32toh(desc->flags) & RT2560_RX_CIPHER_BUSY))
+			break;
+
+		if (data->drop) {
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		if ((le32toh(desc->flags) & RT2560_RX_CIPHER_MASK) != 0 &&
+		    (le32toh(desc->flags) & RT2560_RX_ICV_ERROR)) {
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		/*
+		 * Try to allocate a new mbuf for this ring element and load it
+		 * before processing the current mbuf. If the ring element
+		 * cannot be loaded, drop the received packet and reuse the old
+		 * mbuf. In the unlikely case that the old mbuf can't be
+		 * reloaded either, explicitly panic.
+		 */
+		mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (mnew == NULL) {
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+		    BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(sc->rxq.data_dmat, data->map);
+
+		error = bus_dmamap_load(sc->rxq.data_dmat, data->map,
+		    mtod(mnew, void *), MCLBYTES, rt2560_dma_map_addr,
+		    &physaddr, 0);
+		if (error != 0) {
+			m_freem(mnew);
+
+			/* try to reload the old mbuf */
+			error = bus_dmamap_load(sc->rxq.data_dmat, data->map,
+			    mtod(data->m, void *), MCLBYTES,
+			    rt2560_dma_map_addr, &physaddr, 0);
+			if (error != 0) {
+				/* very unlikely that it will fail... */
+				panic("%s: could not load old rx mbuf",
+				    device_get_name(sc->sc_dev));
+			}
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		/*
+	 	 * New mbuf successfully loaded, update Rx ring and continue
+		 * processing.
+		 */
+		m = data->m;
+		data->m = mnew;
+		desc->physaddr = htole32(physaddr);
+
+		/* finalize mbuf */
+		m->m_pkthdr.rcvif = ifp;
+		m->m_pkthdr.len = m->m_len =
+		    (le32toh(desc->flags) >> 16) & 0xfff;
+
+		if (bpf_peers_present(sc->sc_drvbpf)) {
+			struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap;
+			uint32_t tsf_lo, tsf_hi;
+
+			/* get timestamp (low and high 32 bits) */
+			tsf_hi = RAL_READ(sc, RT2560_CSR17);
+			tsf_lo = RAL_READ(sc, RT2560_CSR16);
+
+			tap->wr_tsf =
+			    htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
+			tap->wr_flags = 0;
+			tap->wr_rate = rt2560_rxrate(desc);
+			tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+			tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
+			tap->wr_antenna = sc->rx_ant;
+			tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi);
+
+			bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
+		}
+
+		sc->sc_flags |= RAL_INPUT_RUNNING;
+		RAL_UNLOCK(sc);
+		wh = mtod(m, struct ieee80211_frame *);
+		ni = ieee80211_find_rxnode(ic,
+		    (struct ieee80211_frame_min *)wh);
+
+		/* send the frame to the 802.11 layer */
+		ieee80211_input(ic, m, ni, RT2560_RSSI(sc, desc->rssi),
+				RT2560_NOISE_FLOOR, 0);
+
+		/* give rssi to the rate adatation algorithm */
+		rn = (struct rt2560_node *)ni;
+		ral_rssadapt_input(ic, ni, &rn->rssadapt,
+				   RT2560_RSSI(sc, desc->rssi));
+
+		/* node is no longer needed */
+		ieee80211_free_node(ni);
+
+		RAL_LOCK(sc);
+		sc->sc_flags &= ~RAL_INPUT_RUNNING;
+skip:		desc->flags = htole32(RT2560_RX_BUSY);
+
+		DPRINTFN(15, ("decryption done idx=%u\n", sc->rxq.cur_decrypt));
+
+		sc->rxq.cur_decrypt =
+		    (sc->rxq.cur_decrypt + 1) % RT2560_RX_RING_COUNT;
+	}
+
+	bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+}
+
+/*
+ * Some frames were received. Pass them to the hardware cipher engine before
+ * sending them to the 802.11 layer.
+ */
+static void
+rt2560_rx_intr(struct rt2560_softc *sc)
+{
+	struct rt2560_rx_desc *desc;
+	struct rt2560_rx_data *data;
+
+	bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map,
+	    BUS_DMASYNC_POSTREAD);
+
+	for (;;) {
+		desc = &sc->rxq.desc[sc->rxq.cur];
+		data = &sc->rxq.data[sc->rxq.cur];
+
+		if ((le32toh(desc->flags) & RT2560_RX_BUSY) ||
+		    (le32toh(desc->flags) & RT2560_RX_CIPHER_BUSY))
+			break;
+
+		data->drop = 0;
+
+		if ((le32toh(desc->flags) & RT2560_RX_PHY_ERROR) ||
+		    (le32toh(desc->flags) & RT2560_RX_CRC_ERROR)) {
+			/*
+			 * This should not happen since we did not request
+			 * to receive those frames when we filled RXCSR0.
+			 */
+			DPRINTFN(5, ("PHY or CRC error flags 0x%08x\n",
+			    le32toh(desc->flags)));
+			data->drop = 1;
+		}
+
+		if (((le32toh(desc->flags) >> 16) & 0xfff) > MCLBYTES) {
+			DPRINTFN(5, ("bad length\n"));
+			data->drop = 1;
+		}
+
+		/* mark the frame for decryption */
+		desc->flags |= htole32(RT2560_RX_CIPHER_BUSY);
+
+		DPRINTFN(15, ("rx done idx=%u\n", sc->rxq.cur));
+
+		sc->rxq.cur = (sc->rxq.cur + 1) % RT2560_RX_RING_COUNT;
+	}
+
+	bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	/* kick decrypt */
+	RAL_WRITE(sc, RT2560_SECCSR0, RT2560_KICK_DECRYPT);
+}
+
+static void
+rt2560_beacon_update(struct ieee80211com *ic, int item)
+{
+	struct rt2560_softc *sc = ic->ic_ifp->if_softc;
+	struct ieee80211_beacon_offsets *bo = &sc->sc_bo;
+
+	setbit(bo->bo_flags, item);
+}
+
+/*
+ * This function is called periodically in IBSS mode when a new beacon must be
+ * sent out.
+ */
+static void
+rt2560_beacon_expire(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2560_tx_data *data;
+
+	if (ic->ic_opmode != IEEE80211_M_IBSS &&
+	    ic->ic_opmode != IEEE80211_M_HOSTAP)
+		return;	
+
+	data = &sc->bcnq.data[sc->bcnq.next];
+	/*
+	 * Don't send beacon if bsschan isn't set
+	 */
+	if (data->ni == NULL)
+	        return;
+
+	bus_dmamap_sync(sc->bcnq.data_dmat, data->map, BUS_DMASYNC_POSTWRITE);
+	bus_dmamap_unload(sc->bcnq.data_dmat, data->map);
+
+	ieee80211_beacon_update(data->ni, &sc->sc_bo, data->m, 1);
+
+	if (bpf_peers_present(ic->ic_rawbpf))
+		bpf_mtap(ic->ic_rawbpf, data->m);
+
+	rt2560_tx_bcn(sc, data->m, data->ni);
+
+	DPRINTFN(15, ("beacon expired\n"));
+
+	sc->bcnq.next = (sc->bcnq.next + 1) % RT2560_BEACON_RING_COUNT;
+}
+
+/* ARGSUSED */
+static void
+rt2560_wakeup_expire(struct rt2560_softc *sc)
+{
+	DPRINTFN(2, ("wakeup expired\n"));
+}
+
+void
+rt2560_intr(void *arg)
+{
+	struct rt2560_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
+	uint32_t r;
+
+	RAL_LOCK(sc);
+
+	/* disable interrupts */
+	RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
+
+	/* don't re-enable interrupts if we're shutting down */
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	r = RAL_READ(sc, RT2560_CSR7);
+	RAL_WRITE(sc, RT2560_CSR7, r);
+
+	if (r & RT2560_BEACON_EXPIRE)
+		rt2560_beacon_expire(sc);
+
+	if (r & RT2560_WAKEUP_EXPIRE)
+		rt2560_wakeup_expire(sc);
+
+	if (r & RT2560_ENCRYPTION_DONE)
+		rt2560_encryption_intr(sc);
+
+	if (r & RT2560_TX_DONE)
+		rt2560_tx_intr(sc);
+
+	if (r & RT2560_PRIO_DONE)
+		rt2560_prio_intr(sc);
+
+	if (r & RT2560_DECRYPTION_DONE)
+		rt2560_decryption_intr(sc);
+
+	if (r & RT2560_RX_DONE)
+		rt2560_rx_intr(sc);
+
+	/* re-enable interrupts */
+	RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK);
+
+	RAL_UNLOCK(sc);
+}
+
+/* quickly determine if a given rate is CCK or OFDM */
+#define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
+
+#define RAL_ACK_SIZE	14	/* 10 + 4(FCS) */
+#define RAL_CTS_SIZE	14	/* 10 + 4(FCS) */
+
+#define RAL_SIFS		10	/* us */
+
+#define RT2560_TXRX_TURNAROUND	10	/* us */
+
+/*
+ * This function is only used by the Rx radiotap code.
+ */
+static uint8_t
+rt2560_rxrate(struct rt2560_rx_desc *desc)
+{
+	if (le32toh(desc->flags) & RT2560_RX_OFDM) {
+		/* reverse function of rt2560_plcp_signal */
+		switch (desc->rate) {
+		case 0xb:	return 12;
+		case 0xf:	return 18;
+		case 0xa:	return 24;
+		case 0xe:	return 36;
+		case 0x9:	return 48;
+		case 0xd:	return 72;
+		case 0x8:	return 96;
+		case 0xc:	return 108;
+		}
+	} else {
+		if (desc->rate == 10)
+			return 2;
+		if (desc->rate == 20)
+			return 4;
+		if (desc->rate == 55)
+			return 11;
+		if (desc->rate == 110)
+			return 22;
+	}
+	return 2;	/* should not get there */
+}
+
+/*
+ * Return the expected ack rate for a frame transmitted at rate `rate'.
+ * XXX: this should depend on the destination node basic rate set.
+ */
+static int
+rt2560_ack_rate(struct ieee80211com *ic, int rate)
+{
+	switch (rate) {
+	/* CCK rates */
+	case 2:
+		return 2;
+	case 4:
+	case 11:
+	case 22:
+		return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
+
+	/* OFDM rates */
+	case 12:
+	case 18:
+		return 12;
+	case 24:
+	case 36:
+		return 24;
+	case 48:
+	case 72:
+	case 96:
+	case 108:
+		return 48;
+	}
+
+	/* default to 1Mbps */
+	return 2;
+}
+
+/*
+ * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
+ * The function automatically determines the operating mode depending on the
+ * given rate. `flags' indicates whether short preamble is in use or not.
+ */
+static uint16_t
+rt2560_txtime(int len, int rate, uint32_t flags)
+{
+	uint16_t txtime;
+
+	if (RAL_RATE_IS_OFDM(rate)) {
+		/* IEEE Std 802.11a-1999, pp. 37 */
+		txtime = (8 + 4 * len + 3 + rate - 1) / rate;
+		txtime = 16 + 4 + 4 * txtime + 6;
+	} else {
+		/* IEEE Std 802.11b-1999, pp. 28 */
+		txtime = (16 * len + rate - 1) / rate;
+		if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
+			txtime +=  72 + 24;
+		else
+			txtime += 144 + 48;
+	}
+
+	return txtime;
+}
+
+static uint8_t
+rt2560_plcp_signal(int rate)
+{
+	switch (rate) {
+	/* CCK rates (returned values are device-dependent) */
+	case 2:		return 0x0;
+	case 4:		return 0x1;
+	case 11:	return 0x2;
+	case 22:	return 0x3;
+
+	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
+	case 12:	return 0xb;
+	case 18:	return 0xf;
+	case 24:	return 0xa;
+	case 36:	return 0xe;
+	case 48:	return 0x9;
+	case 72:	return 0xd;
+	case 96:	return 0x8;
+	case 108:	return 0xc;
+
+	/* unsupported rates (should not get there) */
+	default:	return 0xff;
+	}
+}
+
+static void
+rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc,
+    uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint16_t plcp_length;
+	int remainder;
+
+	desc->flags = htole32(flags);
+	desc->flags |= htole32(len << 16);
+	desc->flags |= encrypt ? htole32(RT2560_TX_CIPHER_BUSY) :
+	    htole32(RT2560_TX_BUSY | RT2560_TX_VALID);
+
+	desc->physaddr = htole32(physaddr);
+	desc->wme = htole16(
+	    RT2560_AIFSN(2) |
+	    RT2560_LOGCWMIN(3) |
+	    RT2560_LOGCWMAX(8));
+
+	/* setup PLCP fields */
+	desc->plcp_signal  = rt2560_plcp_signal(rate);
+	desc->plcp_service = 4;
+
+	len += IEEE80211_CRC_LEN;
+	if (RAL_RATE_IS_OFDM(rate)) {
+		desc->flags |= htole32(RT2560_TX_OFDM);
+
+		plcp_length = len & 0xfff;
+		desc->plcp_length_hi = plcp_length >> 6;
+		desc->plcp_length_lo = plcp_length & 0x3f;
+	} else {
+		plcp_length = (16 * len + rate - 1) / rate;
+		if (rate == 22) {
+			remainder = (16 * len) % 22;
+			if (remainder != 0 && remainder < 7)
+				desc->plcp_service |= RT2560_PLCP_LENGEXT;
+		}
+		desc->plcp_length_hi = plcp_length >> 8;
+		desc->plcp_length_lo = plcp_length & 0xff;
+
+		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+			desc->plcp_signal |= 0x08;
+	}
+}
+
+static int
+rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	bus_dma_segment_t segs[RT2560_MAX_SCATTER];
+	int nsegs, rate, error;
+
+	desc = &sc->bcnq.desc[sc->bcnq.cur];
+	data = &sc->bcnq.data[sc->bcnq.cur];
+
+	rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2;
+
+	error = bus_dmamap_load_mbuf_sg(sc->bcnq.data_dmat, data->map, m0,
+	    segs, &nsegs, BUS_DMA_NOWAIT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
+		    error);
+		m_freem(m0);
+		return error;
+	}
+
+	if (bpf_peers_present(sc->sc_drvbpf)) {
+		struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+		tap->wt_antenna = sc->tx_ant;
+
+		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+	}
+
+	data->m = m0;
+	data->ni = ni;
+
+	rt2560_setup_tx_desc(sc, desc, RT2560_TX_IFS_NEWBACKOFF |
+	    RT2560_TX_TIMESTAMP, m0->m_pkthdr.len, rate, 0, segs->ds_addr);
+
+	DPRINTFN(10, ("sending beacon frame len=%u idx=%u rate=%u\n",
+	    m0->m_pkthdr.len, sc->bcnq.cur, rate));
+
+	bus_dmamap_sync(sc->bcnq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->bcnq.desc_dmat, sc->bcnq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	sc->bcnq.cur = (sc->bcnq.cur + 1) % RT2560_BEACON_RING_COUNT;
+
+	return 0;
+}
+
+static int
+rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	struct ieee80211_frame *wh;
+	bus_dma_segment_t segs[RT2560_MAX_SCATTER];
+	uint16_t dur;
+	uint32_t flags = 0;
+	int nsegs, rate, error;
+
+	desc = &sc->prioq.desc[sc->prioq.cur];
+	data = &sc->prioq.data[sc->prioq.cur];
+
+	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
+
+	error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0,
+	    segs, &nsegs, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
+		    error);
+		m_freem(m0);
+		return error;
+	}
+
+	if (bpf_peers_present(sc->sc_drvbpf)) {
+		struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+		tap->wt_antenna = sc->tx_ant;
+
+		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+	}
+
+	data->m = m0;
+	data->ni = ni;
+
+	wh = mtod(m0, struct ieee80211_frame *);
+
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		flags |= RT2560_TX_ACK;
+
+		dur = rt2560_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) +
+		      RAL_SIFS;
+		*(uint16_t *)wh->i_dur = htole16(dur);
+
+		/* tell hardware to add timestamp for probe responses */
+		if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) ==
+		    IEEE80211_FC0_TYPE_MGT &&
+		    (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) ==
+		    IEEE80211_FC0_SUBTYPE_PROBE_RESP)
+			flags |= RT2560_TX_TIMESTAMP;
+	}
+
+	rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate, 0,
+	    segs->ds_addr);
+
+	bus_dmamap_sync(sc->prioq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->prioq.desc_dmat, sc->prioq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	DPRINTFN(10, ("sending mgt frame len=%u idx=%u rate=%u\n",
+	    m0->m_pkthdr.len, sc->prioq.cur, rate));
+
+	/* kick prio */
+	sc->prioq.queued++;
+	sc->prioq.cur = (sc->prioq.cur + 1) % RT2560_PRIO_RING_COUNT;
+	RAL_WRITE(sc, RT2560_TXCSR0, RT2560_KICK_PRIO);
+
+	return 0;
+}
+
+static int
+rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni, const struct ieee80211_bpf_params *params)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	bus_dma_segment_t segs[RT2560_MAX_SCATTER];
+	uint32_t flags;
+	int nsegs, rate, error;
+
+	desc = &sc->prioq.desc[sc->prioq.cur];
+	data = &sc->prioq.data[sc->prioq.cur];
+
+	rate = params->ibp_rate0 & IEEE80211_RATE_VAL;
+	/* XXX validate */
+	if (rate == 0) {
+		m_freem(m0);
+		return EINVAL;
+	}
+
+	error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0,
+	    segs, &nsegs, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
+		    error);
+		m_freem(m0);
+		return error;
+	}
+
+	if (bpf_peers_present(sc->sc_drvbpf)) {
+		struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+		tap->wt_antenna = sc->tx_ant;
+
+		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+	}
+
+	data->m = m0;
+	data->ni = ni;
+
+	flags = 0;
+	if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0)
+		flags |= RT2560_TX_ACK;
+
+	/* XXX need to setup descriptor ourself */
+	rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len,
+	    rate, (params->ibp_flags & IEEE80211_BPF_CRYPTO) != 0,
+	    segs->ds_addr);
+
+	bus_dmamap_sync(sc->prioq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->prioq.desc_dmat, sc->prioq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	DPRINTFN(10, ("sending raw frame len=%u idx=%u rate=%u\n",
+	    m0->m_pkthdr.len, sc->prioq.cur, rate));
+
+	/* kick prio */
+	sc->prioq.queued++;
+	sc->prioq.cur = (sc->prioq.cur + 1) % RT2560_PRIO_RING_COUNT;
+	RAL_WRITE(sc, RT2560_TXCSR0, RT2560_KICK_PRIO);
+
+	return 0;
+}
+
+/*
+ * Build a RTS control frame.
+ */
+static struct mbuf *
+rt2560_get_rts(struct rt2560_softc *sc, struct ieee80211_frame *wh,
+    uint16_t dur)
+{
+	struct ieee80211_frame_rts *rts;
+	struct mbuf *m;
+
+	MGETHDR(m, M_DONTWAIT, MT_DATA);
+	if (m == NULL) {
+		sc->sc_ic.ic_stats.is_tx_nobuf++;
+		device_printf(sc->sc_dev, "could not allocate RTS frame\n");
+		return NULL;
+	}
+
+	rts = mtod(m, struct ieee80211_frame_rts *);
+
+	rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
+	    IEEE80211_FC0_SUBTYPE_RTS;
+	rts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
+	*(uint16_t *)rts->i_dur = htole16(dur);
+	IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1);
+	IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2);
+
+	m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts);
+
+	return m;
+}
+
+static int
+rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2560_tx_desc *desc;
+	struct rt2560_tx_data *data;
+	struct rt2560_node *rn;
+	struct ieee80211_frame *wh;
+	struct ieee80211_key *k;
+	struct mbuf *mnew;
+	bus_dma_segment_t segs[RT2560_MAX_SCATTER];
+	uint16_t dur;
+	uint32_t flags = 0;
+	int nsegs, rate, error;
+
+	wh = mtod(m0, struct ieee80211_frame *);
+
+	if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
+		rate = ic->ic_fixed_rate;
+	} else {
+		struct ieee80211_rateset *rs;
+
+		rs = &ni->ni_rates;
+		rn = (struct rt2560_node *)ni;
+		ni->ni_txrate = ral_rssadapt_choose(&rn->rssadapt, rs, wh,
+		    m0->m_pkthdr.len, NULL, 0);
+		rate = rs->rs_rates[ni->ni_txrate];
+	}
+	rate &= IEEE80211_RATE_VAL;
+
+	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+		k = ieee80211_crypto_encap(ic, ni, m0);
+		if (k == NULL) {
+			m_freem(m0);
+			return ENOBUFS;
+		}
+
+		/* packet header may have moved, reset our local pointer */
+		wh = mtod(m0, struct ieee80211_frame *);
+	}
+
+	/*
+	 * IEEE Std 802.11-1999, pp 82: "A STA shall use an RTS/CTS exchange
+	 * for directed frames only when the length of the MPDU is greater
+	 * than the length threshold indicated by [...]" ic_rtsthreshold.
+	 */
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+	    m0->m_pkthdr.len > ic->ic_rtsthreshold) {
+		struct mbuf *m;
+		uint16_t dur;
+		int rtsrate, ackrate;
+
+		rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
+		ackrate = rt2560_ack_rate(ic, rate);
+
+		dur = rt2560_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) +
+		      rt2560_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) +
+		      rt2560_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) +
+		      3 * RAL_SIFS;
+
+		m = rt2560_get_rts(sc, wh, dur);
+
+		desc = &sc->txq.desc[sc->txq.cur_encrypt];
+		data = &sc->txq.data[sc->txq.cur_encrypt];
+
+		error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map,
+		    m, segs, &nsegs, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not map mbuf (error %d)\n", error);
+			m_freem(m);
+			m_freem(m0);
+			return error;
+		}
+
+		/* avoid multiple free() of the same node for each fragment */
+		ieee80211_ref_node(ni);
+
+		data->m = m;
+		data->ni = ni;
+
+		/* RTS frames are not taken into account for rssadapt */
+		data->id.id_node = NULL;
+
+		rt2560_setup_tx_desc(sc, desc, RT2560_TX_ACK |
+		    RT2560_TX_MORE_FRAG, m->m_pkthdr.len, rtsrate, 1,
+		    segs->ds_addr);
+
+		bus_dmamap_sync(sc->txq.data_dmat, data->map,
+		    BUS_DMASYNC_PREWRITE);
+
+		sc->txq.queued++;
+		sc->txq.cur_encrypt =
+		    (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT;
+
+		/*
+		 * IEEE Std 802.11-1999: when an RTS/CTS exchange is used, the
+		 * asynchronous data frame shall be transmitted after the CTS
+		 * frame and a SIFS period.
+		 */
+		flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS;
+	}
+
+	data = &sc->txq.data[sc->txq.cur_encrypt];
+	desc = &sc->txq.desc[sc->txq.cur_encrypt];
+
+	error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, m0,
+	    segs, &nsegs, 0);
+	if (error != 0 && error != EFBIG) {
+		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
+		    error);
+		m_freem(m0);
+		return error;
+	}
+	if (error != 0) {
+		mnew = m_defrag(m0, M_DONTWAIT);
+		if (mnew == NULL) {
+			device_printf(sc->sc_dev,
+			    "could not defragment mbuf\n");
+			m_freem(m0);
+			return ENOBUFS;
+		}
+		m0 = mnew;
+
+		error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map,
+		    m0, segs, &nsegs, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not map mbuf (error %d)\n", error);
+			m_freem(m0);
+			return error;
+		}
+
+		/* packet header may have moved, reset our local pointer */
+		wh = mtod(m0, struct ieee80211_frame *);
+	}
+
+	if (bpf_peers_present(sc->sc_drvbpf)) {
+		struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+		tap->wt_antenna = sc->tx_ant;
+
+		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+	}
+
+	data->m = m0;
+	data->ni = ni;
+
+	/* remember link conditions for rate adaptation algorithm */
+	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
+		data->id.id_len = m0->m_pkthdr.len;
+		data->id.id_rateidx = ni->ni_txrate;
+		data->id.id_node = ni;
+		data->id.id_rssi = ni->ni_rssi;
+	} else
+		data->id.id_node = NULL;
+
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		flags |= RT2560_TX_ACK;
+
+		dur = rt2560_txtime(RAL_ACK_SIZE, rt2560_ack_rate(ic, rate),
+		    ic->ic_flags) + RAL_SIFS;
+		*(uint16_t *)wh->i_dur = htole16(dur);
+	}
+
+	rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate, 1,
+	    segs->ds_addr);
+
+	bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	DPRINTFN(10, ("sending data frame len=%u idx=%u rate=%u\n",
+	    m0->m_pkthdr.len, sc->txq.cur_encrypt, rate));
+
+	/* kick encrypt */
+	sc->txq.queued++;
+	sc->txq.cur_encrypt = (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT;
+	RAL_WRITE(sc, RT2560_SECCSR1, RT2560_KICK_ENCRYPT);
+
+	return 0;
+}
+
+static void
+rt2560_start(struct ifnet *ifp)
+{
+	struct rt2560_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct mbuf *m0;
+	struct ether_header *eh;
+	struct ieee80211_node *ni;
+
+	RAL_LOCK(sc);
+
+	/* prevent management frames from being sent if we're not ready */
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	for (;;) {
+		IF_POLL(&ic->ic_mgtq, m0);
+		if (m0 != NULL) {
+			if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
+				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+				break;
+			}
+			IF_DEQUEUE(&ic->ic_mgtq, m0);
+
+			ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
+			m0->m_pkthdr.rcvif = NULL;
+
+			if (bpf_peers_present(ic->ic_rawbpf))
+				bpf_mtap(ic->ic_rawbpf, m0);
+
+			if (rt2560_tx_mgt(sc, m0, ni) != 0) {
+				ieee80211_free_node(ni);
+				break;
+			}
+		} else {
+			if (ic->ic_state != IEEE80211_S_RUN)
+				break;
+			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
+			if (m0 == NULL)
+				break;
+			if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) {
+				IFQ_DRV_PREPEND(&ifp->if_snd, m0);
+				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+				break;
+			}
+			/*
+			 * Cancel any background scan.
+			 */
+			if (ic->ic_flags & IEEE80211_F_SCAN)
+				ieee80211_cancel_scan(ic);
+
+			if (m0->m_len < sizeof (struct ether_header) &&
+			    !(m0 = m_pullup(m0, sizeof (struct ether_header))))
+				continue;
+
+			eh = mtod(m0, struct ether_header *);
+			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
+			if (ni == NULL) {
+				m_freem(m0);
+				continue;
+			}
+			if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) &&
+			    (m0->m_flags & M_PWR_SAV) == 0) {
+				/*
+				 * Station in power save mode; pass the frame
+				 * to the 802.11 layer and continue.  We'll get
+				 * the frame back when the time is right.
+				 */
+				ieee80211_pwrsave(ni, m0);
+				/*
+				 * If we're in power save mode 'cuz of a bg
+				 * scan cancel it so the traffic can flow.
+				 * The packet we just queued will automatically
+				 * get sent when we drop out of power save.
+				 * XXX locking
+				 */
+				if (ic->ic_flags & IEEE80211_F_SCAN)
+					ieee80211_cancel_scan(ic);
+				ieee80211_free_node(ni);
+				continue;
+
+			}
+
+			BPF_MTAP(ifp, m0);
+
+			m0 = ieee80211_encap(ic, m0, ni);
+			if (m0 == NULL) {
+				ieee80211_free_node(ni);
+				continue;
+			}
+			
+			if (bpf_peers_present(ic->ic_rawbpf))
+				bpf_mtap(ic->ic_rawbpf, m0);
+
+			if (rt2560_tx_data(sc, m0, ni) != 0) {
+				ieee80211_free_node(ni);
+				ifp->if_oerrors++;
+				break;
+			}
+		}
+
+		sc->sc_tx_timer = 5;
+		ic->ic_lastdata = ticks;
+		callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
+	}
+
+	RAL_UNLOCK(sc);
+}
+
+static void
+rt2560_watchdog(void *arg)
+{
+	struct rt2560_softc *sc = arg;
+
+	if (sc->sc_tx_timer > 0) {
+		if (--sc->sc_tx_timer == 0) {
+			device_printf(sc->sc_dev, "device timeout\n");
+			rt2560_init(sc);
+			sc->sc_ifp->if_oerrors++;
+			return;
+		}
+		callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
+	}
+}
+
+/*
+ * This function allows for fast channel switching in monitor mode (used by
+ * net-mgmt/kismet). In IBSS mode, we must explicitly reset the interface to
+ * generate a new beacon frame.
+ */
+static int
+rt2560_reset(struct ifnet *ifp)
+{
+	struct rt2560_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	if (ic->ic_opmode != IEEE80211_M_MONITOR)
+		return ENETRESET;
+
+	rt2560_set_chan(sc, ic->ic_curchan);
+
+	return 0;
+}
+
+static int
+rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct rt2560_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	int error = 0;
+
+
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		if (ifp->if_flags & IFF_UP) {
+			RAL_LOCK(sc);
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+				rt2560_update_promisc(sc);
+			else
+				rt2560_init(sc);
+			RAL_UNLOCK(sc);
+		} else {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+				rt2560_stop(sc);
+		}
+
+		break;
+
+	default:
+		error = ieee80211_ioctl(ic, cmd, data);
+	}
+
+	if (error == ENETRESET) {
+		if ((ifp->if_flags & IFF_UP) &&
+		    (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+		    (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
+			rt2560_init(sc);
+		error = 0;
+	}
+
+
+	return error;
+}
+
+static void
+rt2560_bbp_write(struct rt2560_softc *sc, uint8_t reg, uint8_t val)
+{
+	uint32_t tmp;
+	int ntries;
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (!(RAL_READ(sc, RT2560_BBPCSR) & RT2560_BBP_BUSY))
+			break;
+		DELAY(1);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "could not write to BBP\n");
+		return;
+	}
+
+	tmp = RT2560_BBP_WRITE | RT2560_BBP_BUSY | reg << 8 | val;
+	RAL_WRITE(sc, RT2560_BBPCSR, tmp);
+
+	DPRINTFN(15, ("BBP R%u <- 0x%02x\n", reg, val));
+}
+
+static uint8_t
+rt2560_bbp_read(struct rt2560_softc *sc, uint8_t reg)
+{
+	uint32_t val;
+	int ntries;
+
+	val = RT2560_BBP_BUSY | reg << 8;
+	RAL_WRITE(sc, RT2560_BBPCSR, val);
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		val = RAL_READ(sc, RT2560_BBPCSR);
+		if (!(val & RT2560_BBP_BUSY))
+			return val & 0xff;
+		DELAY(1);
+	}
+
+	device_printf(sc->sc_dev, "could not read from BBP\n");
+	return 0;
+}
+
+static void
+rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val)
+{
+	uint32_t tmp;
+	int ntries;
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (!(RAL_READ(sc, RT2560_RFCSR) & RT2560_RF_BUSY))
+			break;
+		DELAY(1);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "could not write to RF\n");
+		return;
+	}
+
+	tmp = RT2560_RF_BUSY | RT2560_RF_20BIT | (val & 0xfffff) << 2 |
+	    (reg & 0x3);
+	RAL_WRITE(sc, RT2560_RFCSR, tmp);
+
+	/* remember last written value in sc */
+	sc->rf_regs[reg] = val;
+
+	DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff));
+}
+
+static void
+rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint8_t power, tmp;
+	u_int i, chan;
+
+	chan = ieee80211_chan2ieee(ic, c);
+	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
+		return;
+
+	if (IEEE80211_IS_CHAN_2GHZ(c))
+		power = min(sc->txpow[chan - 1], 31);
+	else
+		power = 31;
+
+	/* adjust txpower using ifconfig settings */
+	power -= (100 - ic->ic_txpowlimit) / 8;
+
+	DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power));
+
+	switch (sc->rf_rev) {
+	case RT2560_RF_2522:
+		rt2560_rf_write(sc, RAL_RF1, 0x00814);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2522_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
+		break;
+
+	case RT2560_RF_2523:
+		rt2560_rf_write(sc, RAL_RF1, 0x08804);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2523_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x38044);
+		rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
+		break;
+
+	case RT2560_RF_2524:
+		rt2560_rf_write(sc, RAL_RF1, 0x0c808);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2524_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
+		rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
+		break;
+
+	case RT2560_RF_2525:
+		rt2560_rf_write(sc, RAL_RF1, 0x08808);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2525_hi_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
+		rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
+
+		rt2560_rf_write(sc, RAL_RF1, 0x08808);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2525_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
+		rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00280 : 0x00286);
+		break;
+
+	case RT2560_RF_2525E:
+		rt2560_rf_write(sc, RAL_RF1, 0x08808);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2525e_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
+		rt2560_rf_write(sc, RAL_RF4, (chan == 14) ? 0x00286 : 0x00282);
+		break;
+
+	case RT2560_RF_2526:
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2526_hi_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
+		rt2560_rf_write(sc, RAL_RF1, 0x08804);
+
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf2526_r2[chan - 1]);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x18044);
+		rt2560_rf_write(sc, RAL_RF4, (chan & 1) ? 0x00386 : 0x00381);
+		break;
+
+	/* dual-band RF */
+	case RT2560_RF_5222:
+		for (i = 0; rt2560_rf5222[i].chan != chan; i++);
+
+		rt2560_rf_write(sc, RAL_RF1, rt2560_rf5222[i].r1);
+		rt2560_rf_write(sc, RAL_RF2, rt2560_rf5222[i].r2);
+		rt2560_rf_write(sc, RAL_RF3, power << 7 | 0x00040);
+		rt2560_rf_write(sc, RAL_RF4, rt2560_rf5222[i].r4);
+		break;
+	default: 
+ 	        printf("unknown ral rev=%d\n", sc->rf_rev);
+	}
+
+	if (ic->ic_state != IEEE80211_S_SCAN) {
+		/* set Japan filter bit for channel 14 */
+		tmp = rt2560_bbp_read(sc, 70);
+
+		tmp &= ~RT2560_JAPAN_FILTER;
+		if (chan == 14)
+			tmp |= RT2560_JAPAN_FILTER;
+
+		rt2560_bbp_write(sc, 70, tmp);
+
+		/* clear CRC errors */
+		RAL_READ(sc, RT2560_CNT0);
+	}
+}
+
+static void
+rt2560_set_channel(struct ieee80211com *ic)
+{
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_softc *sc = ifp->if_softc;
+
+	RAL_LOCK(sc);
+	rt2560_set_chan(sc, ic->ic_curchan);
+	RAL_UNLOCK(sc);
+
+}
+
+#if 0
+/*
+ * Disable RF auto-tuning.
+ */
+static void
+rt2560_disable_rf_tune(struct rt2560_softc *sc)
+{
+	uint32_t tmp;
+
+	if (sc->rf_rev != RT2560_RF_2523) {
+		tmp = sc->rf_regs[RAL_RF1] & ~RAL_RF1_AUTOTUNE;
+		rt2560_rf_write(sc, RAL_RF1, tmp);
+	}
+
+	tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE;
+	rt2560_rf_write(sc, RAL_RF3, tmp);
+
+	DPRINTFN(2, ("disabling RF autotune\n"));
+}
+#endif
+
+/*
+ * Refer to IEEE Std 802.11-1999 pp. 123 for more information on TSF
+ * synchronization.
+ */
+static void
+rt2560_enable_tsf_sync(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint16_t logcwmin, preload;
+	uint32_t tmp;
+
+	/* first, disable TSF synchronization */
+	RAL_WRITE(sc, RT2560_CSR14, 0);
+
+	tmp = 16 * ic->ic_bss->ni_intval;
+	RAL_WRITE(sc, RT2560_CSR12, tmp);
+
+	RAL_WRITE(sc, RT2560_CSR13, 0);
+
+	logcwmin = 5;
+	preload = (ic->ic_opmode == IEEE80211_M_STA) ? 384 : 1024;
+	tmp = logcwmin << 16 | preload;
+	RAL_WRITE(sc, RT2560_BCNOCSR, tmp);
+
+	/* finally, enable TSF synchronization */
+	tmp = RT2560_ENABLE_TSF | RT2560_ENABLE_TBCN;
+	if (ic->ic_opmode == IEEE80211_M_STA)
+		tmp |= RT2560_ENABLE_TSF_SYNC(1);
+	else
+		tmp |= RT2560_ENABLE_TSF_SYNC(2) |
+		       RT2560_ENABLE_BEACON_GENERATOR;
+	RAL_WRITE(sc, RT2560_CSR14, tmp);
+
+	DPRINTF(("enabling TSF synchronization\n"));
+}
+
+static void
+rt2560_update_plcp(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	/* no short preamble for 1Mbps */
+	RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400);
+
+	if (!(ic->ic_flags & IEEE80211_F_SHPREAMBLE)) {
+		/* values taken from the reference driver */
+		RAL_WRITE(sc, RT2560_PLCP2MCSR,   0x00380401);
+		RAL_WRITE(sc, RT2560_PLCP5p5MCSR, 0x00150402);
+		RAL_WRITE(sc, RT2560_PLCP11MCSR,  0x000b8403);
+	} else {
+		/* same values as above or'ed 0x8 */
+		RAL_WRITE(sc, RT2560_PLCP2MCSR,   0x00380409);
+		RAL_WRITE(sc, RT2560_PLCP5p5MCSR, 0x0015040a);
+		RAL_WRITE(sc, RT2560_PLCP11MCSR,  0x000b840b);
+	}
+
+	DPRINTF(("updating PLCP for %s preamble\n",
+	    (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long"));
+}
+
+/*
+ * This function can be called by ieee80211_set_shortslottime(). Refer to
+ * IEEE Std 802.11-1999 pp. 85 to know how these values are computed.
+ */
+static void
+rt2560_update_slot(struct ifnet *ifp)
+{
+	struct rt2560_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint8_t slottime;
+	uint16_t tx_sifs, tx_pifs, tx_difs, eifs;
+	uint32_t tmp;
+
+	slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+
+	/* update the MAC slot boundaries */
+	tx_sifs = RAL_SIFS - RT2560_TXRX_TURNAROUND;
+	tx_pifs = tx_sifs + slottime;
+	tx_difs = tx_sifs + 2 * slottime;
+	eifs = (ic->ic_curmode == IEEE80211_MODE_11B) ? 364 : 60;
+
+	tmp = RAL_READ(sc, RT2560_CSR11);
+	tmp = (tmp & ~0x1f00) | slottime << 8;
+	RAL_WRITE(sc, RT2560_CSR11, tmp);
+
+	tmp = tx_pifs << 16 | tx_sifs;
+	RAL_WRITE(sc, RT2560_CSR18, tmp);
+
+	tmp = eifs << 16 | tx_difs;
+	RAL_WRITE(sc, RT2560_CSR19, tmp);
+
+	DPRINTF(("setting slottime to %uus\n", slottime));
+}
+
+static void
+rt2560_set_basicrates(struct rt2560_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	/* update basic rate set */
+	if (ic->ic_curmode == IEEE80211_MODE_11B) {
+		/* 11b basic rates: 1, 2Mbps */
+		RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x3);
+	} else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) {
+		/* 11a basic rates: 6, 12, 24Mbps */
+		RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x150);
+	} else {
+		/* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */
+		RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x15f);
+	}
+}
+
+static void
+rt2560_update_led(struct rt2560_softc *sc, int led1, int led2)
+{
+	uint32_t tmp;
+
+	/* set ON period to 70ms and OFF period to 30ms */
+	tmp = led1 << 16 | led2 << 17 | 70 << 8 | 30;
+	RAL_WRITE(sc, RT2560_LEDCSR, tmp);
+}
+
+static void
+rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid)
+{
+	uint32_t tmp;
+
+	tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
+	RAL_WRITE(sc, RT2560_CSR5, tmp);
+
+	tmp = bssid[4] | bssid[5] << 8;
+	RAL_WRITE(sc, RT2560_CSR6, tmp);
+
+	DPRINTF(("setting BSSID to %6D\n", bssid, ":"));
+}
+
+static void
+rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr)
+{
+	uint32_t tmp;
+
+	tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
+	RAL_WRITE(sc, RT2560_CSR3, tmp);
+
+	tmp = addr[4] | addr[5] << 8;
+	RAL_WRITE(sc, RT2560_CSR4, tmp);
+
+	DPRINTF(("setting MAC address to %6D\n", addr, ":"));
+}
+
+static void
+rt2560_get_macaddr(struct rt2560_softc *sc, uint8_t *addr)
+{
+	uint32_t tmp;
+
+	tmp = RAL_READ(sc, RT2560_CSR3);
+	addr[0] = tmp & 0xff;
+	addr[1] = (tmp >>  8) & 0xff;
+	addr[2] = (tmp >> 16) & 0xff;
+	addr[3] = (tmp >> 24);
+
+	tmp = RAL_READ(sc, RT2560_CSR4);
+	addr[4] = tmp & 0xff;
+	addr[5] = (tmp >> 8) & 0xff;
+}
+
+static void
+rt2560_update_promisc(struct rt2560_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ic.ic_ifp;
+	uint32_t tmp;
+
+	tmp = RAL_READ(sc, RT2560_RXCSR0);
+
+	tmp &= ~RT2560_DROP_NOT_TO_ME;
+	if (!(ifp->if_flags & IFF_PROMISC))
+		tmp |= RT2560_DROP_NOT_TO_ME;
+
+	RAL_WRITE(sc, RT2560_RXCSR0, tmp);
+
+	DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+	    "entering" : "leaving"));
+}
+
+static const char *
+rt2560_get_rf(int rev)
+{
+	switch (rev) {
+	case RT2560_RF_2522:	return "RT2522";
+	case RT2560_RF_2523:	return "RT2523";
+	case RT2560_RF_2524:	return "RT2524";
+	case RT2560_RF_2525:	return "RT2525";
+	case RT2560_RF_2525E:	return "RT2525e";
+	case RT2560_RF_2526:	return "RT2526";
+	case RT2560_RF_5222:	return "RT5222";
+	default:		return "unknown";
+	}
+}
+
+static void
+rt2560_read_eeprom(struct rt2560_softc *sc)
+{
+	uint16_t val;
+	int i;
+
+	val = rt2560_eeprom_read(sc, RT2560_EEPROM_CONFIG0);
+	sc->rf_rev =   (val >> 11) & 0x7;
+	sc->hw_radio = (val >> 10) & 0x1;
+	sc->led_mode = (val >> 6)  & 0x7;
+	sc->rx_ant =   (val >> 4)  & 0x3;
+	sc->tx_ant =   (val >> 2)  & 0x3;
+	sc->nb_ant =   val & 0x3;
+
+	/* read default values for BBP registers */
+	for (i = 0; i < 16; i++) {
+		val = rt2560_eeprom_read(sc, RT2560_EEPROM_BBP_BASE + i);
+		sc->bbp_prom[i].reg = val >> 8;
+		sc->bbp_prom[i].val = val & 0xff;
+	}
+
+	/* read Tx power for all b/g channels */
+	for (i = 0; i < 14 / 2; i++) {
+		val = rt2560_eeprom_read(sc, RT2560_EEPROM_TXPOWER + i);
+		sc->txpow[i * 2] = val >> 8;
+		sc->txpow[i * 2 + 1] = val & 0xff;
+	}
+
+	val = rt2560_eeprom_read(sc, RT2560_EEPROM_CALIBRATE);
+	if ((val & 0xff) == 0xff)
+		sc->rssi_corr = RT2560_DEFAULT_RSSI_CORR;
+	else
+		sc->rssi_corr = val & 0xff;
+	DPRINTF(("rssi correction %d, calibrate 0x%02x\n",
+		 sc->rssi_corr, val));
+}
+
+
+static void
+rt2560_scan_start(struct ieee80211com *ic)
+{
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_softc *sc = ifp->if_softc;
+
+	/* abort TSF synchronization */
+	RAL_WRITE(sc, RT2560_CSR14, 0);
+	rt2560_set_bssid(sc, ifp->if_broadcastaddr);
+}
+
+static void
+rt2560_scan_end(struct ieee80211com *ic)
+{
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_softc *sc = ifp->if_softc;
+
+	rt2560_enable_tsf_sync(sc);
+	/* XXX keep local copy */
+	rt2560_set_bssid(sc, ic->ic_bss->ni_bssid);
+}
+
+static int
+rt2560_bbp_init(struct rt2560_softc *sc)
+{
+#define N(a)	(sizeof (a) / sizeof ((a)[0]))
+	int i, ntries;
+
+	/* wait for BBP to be ready */
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (rt2560_bbp_read(sc, RT2560_BBP_VERSION) != 0)
+			break;
+		DELAY(1);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "timeout waiting for BBP\n");
+		return EIO;
+	}
+
+	/* initialize BBP registers to default values */
+	for (i = 0; i < N(rt2560_def_bbp); i++) {
+		rt2560_bbp_write(sc, rt2560_def_bbp[i].reg,
+		    rt2560_def_bbp[i].val);
+	}
+#if 0
+	/* initialize BBP registers to values stored in EEPROM */
+	for (i = 0; i < 16; i++) {
+		if (sc->bbp_prom[i].reg == 0xff)
+			continue;
+		rt2560_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
+	}
+#endif
+
+	return 0;
+#undef N
+}
+
+static void
+rt2560_set_txantenna(struct rt2560_softc *sc, int antenna)
+{
+	uint32_t tmp;
+	uint8_t tx;
+
+	tx = rt2560_bbp_read(sc, RT2560_BBP_TX) & ~RT2560_BBP_ANTMASK;
+	if (antenna == 1)
+		tx |= RT2560_BBP_ANTA;
+	else if (antenna == 2)
+		tx |= RT2560_BBP_ANTB;
+	else
+		tx |= RT2560_BBP_DIVERSITY;
+
+	/* need to force I/Q flip for RF 2525e, 2526 and 5222 */
+	if (sc->rf_rev == RT2560_RF_2525E || sc->rf_rev == RT2560_RF_2526 ||
+	    sc->rf_rev == RT2560_RF_5222)
+		tx |= RT2560_BBP_FLIPIQ;
+
+	rt2560_bbp_write(sc, RT2560_BBP_TX, tx);
+
+	/* update values for CCK and OFDM in BBPCSR1 */
+	tmp = RAL_READ(sc, RT2560_BBPCSR1) & ~0x00070007;
+	tmp |= (tx & 0x7) << 16 | (tx & 0x7);
+	RAL_WRITE(sc, RT2560_BBPCSR1, tmp);
+}
+
+static void
+rt2560_set_rxantenna(struct rt2560_softc *sc, int antenna)
+{
+	uint8_t rx;
+
+	rx = rt2560_bbp_read(sc, RT2560_BBP_RX) & ~RT2560_BBP_ANTMASK;
+	if (antenna == 1)
+		rx |= RT2560_BBP_ANTA;
+	else if (antenna == 2)
+		rx |= RT2560_BBP_ANTB;
+	else
+		rx |= RT2560_BBP_DIVERSITY;
+
+	/* need to force no I/Q flip for RF 2525e and 2526 */
+	if (sc->rf_rev == RT2560_RF_2525E || sc->rf_rev == RT2560_RF_2526)
+		rx &= ~RT2560_BBP_FLIPIQ;
+
+	rt2560_bbp_write(sc, RT2560_BBP_RX, rx);
+}
+
+static void
+rt2560_init(void *priv)
+{
+#define N(a)	(sizeof (a) / sizeof ((a)[0]))
+	struct rt2560_softc *sc = priv;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	uint32_t tmp;
+	int i;
+
+
+
+	rt2560_stop(sc);
+
+	RAL_LOCK(sc);
+	/* setup tx rings */
+	tmp = RT2560_PRIO_RING_COUNT << 24 |
+	      RT2560_ATIM_RING_COUNT << 16 |
+	      RT2560_TX_RING_COUNT   <<  8 |
+	      RT2560_TX_DESC_SIZE;
+
+	/* rings must be initialized in this exact order */
+	RAL_WRITE(sc, RT2560_TXCSR2, tmp);
+	RAL_WRITE(sc, RT2560_TXCSR3, sc->txq.physaddr);
+	RAL_WRITE(sc, RT2560_TXCSR5, sc->prioq.physaddr);
+	RAL_WRITE(sc, RT2560_TXCSR4, sc->atimq.physaddr);
+	RAL_WRITE(sc, RT2560_TXCSR6, sc->bcnq.physaddr);
+
+	/* setup rx ring */
+	tmp = RT2560_RX_RING_COUNT << 8 | RT2560_RX_DESC_SIZE;
+
+	RAL_WRITE(sc, RT2560_RXCSR1, tmp);
+	RAL_WRITE(sc, RT2560_RXCSR2, sc->rxq.physaddr);
+
+	/* initialize MAC registers to default values */
+	for (i = 0; i < N(rt2560_def_mac); i++)
+		RAL_WRITE(sc, rt2560_def_mac[i].reg, rt2560_def_mac[i].val);
+
+	IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
+	rt2560_set_macaddr(sc, ic->ic_myaddr);
+
+	/* set basic rate set (will be updated later) */
+	RAL_WRITE(sc, RT2560_ARSP_PLCP_1, 0x153);
+
+	rt2560_set_txantenna(sc, sc->tx_ant);
+	rt2560_set_rxantenna(sc, sc->rx_ant);
+	rt2560_update_slot(ifp);
+	rt2560_update_plcp(sc);
+	rt2560_update_led(sc, 0, 0);
+
+	RAL_WRITE(sc, RT2560_CSR1, RT2560_RESET_ASIC);
+	RAL_WRITE(sc, RT2560_CSR1, RT2560_HOST_READY);
+
+	if (rt2560_bbp_init(sc) != 0) {
+		rt2560_stop(sc);
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	/* set default BSS channel */
+	rt2560_set_chan(sc, ic->ic_curchan);
+
+	/* kick Rx */
+	tmp = RT2560_DROP_PHY_ERROR | RT2560_DROP_CRC_ERROR;
+	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+		tmp |= RT2560_DROP_CTL | RT2560_DROP_VERSION_ERROR;
+		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
+			tmp |= RT2560_DROP_TODS;
+		if (!(ifp->if_flags & IFF_PROMISC))
+			tmp |= RT2560_DROP_NOT_TO_ME;
+	}
+	RAL_WRITE(sc, RT2560_RXCSR0, tmp);
+
+	/* clear old FCS and Rx FIFO errors */
+	RAL_READ(sc, RT2560_CNT0);
+	RAL_READ(sc, RT2560_CNT4);
+
+	/* clear any pending interrupts */
+	RAL_WRITE(sc, RT2560_CSR7, 0xffffffff);
+
+	/* enable interrupts */
+	RAL_WRITE(sc, RT2560_CSR8, RT2560_INTR_MASK);
+
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
+	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+		if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+	} else
+		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+
+	RAL_UNLOCK(sc);
+#undef N
+}
+
+void
+rt2560_stop(void *arg)
+{
+	struct rt2560_softc *sc = arg;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	volatile int *flags = &sc->sc_flags;
+
+	while (*flags & RAL_INPUT_RUNNING) {
+		tsleep(sc, 0, "ralrunning", hz/10);
+	}
+
+	RAL_LOCK(sc);
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+		sc->sc_tx_timer = 0;
+		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+
+		/* abort Tx */
+		RAL_WRITE(sc, RT2560_TXCSR0, RT2560_ABORT_TX);
+		
+		/* disable Rx */
+		RAL_WRITE(sc, RT2560_RXCSR0, RT2560_DISABLE_RX);
+
+		/* reset ASIC (imply reset BBP) */
+		RAL_WRITE(sc, RT2560_CSR1, RT2560_RESET_ASIC);
+		RAL_WRITE(sc, RT2560_CSR1, 0);
+
+		/* disable interrupts */
+		RAL_WRITE(sc, RT2560_CSR8, 0xffffffff);
+		
+		/* reset Tx and Rx rings */
+		rt2560_reset_tx_ring(sc, &sc->txq);
+		rt2560_reset_tx_ring(sc, &sc->atimq);
+		rt2560_reset_tx_ring(sc, &sc->prioq);
+		rt2560_reset_tx_ring(sc, &sc->bcnq);
+		rt2560_reset_rx_ring(sc, &sc->rxq);
+	}
+	RAL_UNLOCK(sc);
+}
+
+static int
+rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m,
+	const struct ieee80211_bpf_params *params)
+{
+	struct ieee80211com *ic = ni->ni_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2560_softc *sc = ifp->if_softc;
+
+	RAL_LOCK(sc);
+
+	/* prevent management frames from being sent if we're not ready */
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		RAL_UNLOCK(sc);
+		m_freem(m);
+		ieee80211_free_node(ni);
+		return ENETDOWN;
+	}
+	if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) {
+		ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+		RAL_UNLOCK(sc);
+		m_freem(m);
+		ieee80211_free_node(ni);
+		return ENOBUFS;		/* XXX */
+	}
+
+	if (bpf_peers_present(ic->ic_rawbpf))
+		bpf_mtap(ic->ic_rawbpf, m);
+
+	ifp->if_opackets++;
+
+	if (params == NULL) {
+		/*
+		 * Legacy path; interpret frame contents to decide
+		 * precisely how to send the frame.
+		 */
+		if (rt2560_tx_mgt(sc, m, ni) != 0)
+			goto bad;
+	} else {
+		/*
+		 * Caller supplied explicit parameters to use in
+		 * sending the frame.
+		 */
+		if (rt2560_tx_raw(sc, m, ni, params))
+			goto bad;
+	}
+	sc->sc_tx_timer = 5;
+	callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc);
+
+	RAL_UNLOCK(sc);
+
+	return 0;
+bad:
+	ifp->if_oerrors++;
+	ieee80211_free_node(ni);
+	RAL_UNLOCK(sc);
+	return EIO;		/* XXX */
+}
+
--- /dev/null
+++ sys/dev/ral/rt2560var.h
@@ -0,0 +1,175 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2560var.h,v 1.3 2007/06/11 03:36:52 sam Exp $	*/
+
+/*-
+ * Copyright (c) 2005, 2006
+ *	Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+struct rt2560_rx_radiotap_header {
+	struct ieee80211_radiotap_header wr_ihdr;
+	uint64_t	wr_tsf;
+	uint8_t		wr_flags;
+	uint8_t		wr_rate;
+	uint16_t	wr_chan_freq;
+	uint16_t	wr_chan_flags;
+	uint8_t		wr_antenna;
+	uint8_t		wr_antsignal;
+};
+
+#define RT2560_RX_RADIOTAP_PRESENT					\
+	((1 << IEEE80211_RADIOTAP_TSFT) |				\
+	 (1 << IEEE80211_RADIOTAP_FLAGS) |				\
+	 (1 << IEEE80211_RADIOTAP_RATE) |				\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
+	 (1 << IEEE80211_RADIOTAP_ANTENNA) |				\
+	 (1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL))
+
+struct rt2560_tx_radiotap_header {
+	struct ieee80211_radiotap_header wt_ihdr;
+	uint8_t		wt_flags;
+	uint8_t		wt_rate;
+	uint16_t	wt_chan_freq;
+	uint16_t	wt_chan_flags;
+	uint8_t		wt_antenna;
+};
+
+#define RT2560_TX_RADIOTAP_PRESENT					\
+	((1 << IEEE80211_RADIOTAP_FLAGS) |				\
+	 (1 << IEEE80211_RADIOTAP_RATE) |				\
+	 (1 << IEEE80211_RADIOTAP_CHANNEL) |				\
+	 (1 << IEEE80211_RADIOTAP_ANTENNA))
+
+struct rt2560_tx_data {
+	bus_dmamap_t			map;
+	struct mbuf			*m;
+	struct ieee80211_node		*ni;
+	struct ral_rssdesc		id;
+};
+
+struct rt2560_tx_ring {
+	bus_dma_tag_t		desc_dmat;
+	bus_dma_tag_t		data_dmat;
+	bus_dmamap_t		desc_map;
+	bus_addr_t		physaddr;
+	struct rt2560_tx_desc	*desc;
+	struct rt2560_tx_data	*data;
+	int			count;
+	int			queued;
+	int			cur;
+	int			next;
+	int			cur_encrypt;
+	int			next_encrypt;
+};
+
+struct rt2560_rx_data {
+	bus_dmamap_t	map;
+	struct mbuf	*m;
+	int		drop;
+};
+
+struct rt2560_rx_ring {
+	bus_dma_tag_t		desc_dmat;
+	bus_dma_tag_t		data_dmat;
+	bus_dmamap_t		desc_map;
+	bus_addr_t		physaddr;
+	struct rt2560_rx_desc	*desc;
+	struct rt2560_rx_data	*data;
+	int			count;
+	int			cur;
+	int			next;
+	int			cur_decrypt;
+};
+
+struct rt2560_node {
+	struct ieee80211_node	ni;
+	struct ral_rssadapt	rssadapt;
+};
+
+struct rt2560_softc {
+	struct ifnet		*sc_ifp;
+	struct ieee80211com	sc_ic;
+	int			(*sc_newstate)(struct ieee80211com *,
+				    enum ieee80211_state, int);
+	device_t		sc_dev;
+	bus_space_tag_t		sc_st;
+	bus_space_handle_t	sc_sh;
+
+	struct mtx		sc_mtx;
+
+	struct callout		watchdog_ch;
+	struct callout		rssadapt_ch;
+
+	int			sc_tx_timer;
+	int                     sc_invalid;
+/*
+ * The same in both up to here
+ * ------------------------------------------------
+ */
+	uint32_t		asic_rev;
+	uint32_t		eeprom_rev;
+	uint8_t			rf_rev;
+	uint8_t			rssi_corr;
+
+	struct rt2560_tx_ring	txq;
+	struct rt2560_tx_ring	prioq;
+	struct rt2560_tx_ring	atimq;
+	struct rt2560_tx_ring	bcnq;
+	struct rt2560_rx_ring	rxq;
+
+	struct ieee80211_beacon_offsets	sc_bo;
+
+	uint32_t		rf_regs[4];
+	uint8_t			txpow[14];
+
+	struct {
+		uint8_t	reg;
+		uint8_t	val;
+	}			bbp_prom[16];
+
+	int			led_mode;
+	int			hw_radio;
+	int			rx_ant;
+	int			tx_ant;
+	int			nb_ant;
+
+	int			dwelltime;
+
+	struct bpf_if		*sc_drvbpf;
+
+	union {
+		struct rt2560_rx_radiotap_header th;
+		uint8_t	pad[64];
+	}			sc_rxtapu;
+#define sc_rxtap	sc_rxtapu.th
+	int			sc_rxtap_len;
+
+	union {
+		struct rt2560_tx_radiotap_header th;
+		uint8_t	pad[64];
+	}			sc_txtapu;
+#define sc_txtap	sc_txtapu.th
+	int			sc_txtap_len;
+#define                 RAL_INPUT_RUNNING       1
+	int                     sc_flags;
+};
+
+int	rt2560_attach(device_t, int);
+int	rt2560_detach(void *);
+void	rt2560_stop(void *);
+void	rt2560_resume(void *);
+void	rt2560_intr(void *);
+
+#define RAL_LOCK(sc)	mtx_lock(&(sc)->sc_mtx)
+#define RAL_UNLOCK(sc)	mtx_unlock(&(sc)->sc_mtx)
--- /dev/null
+++ sys/dev/ral/rt2661reg.h
@@ -0,0 +1,488 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2661reg.h,v 1.2 2007/06/11 03:36:52 sam Exp $	*/
+
+/*-
+ * Copyright (c) 2006
+ *	Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#define RT2661_NOISE_FLOOR	-95
+
+#define RT2661_TX_RING_COUNT	32
+#define RT2661_MGT_RING_COUNT	32
+#define RT2661_RX_RING_COUNT	64
+
+#define RT2661_TX_DESC_SIZE	(sizeof (struct rt2661_tx_desc))
+#define RT2661_TX_DESC_WSIZE	(RT2661_TX_DESC_SIZE / 4)
+#define RT2661_RX_DESC_SIZE	(sizeof (struct rt2661_rx_desc))
+#define RT2661_RX_DESC_WSIZE	(RT2661_RX_DESC_SIZE / 4)
+
+#define RT2661_MAX_SCATTER	5
+
+/*
+ * Control and status registers.
+ */
+#define RT2661_HOST_CMD_CSR		0x0008
+#define RT2661_MCU_CNTL_CSR		0x000c
+#define RT2661_SOFT_RESET_CSR		0x0010
+#define RT2661_MCU_INT_SOURCE_CSR	0x0014
+#define RT2661_MCU_INT_MASK_CSR		0x0018
+#define RT2661_PCI_USEC_CSR		0x001c
+#define RT2661_H2M_MAILBOX_CSR		0x2100
+#define RT2661_M2H_CMD_DONE_CSR		0x2104
+#define RT2661_HW_BEACON_BASE0		0x2c00
+#define RT2661_MAC_CSR0			0x3000
+#define RT2661_MAC_CSR1			0x3004
+#define RT2661_MAC_CSR2			0x3008
+#define RT2661_MAC_CSR3			0x300c
+#define RT2661_MAC_CSR4			0x3010
+#define RT2661_MAC_CSR5			0x3014
+#define RT2661_MAC_CSR6			0x3018
+#define RT2661_MAC_CSR7			0x301c
+#define RT2661_MAC_CSR8			0x3020
+#define RT2661_MAC_CSR9			0x3024
+#define RT2661_MAC_CSR10		0x3028
+#define RT2661_MAC_CSR11		0x302c
+#define RT2661_MAC_CSR12		0x3030
+#define RT2661_MAC_CSR13		0x3034
+#define RT2661_MAC_CSR14		0x3038
+#define RT2661_MAC_CSR15		0x303c
+#define RT2661_TXRX_CSR0		0x3040
+#define RT2661_TXRX_CSR1		0x3044
+#define RT2661_TXRX_CSR2		0x3048
+#define RT2661_TXRX_CSR3		0x304c
+#define RT2661_TXRX_CSR4		0x3050
+#define RT2661_TXRX_CSR5		0x3054
+#define RT2661_TXRX_CSR6		0x3058
+#define RT2661_TXRX_CSR7		0x305c
+#define RT2661_TXRX_CSR8		0x3060
+#define RT2661_TXRX_CSR9		0x3064
+#define RT2661_TXRX_CSR10		0x3068
+#define RT2661_TXRX_CSR11		0x306c
+#define RT2661_TXRX_CSR12		0x3070
+#define RT2661_TXRX_CSR13		0x3074
+#define RT2661_TXRX_CSR14		0x3078
+#define RT2661_TXRX_CSR15		0x307c
+#define RT2661_PHY_CSR0			0x3080
+#define RT2661_PHY_CSR1			0x3084
+#define RT2661_PHY_CSR2			0x3088
+#define RT2661_PHY_CSR3			0x308c
+#define RT2661_PHY_CSR4			0x3090
+#define RT2661_PHY_CSR5			0x3094
+#define RT2661_PHY_CSR6			0x3098
+#define RT2661_PHY_CSR7			0x309c
+#define RT2661_SEC_CSR0			0x30a0
+#define RT2661_SEC_CSR1			0x30a4
+#define RT2661_SEC_CSR2			0x30a8
+#define RT2661_SEC_CSR3			0x30ac
+#define RT2661_SEC_CSR4			0x30b0
+#define RT2661_SEC_CSR5			0x30b4
+#define RT2661_STA_CSR0			0x30c0
+#define RT2661_STA_CSR1			0x30c4
+#define RT2661_STA_CSR2			0x30c8
+#define RT2661_STA_CSR3			0x30cc
+#define RT2661_STA_CSR4			0x30d0
+#define RT2661_AC0_BASE_CSR		0x3400
+#define RT2661_AC1_BASE_CSR		0x3404
+#define RT2661_AC2_BASE_CSR		0x3408
+#define RT2661_AC3_BASE_CSR		0x340c
+#define RT2661_MGT_BASE_CSR		0x3410
+#define RT2661_TX_RING_CSR0		0x3418
+#define RT2661_TX_RING_CSR1		0x341c
+#define RT2661_AIFSN_CSR		0x3420
+#define RT2661_CWMIN_CSR		0x3424
+#define RT2661_CWMAX_CSR		0x3428
+#define RT2661_TX_DMA_DST_CSR		0x342c
+#define RT2661_TX_CNTL_CSR		0x3430
+#define RT2661_LOAD_TX_RING_CSR		0x3434
+#define RT2661_RX_BASE_CSR		0x3450
+#define RT2661_RX_RING_CSR		0x3454
+#define RT2661_RX_CNTL_CSR		0x3458
+#define RT2661_PCI_CFG_CSR		0x3460
+#define RT2661_INT_SOURCE_CSR		0x3468
+#define RT2661_INT_MASK_CSR		0x346c
+#define RT2661_E2PROM_CSR		0x3470
+#define RT2661_AC_TXOP_CSR0		0x3474
+#define RT2661_AC_TXOP_CSR1		0x3478
+#define RT2661_TEST_MODE_CSR		0x3484
+#define RT2661_IO_CNTL_CSR		0x3498
+#define RT2661_MCU_CODE_BASE		0x4000
+
+
+/* possible flags for register HOST_CMD_CSR */
+#define RT2661_KICK_CMD		(1 << 7)
+/* Host to MCU (8051) command identifiers */
+#define RT2661_MCU_CMD_SLEEP	0x30
+#define RT2661_MCU_CMD_WAKEUP	0x31
+#define RT2661_MCU_SET_LED	0x50
+#define RT2661_MCU_SET_RSSI_LED	0x52
+
+/* possible flags for register MCU_CNTL_CSR */
+#define RT2661_MCU_SEL		(1 << 0)
+#define RT2661_MCU_RESET	(1 << 1)
+#define RT2661_MCU_READY	(1 << 2)
+
+/* possible flags for register MCU_INT_SOURCE_CSR */
+#define RT2661_MCU_CMD_DONE		0xff
+#define RT2661_MCU_WAKEUP		(1 << 8)
+#define RT2661_MCU_BEACON_EXPIRE	(1 << 9)
+
+/* possible flags for register H2M_MAILBOX_CSR */
+#define RT2661_H2M_BUSY		(1 << 24)
+#define RT2661_TOKEN_NO_INTR	0xff
+
+/* possible flags for register MAC_CSR5 */
+#define RT2661_ONE_BSSID	3
+
+/* possible flags for register TXRX_CSR0 */
+/* Tx filter flags are in the low 16 bits */
+#define RT2661_AUTO_TX_SEQ	(1 << 15)
+/* Rx filter flags are in the high 16 bits */
+#define RT2661_DISABLE_RX	(1 << 16)
+#define RT2661_DROP_CRC_ERROR	(1 << 17)
+#define RT2661_DROP_PHY_ERROR	(1 << 18)
+#define RT2661_DROP_CTL		(1 << 19)
+#define RT2661_DROP_NOT_TO_ME	(1 << 20)
+#define RT2661_DROP_TODS	(1 << 21)
+#define RT2661_DROP_VER_ERROR	(1 << 22)
+#define RT2661_DROP_MULTICAST	(1 << 23)
+#define RT2661_DROP_BROADCAST	(1 << 24)
+#define RT2661_DROP_ACKCTS	(1 << 25)
+
+/* possible flags for register TXRX_CSR4 */
+#define RT2661_SHORT_PREAMBLE	(1 << 19)
+#define RT2661_MRR_ENABLED	(1 << 20)
+#define RT2661_MRR_CCK_FALLBACK	(1 << 23)
+
+/* possible flags for register TXRX_CSR9 */
+#define RT2661_TSF_TICKING	(1 << 16)
+#define RT2661_TSF_MODE(x)	(((x) & 0x3) << 17)
+/* TBTT stands for Target Beacon Transmission Time */
+#define RT2661_ENABLE_TBTT	(1 << 19)
+#define RT2661_GENERATE_BEACON	(1 << 20)
+
+/* possible flags for register PHY_CSR0 */
+#define RT2661_PA_PE_2GHZ	(1 << 16)
+#define RT2661_PA_PE_5GHZ	(1 << 17)
+
+/* possible flags for register PHY_CSR3 */
+#define RT2661_BBP_READ	(1 << 15)
+#define RT2661_BBP_BUSY	(1 << 16)
+
+/* possible flags for register PHY_CSR4 */
+#define RT2661_RF_21BIT	(21 << 24)
+#define RT2661_RF_BUSY	(1 << 31)
+
+/* possible values for register STA_CSR4 */
+#define RT2661_TX_STAT_VALID	(1 << 0)
+#define RT2661_TX_RESULT(v)	(((v) >> 1) & 0x7)
+#define RT2661_TX_RETRYCNT(v)	(((v) >> 4) & 0xf)
+#define RT2661_TX_QID(v)	(((v) >> 8) & 0xf)
+#define RT2661_TX_SUCCESS	0
+#define RT2661_TX_RETRY_FAIL	6
+
+/* possible flags for register TX_CNTL_CSR */
+#define RT2661_KICK_MGT	(1 << 4)
+
+/* possible flags for register INT_SOURCE_CSR */
+#define RT2661_TX_DONE		(1 << 0)
+#define RT2661_RX_DONE		(1 << 1)
+#define RT2661_TX0_DMA_DONE	(1 << 16)
+#define RT2661_TX1_DMA_DONE	(1 << 17)
+#define RT2661_TX2_DMA_DONE	(1 << 18)
+#define RT2661_TX3_DMA_DONE	(1 << 19)
+#define RT2661_MGT_DONE		(1 << 20)
+
+/* possible flags for register E2PROM_CSR */
+#define RT2661_C	(1 << 1)
+#define RT2661_S	(1 << 2)
+#define RT2661_D	(1 << 3)
+#define RT2661_Q	(1 << 4)
+#define RT2661_93C46	(1 << 5)
+
+/* Tx descriptor */
+struct rt2661_tx_desc {
+	uint32_t	flags;
+#define RT2661_TX_BUSY		(1 << 0)
+#define RT2661_TX_VALID		(1 << 1)
+#define RT2661_TX_MORE_FRAG	(1 << 2)
+#define RT2661_TX_NEED_ACK	(1 << 3)
+#define RT2661_TX_TIMESTAMP	(1 << 4)
+#define RT2661_TX_OFDM		(1 << 5)
+#define RT2661_TX_IFS		(1 << 6)
+#define RT2661_TX_LONG_RETRY	(1 << 7)
+#define RT2661_TX_BURST		(1 << 28)
+
+	uint16_t	wme;
+#define RT2661_QID(v)		(v)
+#define RT2661_AIFSN(v)		((v) << 4)
+#define RT2661_LOGCWMIN(v)	((v) << 8)
+#define RT2661_LOGCWMAX(v)	((v) << 12)
+
+	uint16_t	xflags;
+#define RT2661_TX_HWSEQ		(1 << 12)
+
+	uint8_t		plcp_signal;
+	uint8_t		plcp_service;
+#define RT2661_PLCP_LENGEXT	0x80
+
+	uint8_t		plcp_length_lo;
+	uint8_t		plcp_length_hi;
+
+	uint32_t	iv;
+	uint32_t	eiv;
+
+	uint8_t		offset;
+	uint8_t		qid;
+#define RT2661_QID_MGT	13
+
+	uint8_t		txpower;
+#define RT2661_DEFAULT_TXPOWER	0
+
+	uint8_t		reserved1;
+
+	uint32_t	addr[RT2661_MAX_SCATTER];
+	uint16_t	len[RT2661_MAX_SCATTER];
+
+	uint16_t	reserved2;
+} __packed;
+
+/* Rx descriptor */
+struct rt2661_rx_desc {
+	uint32_t	flags;
+#define RT2661_RX_BUSY		(1 << 0)
+#define RT2661_RX_DROP		(1 << 1)
+#define RT2661_RX_CRC_ERROR	(1 << 6)
+#define RT2661_RX_OFDM		(1 << 7)
+#define RT2661_RX_PHY_ERROR	(1 << 8)
+#define RT2661_RX_CIPHER_MASK	0x00000600
+
+	uint8_t		rate;
+	uint8_t		rssi;
+	uint8_t		reserved1;
+	uint8_t		offset;
+	uint32_t	iv;
+	uint32_t	eiv;
+	uint32_t	reserved2;
+	uint32_t	physaddr;
+	uint32_t	reserved3[10];
+} __packed;
+
+#define RAL_RF1	0
+#define RAL_RF2	2
+#define RAL_RF3	1
+#define RAL_RF4	3
+
+/* dual-band RF */
+#define RT2661_RF_5225	1
+#define RT2661_RF_5325	2
+/* single-band RF */
+#define RT2661_RF_2527	3
+#define RT2661_RF_2529	4
+
+#define RT2661_RX_DESC_BACK	4
+
+#define RT2661_SMART_MODE	(1 << 0)
+
+#define RT2661_BBPR94_DEFAULT	6
+
+#define RT2661_SHIFT_D	3
+#define RT2661_SHIFT_Q	4
+
+#define RT2661_EEPROM_MAC01		0x02
+#define RT2661_EEPROM_MAC23		0x03
+#define RT2661_EEPROM_MAC45		0x04
+#define RT2661_EEPROM_ANTENNA		0x10
+#define RT2661_EEPROM_CONFIG2		0x11
+#define RT2661_EEPROM_BBP_BASE		0x13
+#define RT2661_EEPROM_TXPOWER		0x23
+#define RT2661_EEPROM_FREQ_OFFSET	0x2f
+#define RT2661_EEPROM_RSSI_2GHZ_OFFSET	0x4d
+#define RT2661_EEPROM_RSSI_5GHZ_OFFSET	0x4e
+
+#define RT2661_EEPROM_DELAY	1	/* minimum hold time (microsecond) */
+
+/*
+ * control and status registers access macros
+ */
+#define RAL_READ(sc, reg)						\
+	bus_space_read_4((sc)->sc_st, (sc)->sc_sh, (reg))
+
+#define RAL_READ_REGION_4(sc, offset, datap, count)			\
+	bus_space_read_region_4((sc)->sc_st, (sc)->sc_sh, (offset),	\
+	    (datap), (count))
+
+#define RAL_WRITE(sc, reg, val)						\
+	bus_space_write_4((sc)->sc_st, (sc)->sc_sh, (reg), (val))
+
+#define RAL_WRITE_REGION_1(sc, offset, datap, count)			\
+	bus_space_write_region_1((sc)->sc_st, (sc)->sc_sh, (offset),	\
+	    (datap), (count))
+
+/*
+ * EEPROM access macro
+ */
+#define RT2661_EEPROM_CTL(sc, val) do {					\
+	RAL_WRITE((sc), RT2661_E2PROM_CSR, (val));			\
+	DELAY(RT2661_EEPROM_DELAY);					\
+} while (/* CONSTCOND */0)
+
+/*
+ * Default values for MAC registers; values taken from the reference driver.
+ */
+#define RT2661_DEF_MAC					\
+	{ RT2661_TXRX_CSR0,        0x0000b032 },	\
+	{ RT2661_TXRX_CSR1,        0x9eb39eb3 },	\
+	{ RT2661_TXRX_CSR2,        0x8a8b8c8d },	\
+	{ RT2661_TXRX_CSR3,        0x00858687 },	\
+	{ RT2661_TXRX_CSR7,        0x2e31353b },	\
+	{ RT2661_TXRX_CSR8,        0x2a2a2a2c },	\
+	{ RT2661_TXRX_CSR15,       0x0000000f },	\
+	{ RT2661_MAC_CSR6,         0x00000fff },	\
+	{ RT2661_MAC_CSR8,         0x016c030a },	\
+	{ RT2661_MAC_CSR10,        0x00000718 },	\
+	{ RT2661_MAC_CSR12,        0x00000004 },	\
+	{ RT2661_MAC_CSR13,        0x0000e000 },	\
+	{ RT2661_SEC_CSR0,         0x00000000 },	\
+	{ RT2661_SEC_CSR1,         0x00000000 },	\
+	{ RT2661_SEC_CSR5,         0x00000000 },	\
+	{ RT2661_PHY_CSR1,         0x000023b0 },	\
+	{ RT2661_PHY_CSR5,         0x060a100c },	\
+	{ RT2661_PHY_CSR6,         0x00080606 },	\
+	{ RT2661_PHY_CSR7,         0x00000a08 },	\
+	{ RT2661_PCI_CFG_CSR,      0x3cca4808 },	\
+	{ RT2661_AIFSN_CSR,        0x00002273 },	\
+	{ RT2661_CWMIN_CSR,        0x00002344 },	\
+	{ RT2661_CWMAX_CSR,        0x000034aa },	\
+	{ RT2661_TEST_MODE_CSR,    0x00000200 },	\
+	{ RT2661_M2H_CMD_DONE_CSR, 0xffffffff }
+
+/*
+ * Default values for BBP registers; values taken from the reference driver.
+ */
+#define RT2661_DEF_BBP	\
+	{   3, 0x00 },	\
+	{  15, 0x30 },	\
+	{  17, 0x20 },	\
+	{  21, 0xc8 },	\
+	{  22, 0x38 },	\
+	{  23, 0x06 },	\
+	{  24, 0xfe },	\
+	{  25, 0x0a },	\
+	{  26, 0x0d },	\
+	{  34, 0x12 },	\
+	{  37, 0x07 },	\
+	{  39, 0xf8 },	\
+	{  41, 0x60 },	\
+	{  53, 0x10 },	\
+	{  54, 0x18 },	\
+	{  60, 0x10 },	\
+	{  61, 0x04 },	\
+	{  62, 0x04 },	\
+	{  75, 0xfe },	\
+	{  86, 0xfe },	\
+	{  88, 0xfe },	\
+	{  90, 0x0f },	\
+	{  99, 0x00 },	\
+	{ 102, 0x16 },	\
+	{ 107, 0x04 }
+
+/*
+ * Default settings for RF registers; values taken from the reference driver.
+ */
+#define RT2661_RF5225_1					\
+	{   1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },	\
+	{   2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },	\
+	{   3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },	\
+	{   4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },	\
+	{   5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },	\
+	{   6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },	\
+	{   7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },	\
+	{   8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },	\
+	{   9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },	\
+	{  10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },	\
+	{  11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },	\
+	{  12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },	\
+	{  13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },	\
+	{  14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },	\
+							\
+	{  36, 0x00b33, 0x01266, 0x26014, 0x30288 },	\
+	{  40, 0x00b33, 0x01268, 0x26014, 0x30280 },	\
+	{  44, 0x00b33, 0x01269, 0x26014, 0x30282 },	\
+	{  48, 0x00b33, 0x0126a, 0x26014, 0x30284 },	\
+	{  52, 0x00b33, 0x0126b, 0x26014, 0x30286 },	\
+	{  56, 0x00b33, 0x0126c, 0x26014, 0x30288 },	\
+	{  60, 0x00b33, 0x0126e, 0x26014, 0x30280 },	\
+	{  64, 0x00b33, 0x0126f, 0x26014, 0x30282 },	\
+							\
+	{ 100, 0x00b33, 0x0128a, 0x2e014, 0x30280 },	\
+	{ 104, 0x00b33, 0x0128b, 0x2e014, 0x30282 },	\
+	{ 108, 0x00b33, 0x0128c, 0x2e014, 0x30284 },	\
+	{ 112, 0x00b33, 0x0128d, 0x2e014, 0x30286 },	\
+	{ 116, 0x00b33, 0x0128e, 0x2e014, 0x30288 },	\
+	{ 120, 0x00b33, 0x012a0, 0x2e014, 0x30280 },	\
+	{ 124, 0x00b33, 0x012a1, 0x2e014, 0x30282 },	\
+	{ 128, 0x00b33, 0x012a2, 0x2e014, 0x30284 },	\
+	{ 132, 0x00b33, 0x012a3, 0x2e014, 0x30286 },	\
+	{ 136, 0x00b33, 0x012a4, 0x2e014, 0x30288 },	\
+	{ 140, 0x00b33, 0x012a6, 0x2e014, 0x30280 },	\
+							\
+	{ 149, 0x00b33, 0x012a8, 0x2e014, 0x30287 },	\
+	{ 153, 0x00b33, 0x012a9, 0x2e014, 0x30289 },	\
+	{ 157, 0x00b33, 0x012ab, 0x2e014, 0x30281 },	\
+	{ 161, 0x00b33, 0x012ac, 0x2e014, 0x30283 },	\
+	{ 165, 0x00b33, 0x012ad, 0x2e014, 0x30285 }
+
+#define RT2661_RF5225_2					\
+	{   1, 0x00b33, 0x011e1, 0x1a014, 0x30282 },	\
+	{   2, 0x00b33, 0x011e1, 0x1a014, 0x30287 },	\
+	{   3, 0x00b33, 0x011e2, 0x1a014, 0x30282 },	\
+	{   4, 0x00b33, 0x011e2, 0x1a014, 0x30287 },	\
+	{   5, 0x00b33, 0x011e3, 0x1a014, 0x30282 },	\
+	{   6, 0x00b33, 0x011e3, 0x1a014, 0x30287 },	\
+	{   7, 0x00b33, 0x011e4, 0x1a014, 0x30282 },	\
+	{   8, 0x00b33, 0x011e4, 0x1a014, 0x30287 },	\
+	{   9, 0x00b33, 0x011e5, 0x1a014, 0x30282 },	\
+	{  10, 0x00b33, 0x011e5, 0x1a014, 0x30287 },	\
+	{  11, 0x00b33, 0x011e6, 0x1a014, 0x30282 },	\
+	{  12, 0x00b33, 0x011e6, 0x1a014, 0x30287 },	\
+	{  13, 0x00b33, 0x011e7, 0x1a014, 0x30282 },	\
+	{  14, 0x00b33, 0x011e8, 0x1a014, 0x30284 },	\
+							\
+	{  36, 0x00b35, 0x11206, 0x26014, 0x30280 },	\
+	{  40, 0x00b34, 0x111a0, 0x26014, 0x30280 },	\
+	{  44, 0x00b34, 0x111a1, 0x26014, 0x30286 },	\
+	{  48, 0x00b34, 0x111a3, 0x26014, 0x30282 },	\
+	{  52, 0x00b34, 0x111a4, 0x26014, 0x30288 },	\
+	{  56, 0x00b34, 0x111a6, 0x26014, 0x30284 },	\
+	{  60, 0x00b34, 0x111a8, 0x26014, 0x30280 },	\
+	{  64, 0x00b34, 0x111a9, 0x26014, 0x30286 },	\
+							\
+	{ 100, 0x00b35, 0x11226, 0x2e014, 0x30280 },	\
+	{ 104, 0x00b35, 0x11228, 0x2e014, 0x30280 },	\
+	{ 108, 0x00b35, 0x1122a, 0x2e014, 0x30280 },	\
+	{ 112, 0x00b35, 0x1122c, 0x2e014, 0x30280 },	\
+	{ 116, 0x00b35, 0x1122e, 0x2e014, 0x30280 },	\
+	{ 120, 0x00b34, 0x111c0, 0x2e014, 0x30280 },	\
+	{ 124, 0x00b34, 0x111c1, 0x2e014, 0x30286 },	\
+	{ 128, 0x00b34, 0x111c3, 0x2e014, 0x30282 },	\
+	{ 132, 0x00b34, 0x111c4, 0x2e014, 0x30288 },	\
+	{ 136, 0x00b34, 0x111c6, 0x2e014, 0x30284 },	\
+	{ 140, 0x00b34, 0x111c8, 0x2e014, 0x30280 },	\
+							\
+	{ 149, 0x00b34, 0x111cb, 0x2e014, 0x30286 },	\
+	{ 153, 0x00b34, 0x111cd, 0x2e014, 0x30282 },	\
+	{ 157, 0x00b35, 0x11242, 0x2e014, 0x30285 },	\
+	{ 161, 0x00b35, 0x11244, 0x2e014, 0x30285 },	\
+	{ 165, 0x00b35, 0x11246, 0x2e014, 0x30285 }
--- /dev/null
+++ sys/dev/ral/rt2661.c
@@ -0,0 +1,2943 @@
+/*	$FreeBSD: src/sys/dev/ral/rt2661.c,v 1.17 2007/09/17 19:07:23 sam Exp $	*/
+
+/*-
+ * Copyright (c) 2006
+ *	Damien Bergamini <damien.bergamini at free.fr>
+ *
+ * Permission to use, copy, modify, and distribute this software for any
+ * purpose with or without fee is hereby granted, provided that the above
+ * copyright notice and this permission notice appear in all copies.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
+ * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
+ * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
+ * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
+ * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
+ * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
+ * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
+ */
+
+#include <sys/cdefs.h>
+__FBSDID("$FreeBSD: src/sys/dev/ral/rt2661.c,v 1.17 2007/09/17 19:07:23 sam Exp $");
+
+/*-
+ * Ralink Technology RT2561, RT2561S and RT2661 chipset driver
+ * http://www.ralinktech.com/
+ */
+
+#include <sys/param.h>
+#include <sys/sysctl.h>
+#include <sys/sockio.h>
+#include <sys/mbuf.h>
+#include <sys/kernel.h>
+#include <sys/socket.h>
+#include <sys/systm.h>
+#include <sys/malloc.h>
+#include <sys/lock.h>
+#include <sys/mutex.h>
+#include <sys/module.h>
+#include <sys/bus.h>
+#include <sys/endian.h>
+
+#include <machine/bus.h>
+#include <machine/resource.h>
+#include <sys/rman.h>
+
+#include <net/bpf.h>
+#include <net/if.h>
+#include <net/if_arp.h>
+#include <net/ethernet.h>
+#include <net/if_dl.h>
+#include <net/if_media.h>
+#include <net/if_types.h>
+
+#include <net80211/ieee80211_var.h>
+#include <net80211/ieee80211_radiotap.h>
+#include <net80211/ieee80211_regdomain.h>
+
+#include <netinet/in.h>
+#include <netinet/in_systm.h>
+#include <netinet/in_var.h>
+#include <netinet/ip.h>
+#include <netinet/if_ether.h>
+
+#include <dev/ral/if_ralrate.h>
+#include <dev/ral/rt2661reg.h>
+#include <dev/ral/rt2661var.h>
+#include <dev/ral/rt2661_ucode.h>
+
+#ifdef RAL_DEBUG
+#define DPRINTF(x)	do { if (ral_debug > 0) printf x; } while (0)
+#define DPRINTFN(n, x)	do { if (ral_debug >= (n)) printf x; } while (0)
+int ral_debug = 0;
+SYSCTL_INT(_debug, OID_AUTO, ral, CTLFLAG_RW, &ral_debug, 0, "ral debug level");
+#else
+#define DPRINTF(x)
+#define DPRINTFN(n, x)
+#endif
+
+static void		rt2661_dma_map_addr(void *, bus_dma_segment_t *, int,
+			    int);
+static int		rt2661_alloc_tx_ring(struct rt2661_softc *,
+			    struct rt2661_tx_ring *, int);
+static void		rt2661_reset_tx_ring(struct rt2661_softc *,
+			    struct rt2661_tx_ring *);
+static void		rt2661_free_tx_ring(struct rt2661_softc *,
+			    struct rt2661_tx_ring *);
+static int		rt2661_alloc_rx_ring(struct rt2661_softc *,
+			    struct rt2661_rx_ring *, int);
+static void		rt2661_reset_rx_ring(struct rt2661_softc *,
+			    struct rt2661_rx_ring *);
+static void		rt2661_free_rx_ring(struct rt2661_softc *,
+			    struct rt2661_rx_ring *);
+static struct		ieee80211_node *rt2661_node_alloc(
+			    struct ieee80211_node_table *);
+static int		rt2661_media_change(struct ifnet *);
+static int		rt2661_newstate(struct ieee80211com *,
+			    enum ieee80211_state, int);
+static uint16_t		rt2661_eeprom_read(struct rt2661_softc *, uint8_t);
+static void		rt2661_rx_intr(struct rt2661_softc *);
+static void		rt2661_tx_intr(struct rt2661_softc *);
+static void		rt2661_tx_dma_intr(struct rt2661_softc *,
+			    struct rt2661_tx_ring *);
+static void		rt2661_mcu_beacon_expire(struct rt2661_softc *);
+static void		rt2661_mcu_wakeup(struct rt2661_softc *);
+static void		rt2661_mcu_cmd_intr(struct rt2661_softc *);
+static int		rt2661_ack_rate(struct ieee80211com *, int);
+static void		rt2661_scan_start(struct ieee80211com *);
+static void		rt2661_scan_end(struct ieee80211com *);
+static void		rt2661_set_channel(struct ieee80211com *);
+static uint16_t		rt2661_txtime(int, int, uint32_t);
+static uint8_t		rt2661_rxrate(struct rt2661_rx_desc *);
+static uint8_t		rt2661_plcp_signal(int);
+static void		rt2661_setup_tx_desc(struct rt2661_softc *,
+			    struct rt2661_tx_desc *, uint32_t, uint16_t, int,
+			    int, const bus_dma_segment_t *, int, int);
+static struct mbuf *	rt2661_get_rts(struct rt2661_softc *,
+			    struct ieee80211_frame *, uint16_t);
+static int		rt2661_tx_data(struct rt2661_softc *, struct mbuf *,
+			    struct ieee80211_node *, int);
+static int		rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *,
+			    struct ieee80211_node *);
+static void		rt2661_start(struct ifnet *);
+static void		rt2661_watchdog(void *);
+static int		rt2661_reset(struct ifnet *);
+static int		rt2661_ioctl(struct ifnet *, u_long, caddr_t);
+static void		rt2661_bbp_write(struct rt2661_softc *, uint8_t,
+			    uint8_t);
+static uint8_t		rt2661_bbp_read(struct rt2661_softc *, uint8_t);
+static void		rt2661_rf_write(struct rt2661_softc *, uint8_t,
+			    uint32_t);
+static int		rt2661_tx_cmd(struct rt2661_softc *, uint8_t,
+			    uint16_t);
+static void		rt2661_select_antenna(struct rt2661_softc *);
+static void		rt2661_enable_mrr(struct rt2661_softc *);
+static void		rt2661_set_txpreamble(struct rt2661_softc *);
+static void		rt2661_set_basicrates(struct rt2661_softc *,
+			    const struct ieee80211_rateset *);
+static void		rt2661_select_band(struct rt2661_softc *,
+			    struct ieee80211_channel *);
+static void		rt2661_set_chan(struct rt2661_softc *,
+			    struct ieee80211_channel *);
+static void		rt2661_set_bssid(struct rt2661_softc *,
+			    const uint8_t *);
+static void		rt2661_set_macaddr(struct rt2661_softc *,
+			   const uint8_t *);
+static void		rt2661_update_promisc(struct rt2661_softc *);
+static int		rt2661_wme_update(struct ieee80211com *) __unused;
+static void		rt2661_update_slot(struct ifnet *);
+static const char	*rt2661_get_rf(int);
+static void		rt2661_read_eeprom(struct rt2661_softc *);
+static int		rt2661_bbp_init(struct rt2661_softc *);
+static void		rt2661_init(void *);
+static void		rt2661_stop(void *);
+static void             rt2661_stop_locked(struct rt2661_softc *);
+static int		rt2661_load_microcode(struct rt2661_softc *,
+			    const uint8_t *, int);
+#ifdef notyet
+static void		rt2661_rx_tune(struct rt2661_softc *);
+static void		rt2661_radar_start(struct rt2661_softc *);
+static int		rt2661_radar_stop(struct rt2661_softc *);
+#endif
+static int		rt2661_prepare_beacon(struct rt2661_softc *);
+static void		rt2661_enable_tsf_sync(struct rt2661_softc *);
+static int		rt2661_get_rssi(struct rt2661_softc *, uint8_t);
+
+static const struct {
+	uint32_t	reg;
+	uint32_t	val;
+} rt2661_def_mac[] = {
+	RT2661_DEF_MAC
+};
+
+static const struct {
+	uint8_t	reg;
+	uint8_t	val;
+} rt2661_def_bbp[] = {
+	RT2661_DEF_BBP
+};
+
+static const struct rfprog {
+	uint8_t		chan;
+	uint32_t	r1, r2, r3, r4;
+}  rt2661_rf5225_1[] = {
+	RT2661_RF5225_1
+}, rt2661_rf5225_2[] = {
+	RT2661_RF5225_2
+};
+
+int
+rt2661_attach(device_t dev, int id)
+{
+	struct rt2661_softc *sc = device_get_softc(dev);
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp;
+	uint32_t val;
+	const uint8_t *ucode = NULL;
+	int bands, error, ac, ntries, size = 0;
+
+	sc->sc_dev = dev;
+
+	mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK,
+	    MTX_DEF | MTX_RECURSE);
+
+	callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0);
+	callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE);
+
+	/* wait for NIC to initialize */
+	for (ntries = 0; ntries < 1000; ntries++) {
+		if ((val = RAL_READ(sc, RT2661_MAC_CSR0)) != 0)
+			break;
+		DELAY(1000);
+	}
+	if (ntries == 1000) {
+		device_printf(sc->sc_dev,
+		    "timeout waiting for NIC to initialize\n");
+		error = EIO;
+		goto fail1;
+	}
+
+	/* retrieve RF rev. no and various other things from EEPROM */
+	rt2661_read_eeprom(sc);
+
+	device_printf(dev, "MAC/BBP RT%X, RF %s\n", val,
+	    rt2661_get_rf(sc->rf_rev));
+
+	/*
+	 * Load 8051 microcode into NIC.
+	 */
+	switch (id) {
+	case 0x0301:
+		ucode = rt2561s_ucode;
+		size = sizeof rt2561s_ucode;
+		break;
+	case 0x0302:
+		ucode = rt2561_ucode;
+		size = sizeof rt2561_ucode;
+		break;
+	case 0x0401:
+		ucode = rt2661_ucode;
+		size = sizeof rt2661_ucode;
+		break;
+	}
+
+	error = rt2661_load_microcode(sc, ucode, size);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not load 8051 microcode\n");
+		goto fail1;
+	}
+
+	/*
+	 * Allocate Tx and Rx rings.
+	 */
+	for (ac = 0; ac < 4; ac++) {
+		error = rt2661_alloc_tx_ring(sc, &sc->txq[ac],
+		    RT2661_TX_RING_COUNT);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not allocate Tx ring %d\n", ac);
+			goto fail2;
+		}
+	}
+
+	error = rt2661_alloc_tx_ring(sc, &sc->mgtq, RT2661_MGT_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Mgt ring\n");
+		goto fail2;
+	}
+
+	error = rt2661_alloc_rx_ring(sc, &sc->rxq, RT2661_RX_RING_COUNT);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate Rx ring\n");
+		goto fail3;
+	}
+
+	ifp = sc->sc_ifp = if_alloc(IFT_ETHER);
+	if (ifp == NULL) {
+		device_printf(sc->sc_dev, "can not if_alloc()\n");
+		error = ENOMEM;
+		goto fail4;
+	}
+
+	ifp->if_softc = sc;
+	if_initname(ifp, device_get_name(dev), device_get_unit(dev));
+	ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST;
+	ifp->if_init = rt2661_init;
+	ifp->if_ioctl = rt2661_ioctl;
+	ifp->if_start = rt2661_start;
+	IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN);
+	ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN;
+	IFQ_SET_READY(&ifp->if_snd);
+
+	ic->ic_ifp = ifp;
+	ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */
+	ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */
+	ic->ic_state = IEEE80211_S_INIT;
+
+	/* set device capabilities */
+	ic->ic_caps =
+	    IEEE80211_C_IBSS |		/* IBSS mode supported */
+	    IEEE80211_C_MONITOR |	/* monitor mode supported */
+	    IEEE80211_C_HOSTAP |	/* HostAp mode supported */
+	    IEEE80211_C_TXPMGT |	/* tx power management */
+	    IEEE80211_C_SHPREAMBLE |	/* short preamble supported */
+	    IEEE80211_C_SHSLOT |	/* short slot time supported */
+#ifdef notyet
+	    IEEE80211_C_WME |		/* 802.11e */
+#endif
+	    IEEE80211_C_BGSCAN |	/* bg scanning support */
+	    IEEE80211_C_WPA;		/* 802.11i */
+
+	bands = 0;
+	setbit(&bands, IEEE80211_MODE_11B);
+	setbit(&bands, IEEE80211_MODE_11G);
+	if (sc->rf_rev == RT2661_RF_5225 || sc->rf_rev == RT2661_RF_5325) 
+		setbit(&bands, IEEE80211_MODE_11A);
+	ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1);
+
+	ieee80211_ifattach(ic);
+	ic->ic_node_alloc = rt2661_node_alloc;
+/*	ic->ic_wme.wme_update = rt2661_wme_update;*/
+	ic->ic_scan_start = rt2661_scan_start;
+	ic->ic_scan_end = rt2661_scan_end;
+	ic->ic_set_channel = rt2661_set_channel;
+	ic->ic_updateslot = rt2661_update_slot;
+	ic->ic_reset = rt2661_reset;
+	/* enable s/w bmiss handling in sta mode */
+	ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS;
+
+	/* override state transition machine */
+	sc->sc_newstate = ic->ic_newstate;
+	ic->ic_newstate = rt2661_newstate;
+	ieee80211_media_init(ic, rt2661_media_change, ieee80211_media_status);
+
+	bpfattach2(ifp, DLT_IEEE802_11_RADIO,
+	    sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), 
+	    &sc->sc_drvbpf);
+
+	sc->sc_rxtap_len = sizeof sc->sc_rxtap;
+	sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len);
+	sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2661_RX_RADIOTAP_PRESENT);
+
+	sc->sc_txtap_len = sizeof sc->sc_txtap;
+	sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len);
+	sc->sc_txtap.wt_ihdr.it_present = htole32(RT2661_TX_RADIOTAP_PRESENT);
+
+	
+	/*
+	 * Add a few sysctl knobs.
+	 */
+	sc->dwelltime = 200;
+
+	SYSCTL_ADD_INT(device_get_sysctl_ctx(dev),
+	    SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell",
+	    CTLFLAG_RW, &sc->dwelltime, 0,
+	    "channel dwell time (ms) for AP/station scanning");
+
+	if (bootverbose)
+		ieee80211_announce(ic);
+
+	return 0;
+
+fail4:	rt2661_free_rx_ring(sc, &sc->rxq);
+fail3:	rt2661_free_tx_ring(sc, &sc->mgtq);
+fail2:	while (--ac >= 0)
+		rt2661_free_tx_ring(sc, &sc->txq[ac]);
+fail1:	mtx_destroy(&sc->sc_mtx);
+	return error;
+}
+
+int
+rt2661_detach(void *xsc)
+{
+	struct rt2661_softc *sc = xsc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	
+	rt2661_stop(sc);
+	callout_stop(&sc->watchdog_ch);
+	callout_stop(&sc->rssadapt_ch);
+
+	bpfdetach(ifp);
+	ieee80211_ifdetach(ic);
+
+	rt2661_free_tx_ring(sc, &sc->txq[0]);
+	rt2661_free_tx_ring(sc, &sc->txq[1]);
+	rt2661_free_tx_ring(sc, &sc->txq[2]);
+	rt2661_free_tx_ring(sc, &sc->txq[3]);
+	rt2661_free_tx_ring(sc, &sc->mgtq);
+	rt2661_free_rx_ring(sc, &sc->rxq);
+
+	if_free(ifp);
+
+	mtx_destroy(&sc->sc_mtx);
+
+	return 0;
+}
+
+void
+rt2661_shutdown(void *xsc)
+{
+	struct rt2661_softc *sc = xsc;
+
+	rt2661_stop(sc);
+}
+
+void
+rt2661_suspend(void *xsc)
+{
+	struct rt2661_softc *sc = xsc;
+
+	rt2661_stop(sc);
+}
+
+void
+rt2661_resume(void *xsc)
+{
+	struct rt2661_softc *sc = xsc;
+	struct ifnet *ifp = sc->sc_ic.ic_ifp;
+
+	if (ifp->if_flags & IFF_UP) {
+		ifp->if_init(ifp->if_softc);
+		if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+			ifp->if_start(ifp);
+	}
+}
+
+static void
+rt2661_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error)
+{
+	if (error != 0)
+		return;
+
+	KASSERT(nseg == 1, ("too many DMA segments, %d should be 1", nseg));
+
+	*(bus_addr_t *)arg = segs[0].ds_addr;
+}
+
+static int
+rt2661_alloc_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring,
+    int count)
+{
+	int i, error;
+
+	ring->count = count;
+	ring->queued = 0;
+	ring->cur = ring->next = ring->stat = 0;
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    count * RT2661_TX_DESC_SIZE, 1, count * RT2661_TX_DESC_SIZE,
+	    0, NULL, NULL, &ring->desc_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create desc DMA tag\n");
+		goto fail;
+	}
+
+	error = bus_dmamem_alloc(ring->desc_dmat, (void **)&ring->desc,
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_map);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate DMA memory\n");
+		goto fail;
+	}
+
+	error = bus_dmamap_load(ring->desc_dmat, ring->desc_map, ring->desc,
+	    count * RT2661_TX_DESC_SIZE, rt2661_dma_map_addr, &ring->physaddr,
+	    0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not load desc DMA map\n");
+		goto fail;
+	}
+
+	ring->data = malloc(count * sizeof (struct rt2661_tx_data), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (ring->data == NULL) {
+		device_printf(sc->sc_dev, "could not allocate soft data\n");
+		error = ENOMEM;
+		goto fail;
+	}
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
+	    RT2661_MAX_SCATTER, MCLBYTES, 0, NULL, NULL, &ring->data_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create data DMA tag\n");
+		goto fail;
+	}
+
+	for (i = 0; i < count; i++) {
+		error = bus_dmamap_create(ring->data_dmat, 0,
+		    &ring->data[i].map);
+		if (error != 0) {
+			device_printf(sc->sc_dev, "could not create DMA map\n");
+			goto fail;
+		}
+	}
+
+	return 0;
+
+fail:	rt2661_free_tx_ring(sc, ring);
+	return error;
+}
+
+static void
+rt2661_reset_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
+{
+	struct rt2661_tx_desc *desc;
+	struct rt2661_tx_data *data;
+	int i;
+
+	for (i = 0; i < ring->count; i++) {
+		desc = &ring->desc[i];
+		data = &ring->data[i];
+
+		if (data->m != NULL) {
+			bus_dmamap_sync(ring->data_dmat, data->map,
+			    BUS_DMASYNC_POSTWRITE);
+			bus_dmamap_unload(ring->data_dmat, data->map);
+			m_freem(data->m);
+			data->m = NULL;
+		}
+
+		if (data->ni != NULL) {
+			ieee80211_free_node(data->ni);
+			data->ni = NULL;
+		}
+
+		desc->flags = 0;
+	}
+
+	bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE);
+
+	ring->queued = 0;
+	ring->cur = ring->next = ring->stat = 0;
+}
+
+static void
+rt2661_free_tx_ring(struct rt2661_softc *sc, struct rt2661_tx_ring *ring)
+{
+	struct rt2661_tx_data *data;
+	int i;
+
+	if (ring->desc != NULL) {
+		bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(ring->desc_dmat, ring->desc_map);
+		bus_dmamem_free(ring->desc_dmat, ring->desc, ring->desc_map);
+	}
+
+	if (ring->desc_dmat != NULL)
+		bus_dma_tag_destroy(ring->desc_dmat);
+
+	if (ring->data != NULL) {
+		for (i = 0; i < ring->count; i++) {
+			data = &ring->data[i];
+
+			if (data->m != NULL) {
+				bus_dmamap_sync(ring->data_dmat, data->map,
+				    BUS_DMASYNC_POSTWRITE);
+				bus_dmamap_unload(ring->data_dmat, data->map);
+				m_freem(data->m);
+			}
+
+			if (data->ni != NULL)
+				ieee80211_free_node(data->ni);
+
+			if (data->map != NULL)
+				bus_dmamap_destroy(ring->data_dmat, data->map);
+		}
+
+		free(ring->data, M_DEVBUF);
+	}
+
+	if (ring->data_dmat != NULL)
+		bus_dma_tag_destroy(ring->data_dmat);
+}
+
+static int
+rt2661_alloc_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring,
+    int count)
+{
+	struct rt2661_rx_desc *desc;
+	struct rt2661_rx_data *data;
+	bus_addr_t physaddr;
+	int i, error;
+
+	ring->count = count;
+	ring->cur = ring->next = 0;
+
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 4, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL,
+	    count * RT2661_RX_DESC_SIZE, 1, count * RT2661_RX_DESC_SIZE,
+	    0, NULL, NULL, &ring->desc_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create desc DMA tag\n");
+		goto fail;
+	}
+
+	error = bus_dmamem_alloc(ring->desc_dmat, (void **)&ring->desc,
+	    BUS_DMA_NOWAIT | BUS_DMA_ZERO, &ring->desc_map);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not allocate DMA memory\n");
+		goto fail;
+	}
+
+	error = bus_dmamap_load(ring->desc_dmat, ring->desc_map, ring->desc,
+	    count * RT2661_RX_DESC_SIZE, rt2661_dma_map_addr, &ring->physaddr,
+	    0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not load desc DMA map\n");
+		goto fail;
+	}
+
+	ring->data = malloc(count * sizeof (struct rt2661_rx_data), M_DEVBUF,
+	    M_NOWAIT | M_ZERO);
+	if (ring->data == NULL) {
+		device_printf(sc->sc_dev, "could not allocate soft data\n");
+		error = ENOMEM;
+		goto fail;
+	}
+
+	/*
+	 * Pre-allocate Rx buffers and populate Rx ring.
+	 */
+	error = bus_dma_tag_create(bus_get_dma_tag(sc->sc_dev), 1, 0, 
+	    BUS_SPACE_MAXADDR_32BIT, BUS_SPACE_MAXADDR, NULL, NULL, MCLBYTES,
+	    1, MCLBYTES, 0, NULL, NULL, &ring->data_dmat);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not create data DMA tag\n");
+		goto fail;
+	}
+
+	for (i = 0; i < count; i++) {
+		desc = &sc->rxq.desc[i];
+		data = &sc->rxq.data[i];
+
+		error = bus_dmamap_create(ring->data_dmat, 0, &data->map);
+		if (error != 0) {
+			device_printf(sc->sc_dev, "could not create DMA map\n");
+			goto fail;
+		}
+
+		data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (data->m == NULL) {
+			device_printf(sc->sc_dev,
+			    "could not allocate rx mbuf\n");
+			error = ENOMEM;
+			goto fail;
+		}
+
+		error = bus_dmamap_load(ring->data_dmat, data->map,
+		    mtod(data->m, void *), MCLBYTES, rt2661_dma_map_addr,
+		    &physaddr, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not load rx buf DMA map");
+			goto fail;
+		}
+
+		desc->flags = htole32(RT2661_RX_BUSY);
+		desc->physaddr = htole32(physaddr);
+	}
+
+	bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE);
+
+	return 0;
+
+fail:	rt2661_free_rx_ring(sc, ring);
+	return error;
+}
+
+static void
+rt2661_reset_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
+{
+	int i;
+
+	for (i = 0; i < ring->count; i++)
+		ring->desc[i].flags = htole32(RT2661_RX_BUSY);
+
+	bus_dmamap_sync(ring->desc_dmat, ring->desc_map, BUS_DMASYNC_PREWRITE);
+
+	ring->cur = ring->next = 0;
+}
+
+static void
+rt2661_free_rx_ring(struct rt2661_softc *sc, struct rt2661_rx_ring *ring)
+{
+	struct rt2661_rx_data *data;
+	int i;
+
+	if (ring->desc != NULL) {
+		bus_dmamap_sync(ring->desc_dmat, ring->desc_map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(ring->desc_dmat, ring->desc_map);
+		bus_dmamem_free(ring->desc_dmat, ring->desc, ring->desc_map);
+	}
+
+	if (ring->desc_dmat != NULL)
+		bus_dma_tag_destroy(ring->desc_dmat);
+
+	if (ring->data != NULL) {
+		for (i = 0; i < ring->count; i++) {
+			data = &ring->data[i];
+
+			if (data->m != NULL) {
+				bus_dmamap_sync(ring->data_dmat, data->map,
+				    BUS_DMASYNC_POSTREAD);
+				bus_dmamap_unload(ring->data_dmat, data->map);
+				m_freem(data->m);
+			}
+
+			if (data->map != NULL)
+				bus_dmamap_destroy(ring->data_dmat, data->map);
+		}
+
+		free(ring->data, M_DEVBUF);
+	}
+
+	if (ring->data_dmat != NULL)
+		bus_dma_tag_destroy(ring->data_dmat);
+}
+
+static struct ieee80211_node *
+rt2661_node_alloc(struct ieee80211_node_table *nt)
+{
+	struct rt2661_node *rn;
+
+	rn = malloc(sizeof (struct rt2661_node), M_80211_NODE,
+	    M_NOWAIT | M_ZERO);
+
+	return (rn != NULL) ? &rn->ni : NULL;
+}
+
+static int
+rt2661_media_change(struct ifnet *ifp)
+{
+	struct rt2661_softc *sc = ifp->if_softc;
+	int error;
+
+	error = ieee80211_media_change(ifp);
+	if (error != ENETRESET)
+		return error;
+
+	if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING))
+		rt2661_init(sc);
+
+	return 0;
+}
+
+/*
+ * This function is called for each node present in the node station table.
+ */
+static void
+rt2661_iter_func(void *arg, struct ieee80211_node *ni)
+{
+	struct rt2661_node *rn = (struct rt2661_node *)ni;
+
+	ral_rssadapt_updatestats(&rn->rssadapt);
+}
+
+/*
+ * This function is called periodically (every 100ms) in RUN state to update
+ * the rate adaptation statistics.
+ */
+static void
+rt2661_update_rssadapt(void *arg)
+{
+	struct rt2661_softc *sc = arg;
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	RAL_LOCK(sc);
+
+	ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg);
+	callout_reset(&sc->rssadapt_ch, hz / 10, rt2661_update_rssadapt, sc);
+
+	RAL_UNLOCK(sc);
+}
+
+static int
+rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg)
+{
+	struct rt2661_softc *sc = ic->ic_ifp->if_softc;
+	enum ieee80211_state ostate;
+	struct ieee80211_node *ni;
+	uint32_t tmp;
+	int error = 0;
+
+	ostate = ic->ic_state;
+
+	switch (nstate) {
+	case IEEE80211_S_INIT:
+		callout_stop(&sc->rssadapt_ch);
+
+		if (ostate == IEEE80211_S_RUN) {
+			/* abort TSF synchronization */
+			tmp = RAL_READ(sc, RT2661_TXRX_CSR9);
+			RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff);
+		}
+		break;
+	case IEEE80211_S_RUN:
+		ni = ic->ic_bss;
+
+		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+			rt2661_enable_mrr(sc);
+			rt2661_set_txpreamble(sc);
+			rt2661_set_basicrates(sc, &ni->ni_rates);
+			rt2661_set_bssid(sc, ni->ni_bssid);
+		}
+
+		if (ic->ic_opmode == IEEE80211_M_HOSTAP ||
+		    ic->ic_opmode == IEEE80211_M_IBSS) {
+			if ((error = rt2661_prepare_beacon(sc)) != 0)
+				break;
+		}
+
+		if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+			callout_reset(&sc->rssadapt_ch, hz / 10,
+			    rt2661_update_rssadapt, sc);
+			rt2661_enable_tsf_sync(sc);
+		}
+		break;
+	case IEEE80211_S_SCAN:
+	case IEEE80211_S_AUTH:
+	case IEEE80211_S_ASSOC:
+	default:
+		break;
+	}	
+
+	return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg);
+}
+
+/*
+ * Read 16 bits at address 'addr' from the serial EEPROM (either 93C46 or
+ * 93C66).
+ */
+static uint16_t
+rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr)
+{
+	uint32_t tmp;
+	uint16_t val;
+	int n;
+
+	/* clock C once before the first command */
+	RT2661_EEPROM_CTL(sc, 0);
+
+	RT2661_EEPROM_CTL(sc, RT2661_S);
+	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
+	RT2661_EEPROM_CTL(sc, RT2661_S);
+
+	/* write start bit (1) */
+	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
+	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
+
+	/* write READ opcode (10) */
+	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D);
+	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_D | RT2661_C);
+	RT2661_EEPROM_CTL(sc, RT2661_S);
+	RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
+
+	/* write address (A5-A0 or A7-A0) */
+	n = (RAL_READ(sc, RT2661_E2PROM_CSR) & RT2661_93C46) ? 5 : 7;
+	for (; n >= 0; n--) {
+		RT2661_EEPROM_CTL(sc, RT2661_S |
+		    (((addr >> n) & 1) << RT2661_SHIFT_D));
+		RT2661_EEPROM_CTL(sc, RT2661_S |
+		    (((addr >> n) & 1) << RT2661_SHIFT_D) | RT2661_C);
+	}
+
+	RT2661_EEPROM_CTL(sc, RT2661_S);
+
+	/* read data Q15-Q0 */
+	val = 0;
+	for (n = 15; n >= 0; n--) {
+		RT2661_EEPROM_CTL(sc, RT2661_S | RT2661_C);
+		tmp = RAL_READ(sc, RT2661_E2PROM_CSR);
+		val |= ((tmp & RT2661_Q) >> RT2661_SHIFT_Q) << n;
+		RT2661_EEPROM_CTL(sc, RT2661_S);
+	}
+
+	RT2661_EEPROM_CTL(sc, 0);
+
+	/* clear Chip Select and clock C */
+	RT2661_EEPROM_CTL(sc, RT2661_S);
+	RT2661_EEPROM_CTL(sc, 0);
+	RT2661_EEPROM_CTL(sc, RT2661_C);
+
+	return val;
+}
+
+static void
+rt2661_tx_intr(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2661_tx_ring *txq;
+	struct rt2661_tx_data *data;
+	struct rt2661_node *rn;
+	uint32_t val;
+	int qid, retrycnt;
+
+	for (;;) {
+		struct ieee80211_node *ni;
+		struct mbuf *m;
+
+		val = RAL_READ(sc, RT2661_STA_CSR4);
+		if (!(val & RT2661_TX_STAT_VALID))
+			break;
+
+		/* retrieve the queue in which this frame was sent */
+		qid = RT2661_TX_QID(val);
+		txq = (qid <= 3) ? &sc->txq[qid] : &sc->mgtq;
+
+		/* retrieve rate control algorithm context */
+		data = &txq->data[txq->stat];
+		m = data->m;
+		data->m = NULL;
+		ni = data->ni;
+		data->ni = NULL;
+
+		/* if no frame has been sent, ignore */
+		if (ni == NULL)
+			continue;
+
+		rn = (struct rt2661_node *)ni;
+
+		switch (RT2661_TX_RESULT(val)) {
+		case RT2661_TX_SUCCESS:
+			retrycnt = RT2661_TX_RETRYCNT(val);
+
+			DPRINTFN(10, ("data frame sent successfully after "
+			    "%d retries\n", retrycnt));
+			if (retrycnt == 0 && data->id.id_node != NULL) {
+				ral_rssadapt_raise_rate(ic, &rn->rssadapt,
+				    &data->id);
+			}
+			ifp->if_opackets++;
+			break;
+
+		case RT2661_TX_RETRY_FAIL:
+			DPRINTFN(9, ("sending data frame failed (too much "
+			    "retries)\n"));
+			if (data->id.id_node != NULL) {
+				ral_rssadapt_lower_rate(ic, ni,
+				    &rn->rssadapt, &data->id);
+			}
+			ifp->if_oerrors++;
+			break;
+
+		default:
+			/* other failure */
+			device_printf(sc->sc_dev,
+			    "sending data frame failed 0x%08x\n", val);
+			ifp->if_oerrors++;
+		}
+
+		DPRINTFN(15, ("tx done q=%d idx=%u\n", qid, txq->stat));
+
+		txq->queued--;
+		if (++txq->stat >= txq->count)	/* faster than % count */
+			txq->stat = 0;
+
+		if (m->m_flags & M_TXCB)
+			ieee80211_process_callback(ni, m,
+				RT2661_TX_RESULT(val) != RT2661_TX_SUCCESS);
+		m_freem(m);
+		ieee80211_free_node(ni);
+	}
+
+	sc->sc_tx_timer = 0;
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	rt2661_start(ifp);
+}
+
+static void
+rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq)
+{
+	struct rt2661_tx_desc *desc;
+	struct rt2661_tx_data *data;
+
+	bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_POSTREAD);
+
+	for (;;) {
+		desc = &txq->desc[txq->next];
+		data = &txq->data[txq->next];
+
+		if ((le32toh(desc->flags) & RT2661_TX_BUSY) ||
+		    !(le32toh(desc->flags) & RT2661_TX_VALID))
+			break;
+
+		bus_dmamap_sync(txq->data_dmat, data->map,
+		    BUS_DMASYNC_POSTWRITE);
+		bus_dmamap_unload(txq->data_dmat, data->map);
+
+		/* descriptor is no longer valid */
+		desc->flags &= ~htole32(RT2661_TX_VALID);
+
+		DPRINTFN(15, ("tx dma done q=%p idx=%u\n", txq, txq->next));
+
+		if (++txq->next >= txq->count)	/* faster than % count */
+			txq->next = 0;
+	}
+
+	bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE);
+}
+
+static void
+rt2661_rx_intr(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2661_rx_desc *desc;
+	struct rt2661_rx_data *data;
+	bus_addr_t physaddr;
+	struct ieee80211_frame *wh;
+	struct ieee80211_node *ni;
+	struct rt2661_node *rn;
+	struct mbuf *mnew, *m;
+	int error;
+
+	bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map,
+	    BUS_DMASYNC_POSTREAD);
+
+	for (;;) {
+		int rssi;
+
+		desc = &sc->rxq.desc[sc->rxq.cur];
+		data = &sc->rxq.data[sc->rxq.cur];
+
+		if (le32toh(desc->flags) & RT2661_RX_BUSY)
+			break;
+
+		if ((le32toh(desc->flags) & RT2661_RX_PHY_ERROR) ||
+		    (le32toh(desc->flags) & RT2661_RX_CRC_ERROR)) {
+			/*
+			 * This should not happen since we did not request
+			 * to receive those frames when we filled TXRX_CSR0.
+			 */
+			DPRINTFN(5, ("PHY or CRC error flags 0x%08x\n",
+			    le32toh(desc->flags)));
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		if ((le32toh(desc->flags) & RT2661_RX_CIPHER_MASK) != 0) {
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		/*
+		 * Try to allocate a new mbuf for this ring element and load it
+		 * before processing the current mbuf. If the ring element
+		 * cannot be loaded, drop the received packet and reuse the old
+		 * mbuf. In the unlikely case that the old mbuf can't be
+		 * reloaded either, explicitly panic.
+		 */
+		mnew = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR);
+		if (mnew == NULL) {
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		bus_dmamap_sync(sc->rxq.data_dmat, data->map,
+		    BUS_DMASYNC_POSTREAD);
+		bus_dmamap_unload(sc->rxq.data_dmat, data->map);
+
+		error = bus_dmamap_load(sc->rxq.data_dmat, data->map,
+		    mtod(mnew, void *), MCLBYTES, rt2661_dma_map_addr,
+		    &physaddr, 0);
+		if (error != 0) {
+			m_freem(mnew);
+
+			/* try to reload the old mbuf */
+			error = bus_dmamap_load(sc->rxq.data_dmat, data->map,
+			    mtod(data->m, void *), MCLBYTES,
+			    rt2661_dma_map_addr, &physaddr, 0);
+			if (error != 0) {
+				/* very unlikely that it will fail... */
+				panic("%s: could not load old rx mbuf",
+				    device_get_name(sc->sc_dev));
+			}
+			ifp->if_ierrors++;
+			goto skip;
+		}
+
+		/*
+	 	 * New mbuf successfully loaded, update Rx ring and continue
+		 * processing.
+		 */
+		m = data->m;
+		data->m = mnew;
+		desc->physaddr = htole32(physaddr);
+
+		/* finalize mbuf */
+		m->m_pkthdr.rcvif = ifp;
+		m->m_pkthdr.len = m->m_len =
+		    (le32toh(desc->flags) >> 16) & 0xfff;
+
+		rssi = rt2661_get_rssi(sc, desc->rssi);
+
+		if (bpf_peers_present(sc->sc_drvbpf)) {
+			struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap;
+			uint32_t tsf_lo, tsf_hi;
+
+			/* get timestamp (low and high 32 bits) */
+			tsf_hi = RAL_READ(sc, RT2661_TXRX_CSR13);
+			tsf_lo = RAL_READ(sc, RT2661_TXRX_CSR12);
+
+			tap->wr_tsf =
+			    htole64(((uint64_t)tsf_hi << 32) | tsf_lo);
+			tap->wr_flags = 0;
+			tap->wr_rate = rt2661_rxrate(desc);
+			tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq);
+			tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags);
+			tap->wr_antsignal = rssi < 0 ? 0 : rssi;
+
+			bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m);
+		}
+		sc->sc_flags |= RAL_INPUT_RUNNING;
+		RAL_UNLOCK(sc);
+		wh = mtod(m, struct ieee80211_frame *);
+		ni = ieee80211_find_rxnode(ic,
+		    (struct ieee80211_frame_min *)wh);
+
+		/* Error happened during RSSI conversion. */
+		if (rssi < 0)
+			rssi = ni->ni_rssi;
+
+		/* send the frame to the 802.11 layer */
+		ieee80211_input(ic, m, ni, rssi, RT2661_NOISE_FLOOR, 0);
+
+		/* give rssi to the rate adatation algorithm */
+		rn = (struct rt2661_node *)ni;
+		RAL_LOCK(sc);
+		sc->sc_flags &= ~RAL_INPUT_RUNNING;
+		ral_rssadapt_input(ic, ni, &rn->rssadapt, rssi);
+
+		/* node is no longer needed */
+		ieee80211_free_node(ni);
+
+skip:		desc->flags |= htole32(RT2661_RX_BUSY);
+
+		DPRINTFN(15, ("rx intr idx=%u\n", sc->rxq.cur));
+
+		sc->rxq.cur = (sc->rxq.cur + 1) % RT2661_RX_RING_COUNT;
+	}
+
+	bus_dmamap_sync(sc->rxq.desc_dmat, sc->rxq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+}
+
+/* ARGSUSED */
+static void
+rt2661_mcu_beacon_expire(struct rt2661_softc *sc)
+{
+	/* do nothing */
+}
+
+static void
+rt2661_mcu_wakeup(struct rt2661_softc *sc)
+{
+	RAL_WRITE(sc, RT2661_MAC_CSR11, 5 << 16);
+
+	RAL_WRITE(sc, RT2661_SOFT_RESET_CSR, 0x7);
+	RAL_WRITE(sc, RT2661_IO_CNTL_CSR, 0x18);
+	RAL_WRITE(sc, RT2661_PCI_USEC_CSR, 0x20);
+
+	/* send wakeup command to MCU */
+	rt2661_tx_cmd(sc, RT2661_MCU_CMD_WAKEUP, 0);
+}
+
+static void
+rt2661_mcu_cmd_intr(struct rt2661_softc *sc)
+{
+	RAL_READ(sc, RT2661_M2H_CMD_DONE_CSR);
+	RAL_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
+}
+
+void
+rt2661_intr(void *arg)
+{
+	struct rt2661_softc *sc = arg;
+	struct ifnet *ifp = sc->sc_ifp;
+	uint32_t r1, r2;
+
+	RAL_LOCK(sc);
+
+	/* disable MAC and MCU interrupts */
+	RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffff7f);
+	RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
+
+	/* don't re-enable interrupts if we're shutting down */
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) {
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	r1 = RAL_READ(sc, RT2661_INT_SOURCE_CSR);
+	RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, r1);
+
+	r2 = RAL_READ(sc, RT2661_MCU_INT_SOURCE_CSR);
+	RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, r2);
+
+	if (r1 & RT2661_MGT_DONE)
+		rt2661_tx_dma_intr(sc, &sc->mgtq);
+
+	if (r1 & RT2661_RX_DONE)
+		rt2661_rx_intr(sc);
+
+	if (r1 & RT2661_TX0_DMA_DONE)
+		rt2661_tx_dma_intr(sc, &sc->txq[0]);
+
+	if (r1 & RT2661_TX1_DMA_DONE)
+		rt2661_tx_dma_intr(sc, &sc->txq[1]);
+
+	if (r1 & RT2661_TX2_DMA_DONE)
+		rt2661_tx_dma_intr(sc, &sc->txq[2]);
+
+	if (r1 & RT2661_TX3_DMA_DONE)
+		rt2661_tx_dma_intr(sc, &sc->txq[3]);
+
+	if (r1 & RT2661_TX_DONE)
+		rt2661_tx_intr(sc);
+
+	if (r2 & RT2661_MCU_CMD_DONE)
+		rt2661_mcu_cmd_intr(sc);
+
+	if (r2 & RT2661_MCU_BEACON_EXPIRE)
+		rt2661_mcu_beacon_expire(sc);
+
+	if (r2 & RT2661_MCU_WAKEUP)
+		rt2661_mcu_wakeup(sc);
+
+	/* re-enable MAC and MCU interrupts */
+	RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
+	RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
+
+	RAL_UNLOCK(sc);
+}
+
+/* quickly determine if a given rate is CCK or OFDM */
+#define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22)
+
+#define RAL_ACK_SIZE	14	/* 10 + 4(FCS) */
+#define RAL_CTS_SIZE	14	/* 10 + 4(FCS) */
+
+#define RAL_SIFS	10	/* us */
+
+/*
+ * This function is only used by the Rx radiotap code. It returns the rate at
+ * which a given frame was received.
+ */
+static uint8_t
+rt2661_rxrate(struct rt2661_rx_desc *desc)
+{
+	if (le32toh(desc->flags) & RT2661_RX_OFDM) {
+		/* reverse function of rt2661_plcp_signal */
+		switch (desc->rate & 0xf) {
+		case 0xb:	return 12;
+		case 0xf:	return 18;
+		case 0xa:	return 24;
+		case 0xe:	return 36;
+		case 0x9:	return 48;
+		case 0xd:	return 72;
+		case 0x8:	return 96;
+		case 0xc:	return 108;
+		}
+	} else {
+		if (desc->rate == 10)
+			return 2;
+		if (desc->rate == 20)
+			return 4;
+		if (desc->rate == 55)
+			return 11;
+		if (desc->rate == 110)
+			return 22;
+	}
+	return 2;	/* should not get there */
+}
+
+/*
+ * Return the expected ack rate for a frame transmitted at rate `rate'.
+ * XXX: this should depend on the destination node basic rate set.
+ */
+static int
+rt2661_ack_rate(struct ieee80211com *ic, int rate)
+{
+	switch (rate) {
+	/* CCK rates */
+	case 2:
+		return 2;
+	case 4:
+	case 11:
+	case 22:
+		return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate;
+
+	/* OFDM rates */
+	case 12:
+	case 18:
+		return 12;
+	case 24:
+	case 36:
+		return 24;
+	case 48:
+	case 72:
+	case 96:
+	case 108:
+		return 48;
+	}
+
+	/* default to 1Mbps */
+	return 2;
+}
+
+/*
+ * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'.
+ * The function automatically determines the operating mode depending on the
+ * given rate. `flags' indicates whether short preamble is in use or not.
+ */
+static uint16_t
+rt2661_txtime(int len, int rate, uint32_t flags)
+{
+	uint16_t txtime;
+
+	if (RAL_RATE_IS_OFDM(rate)) {
+		/* IEEE Std 802.11a-1999, pp. 37 */
+		txtime = (8 + 4 * len + 3 + rate - 1) / rate;
+		txtime = 16 + 4 + 4 * txtime + 6;
+	} else {
+		/* IEEE Std 802.11b-1999, pp. 28 */
+		txtime = (16 * len + rate - 1) / rate;
+		if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE))
+			txtime +=  72 + 24;
+		else
+			txtime += 144 + 48;
+	}
+
+	return txtime;
+}
+
+static uint8_t
+rt2661_plcp_signal(int rate)
+{
+	switch (rate) {
+	/* CCK rates (returned values are device-dependent) */
+	case 2:		return 0x0;
+	case 4:		return 0x1;
+	case 11:	return 0x2;
+	case 22:	return 0x3;
+
+	/* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */
+	case 12:	return 0xb;
+	case 18:	return 0xf;
+	case 24:	return 0xa;
+	case 36:	return 0xe;
+	case 48:	return 0x9;
+	case 72:	return 0xd;
+	case 96:	return 0x8;
+	case 108:	return 0xc;
+
+	/* unsupported rates (should not get there) */
+	default:	return 0xff;
+	}
+}
+
+static void
+rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc,
+    uint32_t flags, uint16_t xflags, int len, int rate,
+    const bus_dma_segment_t *segs, int nsegs, int ac)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint16_t plcp_length;
+	int i, remainder;
+
+	desc->flags = htole32(flags);
+	desc->flags |= htole32(len << 16);
+	desc->flags |= htole32(RT2661_TX_BUSY | RT2661_TX_VALID);
+
+	desc->xflags = htole16(xflags);
+	desc->xflags |= htole16(nsegs << 13);
+
+	desc->wme = htole16(
+	    RT2661_QID(ac) |
+	    RT2661_AIFSN(2) |
+	    RT2661_LOGCWMIN(4) |
+	    RT2661_LOGCWMAX(10));
+
+	/*
+	 * Remember in which queue this frame was sent. This field is driver
+	 * private data only. It will be made available by the NIC in STA_CSR4
+	 * on Tx interrupts.
+	 */
+	desc->qid = ac;
+
+	/* setup PLCP fields */
+	desc->plcp_signal  = rt2661_plcp_signal(rate);
+	desc->plcp_service = 4;
+
+	len += IEEE80211_CRC_LEN;
+	if (RAL_RATE_IS_OFDM(rate)) {
+		desc->flags |= htole32(RT2661_TX_OFDM);
+
+		plcp_length = len & 0xfff;
+		desc->plcp_length_hi = plcp_length >> 6;
+		desc->plcp_length_lo = plcp_length & 0x3f;
+	} else {
+		plcp_length = (16 * len + rate - 1) / rate;
+		if (rate == 22) {
+			remainder = (16 * len) % 22;
+			if (remainder != 0 && remainder < 7)
+				desc->plcp_service |= RT2661_PLCP_LENGEXT;
+		}
+		desc->plcp_length_hi = plcp_length >> 8;
+		desc->plcp_length_lo = plcp_length & 0xff;
+
+		if (rate != 2 && (ic->ic_flags & IEEE80211_F_SHPREAMBLE))
+			desc->plcp_signal |= 0x08;
+	}
+
+	/* RT2x61 supports scatter with up to 5 segments */
+	for (i = 0; i < nsegs; i++) {
+		desc->addr[i] = htole32(segs[i].ds_addr);
+		desc->len [i] = htole16(segs[i].ds_len);
+	}
+}
+
+static int
+rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2661_tx_desc *desc;
+	struct rt2661_tx_data *data;
+	struct ieee80211_frame *wh;
+	bus_dma_segment_t segs[RT2661_MAX_SCATTER];
+	uint16_t dur;
+	uint32_t flags = 0;	/* XXX HWSEQ */
+	int nsegs, rate, error;
+
+	desc = &sc->mgtq.desc[sc->mgtq.cur];
+	data = &sc->mgtq.data[sc->mgtq.cur];
+
+	/* send mgt frames at the lowest available rate */
+	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
+
+	error = bus_dmamap_load_mbuf_sg(sc->mgtq.data_dmat, data->map, m0,
+	    segs, &nsegs, 0);
+	if (error != 0) {
+		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
+		    error);
+		m_freem(m0);
+		return error;
+	}
+
+	if (bpf_peers_present(sc->sc_drvbpf)) {
+		struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+
+		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+	}
+
+	data->m = m0;
+	data->ni = ni;
+
+	wh = mtod(m0, struct ieee80211_frame *);
+
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		flags |= RT2661_TX_NEED_ACK;
+
+		dur = rt2661_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) +
+		    RAL_SIFS;
+		*(uint16_t *)wh->i_dur = htole16(dur);
+
+		/* tell hardware to add timestamp in probe responses */
+		if ((wh->i_fc[0] &
+		    (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) ==
+		    (IEEE80211_FC0_TYPE_MGT | IEEE80211_FC0_SUBTYPE_PROBE_RESP))
+			flags |= RT2661_TX_TIMESTAMP;
+	}
+
+	rt2661_setup_tx_desc(sc, desc, flags, 0 /* XXX HWSEQ */,
+	    m0->m_pkthdr.len, rate, segs, nsegs, RT2661_QID_MGT);
+
+	bus_dmamap_sync(sc->mgtq.data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(sc->mgtq.desc_dmat, sc->mgtq.desc_map,
+	    BUS_DMASYNC_PREWRITE);
+
+	DPRINTFN(10, ("sending mgt frame len=%u idx=%u rate=%u\n",
+	    m0->m_pkthdr.len, sc->mgtq.cur, rate));
+
+	/* kick mgt */
+	sc->mgtq.queued++;
+	sc->mgtq.cur = (sc->mgtq.cur + 1) % RT2661_MGT_RING_COUNT;
+	RAL_WRITE(sc, RT2661_TX_CNTL_CSR, RT2661_KICK_MGT);
+
+	return 0;
+}
+
+/*
+ * Build a RTS control frame.
+ */
+static struct mbuf *
+rt2661_get_rts(struct rt2661_softc *sc, struct ieee80211_frame *wh,
+    uint16_t dur)
+{
+	struct ieee80211_frame_rts *rts;
+	struct mbuf *m;
+
+	MGETHDR(m, M_DONTWAIT, MT_DATA);
+	if (m == NULL) {
+		sc->sc_ic.ic_stats.is_tx_nobuf++;
+		device_printf(sc->sc_dev, "could not allocate RTS frame\n");
+		return NULL;
+	}
+
+	rts = mtod(m, struct ieee80211_frame_rts *);
+
+	rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL |
+	    IEEE80211_FC0_SUBTYPE_RTS;
+	rts->i_fc[1] = IEEE80211_FC1_DIR_NODS;
+	*(uint16_t *)rts->i_dur = htole16(dur);
+	IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1);
+	IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2);
+
+	m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts);
+
+	return m;
+}
+
+static int
+rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0,
+    struct ieee80211_node *ni, int ac)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct rt2661_tx_ring *txq = &sc->txq[ac];
+	struct rt2661_tx_desc *desc;
+	struct rt2661_tx_data *data;
+	struct rt2661_node *rn;
+	struct ieee80211_frame *wh;
+	struct ieee80211_key *k;
+	const struct chanAccParams *cap;
+	struct mbuf *mnew;
+	bus_dma_segment_t segs[RT2661_MAX_SCATTER];
+	uint16_t dur;
+	uint32_t flags = 0;
+	int error, nsegs, rate, noack = 0;
+
+	wh = mtod(m0, struct ieee80211_frame *);
+
+	if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) {
+		rate = ic->ic_fixed_rate;
+	} else {
+		struct ieee80211_rateset *rs;
+
+		rs = &ni->ni_rates;
+		rn = (struct rt2661_node *)ni;
+		ni->ni_txrate = ral_rssadapt_choose(&rn->rssadapt, rs,
+		    wh, m0->m_pkthdr.len, NULL, 0);
+		rate = rs->rs_rates[ni->ni_txrate];
+	}
+	rate &= IEEE80211_RATE_VAL;
+
+	if (wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_QOS) {
+		cap = &ic->ic_wme.wme_chanParams;
+		noack = cap->cap_wmeParams[ac].wmep_noackPolicy;
+	}
+
+	if (wh->i_fc[1] & IEEE80211_FC1_WEP) {
+		k = ieee80211_crypto_encap(ic, ni, m0);
+		if (k == NULL) {
+			m_freem(m0);
+			return ENOBUFS;
+		}
+
+		/* packet header may have moved, reset our local pointer */
+		wh = mtod(m0, struct ieee80211_frame *);
+	}
+
+	/*
+	 * IEEE Std 802.11-1999, pp 82: "A STA shall use an RTS/CTS exchange
+	 * for directed frames only when the length of the MPDU is greater
+	 * than the length threshold indicated by [...]" ic_rtsthreshold.
+	 */
+	if (!IEEE80211_IS_MULTICAST(wh->i_addr1) &&
+	    m0->m_pkthdr.len > ic->ic_rtsthreshold) {
+		struct mbuf *m;
+		uint16_t dur;
+		int rtsrate, ackrate;
+
+		rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2;
+		ackrate = rt2661_ack_rate(ic, rate);
+
+		dur = rt2661_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) +
+		      rt2661_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) +
+		      /* XXX: noack (QoS)? */
+		      rt2661_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) +
+		      3 * RAL_SIFS;
+
+		m = rt2661_get_rts(sc, wh, dur);
+
+		desc = &txq->desc[txq->cur];
+		data = &txq->data[txq->cur];
+
+		error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m,
+		    segs, &nsegs, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not map mbuf (error %d)\n", error);
+			m_freem(m);
+			m_freem(m0);
+			return error;
+		}
+
+		/* avoid multiple free() of the same node for each fragment */
+		ieee80211_ref_node(ni);
+
+		data->m = m;
+		data->ni = ni;
+
+		/* RTS frames are not taken into account for rssadapt */
+		data->id.id_node = NULL;
+
+		rt2661_setup_tx_desc(sc, desc, RT2661_TX_NEED_ACK |
+		    RT2661_TX_MORE_FRAG, 0, m->m_pkthdr.len, rtsrate, segs,
+		    nsegs, ac);
+
+		bus_dmamap_sync(txq->data_dmat, data->map,
+		    BUS_DMASYNC_PREWRITE);
+
+		txq->queued++;
+		txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT;
+
+		/*
+		 * IEEE Std 802.11-1999: when an RTS/CTS exchange is used, the
+		 * asynchronous data frame shall be transmitted after the CTS
+		 * frame and a SIFS period.
+		 */
+		flags |= RT2661_TX_LONG_RETRY | RT2661_TX_IFS;
+	}
+
+	data = &txq->data[txq->cur];
+	desc = &txq->desc[txq->cur];
+
+	error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0, segs,
+	    &nsegs, 0);
+	if (error != 0 && error != EFBIG) {
+		device_printf(sc->sc_dev, "could not map mbuf (error %d)\n",
+		    error);
+		m_freem(m0);
+		return error;
+	}
+	if (error != 0) {
+		mnew = m_defrag(m0, M_DONTWAIT);
+		if (mnew == NULL) {
+			device_printf(sc->sc_dev,
+			    "could not defragment mbuf\n");
+			m_freem(m0);
+			return ENOBUFS;
+		}
+		m0 = mnew;
+
+		error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m0,
+		    segs, &nsegs, 0);
+		if (error != 0) {
+			device_printf(sc->sc_dev,
+			    "could not map mbuf (error %d)\n", error);
+			m_freem(m0);
+			return error;
+		}
+
+		/* packet header have moved, reset our local pointer */
+		wh = mtod(m0, struct ieee80211_frame *);
+	}
+
+	if (bpf_peers_present(sc->sc_drvbpf)) {
+		struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap;
+
+		tap->wt_flags = 0;
+		tap->wt_rate = rate;
+		tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq);
+		tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags);
+
+		bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0);
+	}
+
+	data->m = m0;
+	data->ni = ni;
+
+	/* remember link conditions for rate adaptation algorithm */
+	if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) {
+		data->id.id_len = m0->m_pkthdr.len;
+		data->id.id_rateidx = ni->ni_txrate;
+		data->id.id_node = ni;
+		data->id.id_rssi = ni->ni_rssi;
+	} else
+		data->id.id_node = NULL;
+
+	if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) {
+		flags |= RT2661_TX_NEED_ACK;
+
+		dur = rt2661_txtime(RAL_ACK_SIZE, rt2661_ack_rate(ic, rate),
+		    ic->ic_flags) + RAL_SIFS;
+		*(uint16_t *)wh->i_dur = htole16(dur);
+	}
+
+	rt2661_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate, segs,
+	    nsegs, ac);
+
+	bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_PREWRITE);
+	bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE);
+
+	DPRINTFN(10, ("sending data frame len=%u idx=%u rate=%u\n",
+	    m0->m_pkthdr.len, txq->cur, rate));
+
+	/* kick Tx */
+	txq->queued++;
+	txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT;
+	RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 1 << ac);
+
+	return 0;
+}
+
+static void
+rt2661_start(struct ifnet *ifp)
+{
+	struct rt2661_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct mbuf *m0;
+	struct ether_header *eh;
+	struct ieee80211_node *ni;
+	int ac;
+
+	RAL_LOCK(sc);
+
+	/* prevent management frames from being sent if we're not ready */
+	if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid) {
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	for (;;) {
+		IF_POLL(&ic->ic_mgtq, m0);
+		if (m0 != NULL) {
+			if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) {
+				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+				break;
+			}
+			IF_DEQUEUE(&ic->ic_mgtq, m0);
+
+			ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif;
+			m0->m_pkthdr.rcvif = NULL;
+
+			if (bpf_peers_present(ic->ic_rawbpf))
+				bpf_mtap(ic->ic_rawbpf, m0);
+
+			if (rt2661_tx_mgt(sc, m0, ni) != 0) {
+				ieee80211_free_node(ni);
+				break;
+			}
+		} else {
+			if (ic->ic_state != IEEE80211_S_RUN)
+				break;
+
+			IFQ_DRV_DEQUEUE(&ifp->if_snd, m0);
+			if (m0 == NULL)
+				break;
+			/*
+			 * Cancel any background scan.
+			 */
+			if (ic->ic_flags & IEEE80211_F_SCAN)
+				ieee80211_cancel_scan(ic);
+
+			if (m0->m_len < sizeof (struct ether_header) &&
+			    !(m0 = m_pullup(m0, sizeof (struct ether_header))))
+				continue;
+
+			eh = mtod(m0, struct ether_header *);
+			ni = ieee80211_find_txnode(ic, eh->ether_dhost);
+			if (ni == NULL) {
+				m_freem(m0);
+				ifp->if_oerrors++;
+				continue;
+			}
+
+			/* classify mbuf so we can find which tx ring to use */
+			if (ieee80211_classify(ic, m0, ni) != 0) {
+				m_freem(m0);
+				ieee80211_free_node(ni);
+				ifp->if_oerrors++;
+				continue;
+			}
+
+			/* no QoS encapsulation for EAPOL frames */
+			ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ?
+			    M_WME_GETAC(m0) : WME_AC_BE;
+
+			if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) {
+				/* there is no place left in this ring */
+				IFQ_DRV_PREPEND(&ifp->if_snd, m0);
+				ifp->if_drv_flags |= IFF_DRV_OACTIVE;
+				ieee80211_free_node(ni);
+				break;
+			}
+
+			BPF_MTAP(ifp, m0);
+
+			m0 = ieee80211_encap(ic, m0, ni);
+			if (m0 == NULL) {
+				ieee80211_free_node(ni);
+				ifp->if_oerrors++;
+				continue;
+			}
+
+			if (bpf_peers_present(ic->ic_rawbpf))
+				bpf_mtap(ic->ic_rawbpf, m0);
+
+			if (rt2661_tx_data(sc, m0, ni, ac) != 0) {
+				ieee80211_free_node(ni);
+				ifp->if_oerrors++;
+				break;
+			}
+		}
+
+		sc->sc_tx_timer = 5;
+		ic->ic_lastdata = ticks;
+		callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
+	}
+
+	RAL_UNLOCK(sc);
+}
+
+static void
+rt2661_watchdog(void *arg)
+{
+	struct rt2661_softc *sc = (struct rt2661_softc *)arg;
+
+	if (sc->sc_tx_timer > 0 && !sc->sc_invalid) {
+		if (--sc->sc_tx_timer == 0) {
+			device_printf(sc->sc_dev, "device timeout\n");
+			rt2661_init(sc);
+			sc->sc_ifp->if_oerrors++;
+			return;
+		}
+		callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc);
+	}
+}
+
+/*
+ * This function allows for fast channel switching in monitor mode (used by
+ * net-mgmt/kismet). In IBSS mode, we must explicitly reset the interface to
+ * generate a new beacon frame.
+ */
+static int
+rt2661_reset(struct ifnet *ifp)
+{
+	struct rt2661_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+
+	if (ic->ic_opmode != IEEE80211_M_MONITOR)
+		return ENETRESET;
+
+	rt2661_set_chan(sc, ic->ic_curchan);
+
+	return 0;
+}
+
+static int
+rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data)
+{
+	struct rt2661_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	int error = 0;
+
+	switch (cmd) {
+	case SIOCSIFFLAGS:
+		if (ifp->if_flags & IFF_UP) {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+				rt2661_update_promisc(sc);
+			else
+				rt2661_init(sc);
+		} else {
+			if (ifp->if_drv_flags & IFF_DRV_RUNNING)
+				rt2661_stop(sc);
+		}
+		break;
+
+	default:
+		error = ieee80211_ioctl(ic, cmd, data);
+	}
+
+	if (error == ENETRESET) {
+		if ((ifp->if_flags & IFF_UP) &&
+		    (ifp->if_drv_flags & IFF_DRV_RUNNING) &&
+		    (ic->ic_roaming != IEEE80211_ROAMING_MANUAL))
+			rt2661_init(sc);
+		error = 0;
+	}
+
+	return error;
+}
+
+static void
+rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val)
+{
+	uint32_t tmp;
+	int ntries;
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (!(RAL_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
+			break;
+		DELAY(1);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "could not write to BBP\n");
+		return;
+	}
+
+	tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val;
+	RAL_WRITE(sc, RT2661_PHY_CSR3, tmp);
+
+	DPRINTFN(15, ("BBP R%u <- 0x%02x\n", reg, val));
+}
+
+static uint8_t
+rt2661_bbp_read(struct rt2661_softc *sc, uint8_t reg)
+{
+	uint32_t val;
+	int ntries;
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (!(RAL_READ(sc, RT2661_PHY_CSR3) & RT2661_BBP_BUSY))
+			break;
+		DELAY(1);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "could not read from BBP\n");
+		return 0;
+	}
+
+	val = RT2661_BBP_BUSY | RT2661_BBP_READ | reg << 8;
+	RAL_WRITE(sc, RT2661_PHY_CSR3, val);
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		val = RAL_READ(sc, RT2661_PHY_CSR3);
+		if (!(val & RT2661_BBP_BUSY))
+			return val & 0xff;
+		DELAY(1);
+	}
+
+	device_printf(sc->sc_dev, "could not read from BBP\n");
+	return 0;
+}
+
+static void
+rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val)
+{
+	uint32_t tmp;
+	int ntries;
+
+	for (ntries = 0; ntries < 100; ntries++) {
+		if (!(RAL_READ(sc, RT2661_PHY_CSR4) & RT2661_RF_BUSY))
+			break;
+		DELAY(1);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "could not write to RF\n");
+		return;
+	}
+
+	tmp = RT2661_RF_BUSY | RT2661_RF_21BIT | (val & 0x1fffff) << 2 |
+	    (reg & 3);
+	RAL_WRITE(sc, RT2661_PHY_CSR4, tmp);
+
+	/* remember last written value in sc */
+	sc->rf_regs[reg] = val;
+
+	DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff));
+}
+
+static int
+rt2661_tx_cmd(struct rt2661_softc *sc, uint8_t cmd, uint16_t arg)
+{
+	if (RAL_READ(sc, RT2661_H2M_MAILBOX_CSR) & RT2661_H2M_BUSY)
+		return EIO;	/* there is already a command pending */
+
+	RAL_WRITE(sc, RT2661_H2M_MAILBOX_CSR,
+	    RT2661_H2M_BUSY | RT2661_TOKEN_NO_INTR << 16 | arg);
+
+	RAL_WRITE(sc, RT2661_HOST_CMD_CSR, RT2661_KICK_CMD | cmd);
+
+	return 0;
+}
+
+static void
+rt2661_select_antenna(struct rt2661_softc *sc)
+{
+	uint8_t bbp4, bbp77;
+	uint32_t tmp;
+
+	bbp4  = rt2661_bbp_read(sc,  4);
+	bbp77 = rt2661_bbp_read(sc, 77);
+
+	/* TBD */
+
+	/* make sure Rx is disabled before switching antenna */
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
+	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
+
+	rt2661_bbp_write(sc,  4, bbp4);
+	rt2661_bbp_write(sc, 77, bbp77);
+
+	/* restore Rx filter */
+	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
+}
+
+/*
+ * Enable multi-rate retries for frames sent at OFDM rates.
+ * In 802.11b/g mode, allow fallback to CCK rates.
+ */
+static void
+rt2661_enable_mrr(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint32_t tmp;
+
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
+
+	tmp &= ~RT2661_MRR_CCK_FALLBACK;
+	if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan))
+		tmp |= RT2661_MRR_CCK_FALLBACK;
+	tmp |= RT2661_MRR_ENABLED;
+
+	RAL_WRITE(sc, RT2661_TXRX_CSR4, tmp);
+}
+
+static void
+rt2661_set_txpreamble(struct rt2661_softc *sc)
+{
+	uint32_t tmp;
+
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR4);
+
+	tmp &= ~RT2661_SHORT_PREAMBLE;
+	if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE)
+		tmp |= RT2661_SHORT_PREAMBLE;
+
+	RAL_WRITE(sc, RT2661_TXRX_CSR4, tmp);
+}
+
+/*
+ * Supported rates for 802.11g. XXX should use ic_sup_rates.
+ */
+static const struct ieee80211_rateset rt2661_rateset_11g =
+	{ 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } };
+
+static void
+rt2661_set_basicrates(struct rt2661_softc *sc,
+    const struct ieee80211_rateset *rs)
+{
+#define RV(r)	((r) & IEEE80211_RATE_VAL)
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint32_t mask = 0;
+	uint8_t rate;
+	int i, j;
+
+	for (i = 0; i < rs->rs_nrates; i++) {
+		rate = rs->rs_rates[i];
+
+		if (!(rate & IEEE80211_RATE_BASIC))
+			continue;
+
+		/*
+		 * Find h/w rate index.  We know it exists because the rate
+		 * set has already been negotiated.
+		 */
+		for (j = 0; ic->ic_sup_rates[IEEE80211_MODE_11G].rs_rates[j] != RV(rate); j++);
+
+		mask |= 1 << j;
+	}
+
+	RAL_WRITE(sc, RT2661_TXRX_CSR5, mask);
+
+	DPRINTF(("Setting basic rate mask to 0x%x\n", mask));
+#undef RV
+}
+
+/*
+ * Reprogram MAC/BBP to switch to a new band.  Values taken from the reference
+ * driver.
+ */
+static void
+rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c)
+{
+	uint8_t bbp17, bbp35, bbp96, bbp97, bbp98, bbp104;
+	uint32_t tmp;
+
+	/* update all BBP registers that depend on the band */
+	bbp17 = 0x20; bbp96 = 0x48; bbp104 = 0x2c;
+	bbp35 = 0x50; bbp97 = 0x48; bbp98  = 0x48;
+	if (IEEE80211_IS_CHAN_5GHZ(c)) {
+		bbp17 += 0x08; bbp96 += 0x10; bbp104 += 0x0c;
+		bbp35 += 0x10; bbp97 += 0x10; bbp98  += 0x10;
+	}
+	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
+	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
+		bbp17 += 0x10; bbp96 += 0x10; bbp104 += 0x10;
+	}
+
+	rt2661_bbp_write(sc,  17, bbp17);
+	rt2661_bbp_write(sc,  96, bbp96);
+	rt2661_bbp_write(sc, 104, bbp104);
+
+	if ((IEEE80211_IS_CHAN_2GHZ(c) && sc->ext_2ghz_lna) ||
+	    (IEEE80211_IS_CHAN_5GHZ(c) && sc->ext_5ghz_lna)) {
+		rt2661_bbp_write(sc, 75, 0x80);
+		rt2661_bbp_write(sc, 86, 0x80);
+		rt2661_bbp_write(sc, 88, 0x80);
+	}
+
+	rt2661_bbp_write(sc, 35, bbp35);
+	rt2661_bbp_write(sc, 97, bbp97);
+	rt2661_bbp_write(sc, 98, bbp98);
+
+	tmp = RAL_READ(sc, RT2661_PHY_CSR0);
+	tmp &= ~(RT2661_PA_PE_2GHZ | RT2661_PA_PE_5GHZ);
+	if (IEEE80211_IS_CHAN_2GHZ(c))
+		tmp |= RT2661_PA_PE_2GHZ;
+	else
+		tmp |= RT2661_PA_PE_5GHZ;
+	RAL_WRITE(sc, RT2661_PHY_CSR0, tmp);
+}
+
+static void
+rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	const struct rfprog *rfprog;
+	uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT;
+	int8_t power;
+	u_int i, chan;
+
+	chan = ieee80211_chan2ieee(ic, c);
+	if (chan == 0 || chan == IEEE80211_CHAN_ANY)
+		return;
+
+	/* select the appropriate RF settings based on what EEPROM says */
+	rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2;
+
+	/* find the settings for this channel (we know it exists) */
+	for (i = 0; rfprog[i].chan != chan; i++);
+
+	power = sc->txpow[i];
+	if (power < 0) {
+		bbp94 += power;
+		power = 0;
+	} else if (power > 31) {
+		bbp94 += power - 31;
+		power = 31;
+	}
+
+	/*
+	 * If we are switching from the 2GHz band to the 5GHz band or
+	 * vice-versa, BBP registers need to be reprogrammed.
+	 */
+	if (c->ic_flags != sc->sc_curchan->ic_flags) {
+		rt2661_select_band(sc, c);
+		rt2661_select_antenna(sc);
+	}
+	sc->sc_curchan = c;
+
+	rt2661_rf_write(sc, RAL_RF1, rfprog[i].r1);
+	rt2661_rf_write(sc, RAL_RF2, rfprog[i].r2);
+	rt2661_rf_write(sc, RAL_RF3, rfprog[i].r3 | power << 7);
+	rt2661_rf_write(sc, RAL_RF4, rfprog[i].r4 | sc->rffreq << 10);
+
+	DELAY(200);
+
+	rt2661_rf_write(sc, RAL_RF1, rfprog[i].r1);
+	rt2661_rf_write(sc, RAL_RF2, rfprog[i].r2);
+	rt2661_rf_write(sc, RAL_RF3, rfprog[i].r3 | power << 7 | 1);
+	rt2661_rf_write(sc, RAL_RF4, rfprog[i].r4 | sc->rffreq << 10);
+
+	DELAY(200);
+
+	rt2661_rf_write(sc, RAL_RF1, rfprog[i].r1);
+	rt2661_rf_write(sc, RAL_RF2, rfprog[i].r2);
+	rt2661_rf_write(sc, RAL_RF3, rfprog[i].r3 | power << 7);
+	rt2661_rf_write(sc, RAL_RF4, rfprog[i].r4 | sc->rffreq << 10);
+
+	/* enable smart mode for MIMO-capable RFs */
+	bbp3 = rt2661_bbp_read(sc, 3);
+
+	bbp3 &= ~RT2661_SMART_MODE;
+	if (sc->rf_rev == RT2661_RF_5325 || sc->rf_rev == RT2661_RF_2529)
+		bbp3 |= RT2661_SMART_MODE;
+
+	rt2661_bbp_write(sc, 3, bbp3);
+
+	if (bbp94 != RT2661_BBPR94_DEFAULT)
+		rt2661_bbp_write(sc, 94, bbp94);
+
+	/* 5GHz radio needs a 1ms delay here */
+	if (IEEE80211_IS_CHAN_5GHZ(c))
+		DELAY(1000);
+}
+
+static void
+rt2661_set_bssid(struct rt2661_softc *sc, const uint8_t *bssid)
+{
+	uint32_t tmp;
+
+	tmp = bssid[0] | bssid[1] << 8 | bssid[2] << 16 | bssid[3] << 24;
+	RAL_WRITE(sc, RT2661_MAC_CSR4, tmp);
+
+	tmp = bssid[4] | bssid[5] << 8 | RT2661_ONE_BSSID << 16;
+	RAL_WRITE(sc, RT2661_MAC_CSR5, tmp);
+}
+
+static void
+rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr)
+{
+	uint32_t tmp;
+
+	tmp = addr[0] | addr[1] << 8 | addr[2] << 16 | addr[3] << 24;
+	RAL_WRITE(sc, RT2661_MAC_CSR2, tmp);
+
+	tmp = addr[4] | addr[5] << 8;
+	RAL_WRITE(sc, RT2661_MAC_CSR3, tmp);
+}
+
+static void
+rt2661_update_promisc(struct rt2661_softc *sc)
+{
+	struct ifnet *ifp = sc->sc_ic.ic_ifp;
+	uint32_t tmp;
+
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
+
+	tmp &= ~RT2661_DROP_NOT_TO_ME;
+	if (!(ifp->if_flags & IFF_PROMISC))
+		tmp |= RT2661_DROP_NOT_TO_ME;
+
+	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
+
+	DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ?
+	    "entering" : "leaving"));
+}
+
+/*
+ * Update QoS (802.11e) settings for each h/w Tx ring.
+ */
+static int
+rt2661_wme_update(struct ieee80211com *ic)
+{
+	struct rt2661_softc *sc = ic->ic_ifp->if_softc;
+	const struct wmeParams *wmep;
+
+	wmep = ic->ic_wme.wme_chanParams.cap_wmeParams;
+
+	/* XXX: not sure about shifts. */
+	/* XXX: the reference driver plays with AC_VI settings too. */
+
+	/* update TxOp */
+	RAL_WRITE(sc, RT2661_AC_TXOP_CSR0,
+	    wmep[WME_AC_BE].wmep_txopLimit << 16 |
+	    wmep[WME_AC_BK].wmep_txopLimit);
+	RAL_WRITE(sc, RT2661_AC_TXOP_CSR1,
+	    wmep[WME_AC_VI].wmep_txopLimit << 16 |
+	    wmep[WME_AC_VO].wmep_txopLimit);
+
+	/* update CWmin */
+	RAL_WRITE(sc, RT2661_CWMIN_CSR,
+	    wmep[WME_AC_BE].wmep_logcwmin << 12 |
+	    wmep[WME_AC_BK].wmep_logcwmin <<  8 |
+	    wmep[WME_AC_VI].wmep_logcwmin <<  4 |
+	    wmep[WME_AC_VO].wmep_logcwmin);
+
+	/* update CWmax */
+	RAL_WRITE(sc, RT2661_CWMAX_CSR,
+	    wmep[WME_AC_BE].wmep_logcwmax << 12 |
+	    wmep[WME_AC_BK].wmep_logcwmax <<  8 |
+	    wmep[WME_AC_VI].wmep_logcwmax <<  4 |
+	    wmep[WME_AC_VO].wmep_logcwmax);
+
+	/* update Aifsn */
+	RAL_WRITE(sc, RT2661_AIFSN_CSR,
+	    wmep[WME_AC_BE].wmep_aifsn << 12 |
+	    wmep[WME_AC_BK].wmep_aifsn <<  8 |
+	    wmep[WME_AC_VI].wmep_aifsn <<  4 |
+	    wmep[WME_AC_VO].wmep_aifsn);
+
+	return 0;
+}
+
+static void
+rt2661_update_slot(struct ifnet *ifp)
+{
+	struct rt2661_softc *sc = ifp->if_softc;
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint8_t slottime;
+	uint32_t tmp;
+
+	slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20;
+
+	tmp = RAL_READ(sc, RT2661_MAC_CSR9);
+	tmp = (tmp & ~0xff) | slottime;
+	RAL_WRITE(sc, RT2661_MAC_CSR9, tmp);
+}
+
+static const char *
+rt2661_get_rf(int rev)
+{
+	switch (rev) {
+	case RT2661_RF_5225:	return "RT5225";
+	case RT2661_RF_5325:	return "RT5325 (MIMO XR)";
+	case RT2661_RF_2527:	return "RT2527";
+	case RT2661_RF_2529:	return "RT2529 (MIMO XR)";
+	default:		return "unknown";
+	}
+}
+
+static void
+rt2661_read_eeprom(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint16_t val;
+	int i;
+
+	/* read MAC address */
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC01);
+	ic->ic_myaddr[0] = val & 0xff;
+	ic->ic_myaddr[1] = val >> 8;
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC23);
+	ic->ic_myaddr[2] = val & 0xff;
+	ic->ic_myaddr[3] = val >> 8;
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_MAC45);
+	ic->ic_myaddr[4] = val & 0xff;
+	ic->ic_myaddr[5] = val >> 8;
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_ANTENNA);
+	/* XXX: test if different from 0xffff? */
+	sc->rf_rev   = (val >> 11) & 0x1f;
+	sc->hw_radio = (val >> 10) & 0x1;
+	sc->rx_ant   = (val >> 4)  & 0x3;
+	sc->tx_ant   = (val >> 2)  & 0x3;
+	sc->nb_ant   = val & 0x3;
+
+	DPRINTF(("RF revision=%d\n", sc->rf_rev));
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2);
+	sc->ext_5ghz_lna = (val >> 6) & 0x1;
+	sc->ext_2ghz_lna = (val >> 4) & 0x1;
+
+	DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n",
+	    sc->ext_2ghz_lna, sc->ext_5ghz_lna));
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET);
+	if ((val & 0xff) != 0xff)
+		sc->rssi_2ghz_corr = (int8_t)(val & 0xff);	/* signed */
+
+	/* Only [-10, 10] is valid */
+	if (sc->rssi_2ghz_corr < -10 || sc->rssi_2ghz_corr > 10)
+		sc->rssi_2ghz_corr = 0;
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_5GHZ_OFFSET);
+	if ((val & 0xff) != 0xff)
+		sc->rssi_5ghz_corr = (int8_t)(val & 0xff);	/* signed */
+
+	/* Only [-10, 10] is valid */
+	if (sc->rssi_5ghz_corr < -10 || sc->rssi_5ghz_corr > 10)
+		sc->rssi_5ghz_corr = 0;
+
+	/* adjust RSSI correction for external low-noise amplifier */
+	if (sc->ext_2ghz_lna)
+		sc->rssi_2ghz_corr -= 14;
+	if (sc->ext_5ghz_lna)
+		sc->rssi_5ghz_corr -= 14;
+
+	DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n",
+	    sc->rssi_2ghz_corr, sc->rssi_5ghz_corr));
+
+	val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET);
+	if ((val >> 8) != 0xff)
+		sc->rfprog = (val >> 8) & 0x3;
+	if ((val & 0xff) != 0xff)
+		sc->rffreq = val & 0xff;
+
+	DPRINTF(("RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq));
+
+	/* read Tx power for all a/b/g channels */
+	for (i = 0; i < 19; i++) {
+		val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i);
+		sc->txpow[i * 2] = (int8_t)(val >> 8);		/* signed */
+		DPRINTF(("Channel=%d Tx power=%d\n",
+		    rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]));
+		sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff);	/* signed */
+		DPRINTF(("Channel=%d Tx power=%d\n",
+		    rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]));
+	}
+
+	/* read vendor-specific BBP values */
+	for (i = 0; i < 16; i++) {
+		val = rt2661_eeprom_read(sc, RT2661_EEPROM_BBP_BASE + i);
+		if (val == 0 || val == 0xffff)
+			continue;	/* skip invalid entries */
+		sc->bbp_prom[i].reg = val >> 8;
+		sc->bbp_prom[i].val = val & 0xff;
+		DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg,
+		    sc->bbp_prom[i].val));
+	}
+}
+
+static int
+rt2661_bbp_init(struct rt2661_softc *sc)
+{
+#define N(a)	(sizeof (a) / sizeof ((a)[0]))
+	int i, ntries;
+	uint8_t val;
+
+	/* wait for BBP to be ready */
+	for (ntries = 0; ntries < 100; ntries++) {
+		val = rt2661_bbp_read(sc, 0);
+		if (val != 0 && val != 0xff)
+			break;
+		DELAY(100);
+	}
+	if (ntries == 100) {
+		device_printf(sc->sc_dev, "timeout waiting for BBP\n");
+		return EIO;
+	}
+
+	/* initialize BBP registers to default values */
+	for (i = 0; i < N(rt2661_def_bbp); i++) {
+		rt2661_bbp_write(sc, rt2661_def_bbp[i].reg,
+		    rt2661_def_bbp[i].val);
+	}
+
+	/* write vendor-specific BBP values (from EEPROM) */
+	for (i = 0; i < 16; i++) {
+		if (sc->bbp_prom[i].reg == 0)
+			continue;
+		rt2661_bbp_write(sc, sc->bbp_prom[i].reg, sc->bbp_prom[i].val);
+	}
+
+	return 0;
+#undef N
+}
+
+static void
+rt2661_init(void *priv)
+{
+#define N(a)	(sizeof (a) / sizeof ((a)[0]))
+	struct rt2661_softc *sc = priv;
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	uint32_t tmp, sta[3];
+	int i, ntries;
+
+	RAL_LOCK(sc);
+
+	rt2661_stop_locked(sc);
+
+	/* initialize Tx rings */
+	RAL_WRITE(sc, RT2661_AC1_BASE_CSR, sc->txq[1].physaddr);
+	RAL_WRITE(sc, RT2661_AC0_BASE_CSR, sc->txq[0].physaddr);
+	RAL_WRITE(sc, RT2661_AC2_BASE_CSR, sc->txq[2].physaddr);
+	RAL_WRITE(sc, RT2661_AC3_BASE_CSR, sc->txq[3].physaddr);
+
+	/* initialize Mgt ring */
+	RAL_WRITE(sc, RT2661_MGT_BASE_CSR, sc->mgtq.physaddr);
+
+	/* initialize Rx ring */
+	RAL_WRITE(sc, RT2661_RX_BASE_CSR, sc->rxq.physaddr);
+
+	/* initialize Tx rings sizes */
+	RAL_WRITE(sc, RT2661_TX_RING_CSR0,
+	    RT2661_TX_RING_COUNT << 24 |
+	    RT2661_TX_RING_COUNT << 16 |
+	    RT2661_TX_RING_COUNT <<  8 |
+	    RT2661_TX_RING_COUNT);
+
+	RAL_WRITE(sc, RT2661_TX_RING_CSR1,
+	    RT2661_TX_DESC_WSIZE << 16 |
+	    RT2661_TX_RING_COUNT <<  8 |	/* XXX: HCCA ring unused */
+	    RT2661_MGT_RING_COUNT);
+
+	/* initialize Rx rings */
+	RAL_WRITE(sc, RT2661_RX_RING_CSR,
+	    RT2661_RX_DESC_BACK  << 16 |
+	    RT2661_RX_DESC_WSIZE <<  8 |
+	    RT2661_RX_RING_COUNT);
+
+	/* XXX: some magic here */
+	RAL_WRITE(sc, RT2661_TX_DMA_DST_CSR, 0xaa);
+
+	/* load base addresses of all 5 Tx rings (4 data + 1 mgt) */
+	RAL_WRITE(sc, RT2661_LOAD_TX_RING_CSR, 0x1f);
+
+	/* load base address of Rx ring */
+	RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 2);
+
+	/* initialize MAC registers to default values */
+	for (i = 0; i < N(rt2661_def_mac); i++)
+		RAL_WRITE(sc, rt2661_def_mac[i].reg, rt2661_def_mac[i].val);
+
+	IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp));
+	rt2661_set_macaddr(sc, ic->ic_myaddr);
+
+	/* set host ready */
+	RAL_WRITE(sc, RT2661_MAC_CSR1, 3);
+	RAL_WRITE(sc, RT2661_MAC_CSR1, 0);
+
+	/* wait for BBP/RF to wakeup */
+	for (ntries = 0; ntries < 1000; ntries++) {
+		if (RAL_READ(sc, RT2661_MAC_CSR12) & 8)
+			break;
+		DELAY(1000);
+	}
+	if (ntries == 1000) {
+		printf("timeout waiting for BBP/RF to wakeup\n");
+		rt2661_stop_locked(sc);
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	if (rt2661_bbp_init(sc) != 0) {
+		rt2661_stop_locked(sc);
+		RAL_UNLOCK(sc);
+		return;
+	}
+
+	/* select default channel */
+	sc->sc_curchan = ic->ic_curchan;
+	rt2661_select_band(sc, sc->sc_curchan);
+	rt2661_select_antenna(sc);
+	rt2661_set_chan(sc, sc->sc_curchan);
+
+	/* update Rx filter */
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR0) & 0xffff;
+
+	tmp |= RT2661_DROP_PHY_ERROR | RT2661_DROP_CRC_ERROR;
+	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+		tmp |= RT2661_DROP_CTL | RT2661_DROP_VER_ERROR |
+		       RT2661_DROP_ACKCTS;
+		if (ic->ic_opmode != IEEE80211_M_HOSTAP)
+			tmp |= RT2661_DROP_TODS;
+		if (!(ifp->if_flags & IFF_PROMISC))
+			tmp |= RT2661_DROP_NOT_TO_ME;
+	}
+
+	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
+
+	/* clear STA registers */
+	RAL_READ_REGION_4(sc, RT2661_STA_CSR0, sta, N(sta));
+
+	/* initialize ASIC */
+	RAL_WRITE(sc, RT2661_MAC_CSR1, 4);
+
+	/* clear any pending interrupt */
+	RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
+
+	/* enable interrupts */
+	RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0x0000ff10);
+	RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0);
+
+	/* kick Rx */
+	RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1);
+	RAL_UNLOCK(sc);
+
+	ifp->if_drv_flags &= ~IFF_DRV_OACTIVE;
+	ifp->if_drv_flags |= IFF_DRV_RUNNING;
+
+	if (ic->ic_opmode != IEEE80211_M_MONITOR) {
+		if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)
+			ieee80211_new_state(ic, IEEE80211_S_SCAN, -1);
+	} else
+		ieee80211_new_state(ic, IEEE80211_S_RUN, -1);
+
+
+#undef N
+}
+
+void
+rt2661_stop(void *priv)
+{
+	struct rt2661_softc *sc = priv;
+
+	RAL_LOCK(sc);
+	rt2661_stop_locked(sc);
+	RAL_UNLOCK(sc);
+}
+
+void
+rt2661_stop_locked(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ifnet *ifp = ic->ic_ifp;
+	uint32_t tmp;
+	volatile int *flags = &sc->sc_flags;
+
+	while (*flags & RAL_INPUT_RUNNING) {
+		msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10);
+	}
+
+	if (ifp->if_drv_flags & IFF_DRV_RUNNING) {
+		sc->sc_tx_timer = 0;
+		ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE);
+		
+		ieee80211_new_state(ic, IEEE80211_S_INIT, -1);
+		
+		/* abort Tx (for all 5 Tx rings) */
+		RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16);
+		
+		/* disable Rx (value remains after reset!) */
+		tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
+		RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
+		
+		/* reset ASIC */
+		RAL_WRITE(sc, RT2661_MAC_CSR1, 3);
+		RAL_WRITE(sc, RT2661_MAC_CSR1, 0);
+		
+		/* disable interrupts */
+		RAL_WRITE(sc, RT2661_INT_MASK_CSR, 0xffffffff);
+		RAL_WRITE(sc, RT2661_MCU_INT_MASK_CSR, 0xffffffff);
+		
+		/* clear any pending interrupt */
+		RAL_WRITE(sc, RT2661_INT_SOURCE_CSR, 0xffffffff);
+		RAL_WRITE(sc, RT2661_MCU_INT_SOURCE_CSR, 0xffffffff);
+		
+		/* reset Tx and Rx rings */
+		rt2661_reset_tx_ring(sc, &sc->txq[0]);
+		rt2661_reset_tx_ring(sc, &sc->txq[1]);
+		rt2661_reset_tx_ring(sc, &sc->txq[2]);
+		rt2661_reset_tx_ring(sc, &sc->txq[3]);
+		rt2661_reset_tx_ring(sc, &sc->mgtq);
+		rt2661_reset_rx_ring(sc, &sc->rxq);
+	}
+}
+
+static int
+rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode, int size)
+{
+	int ntries;
+
+	/* reset 8051 */
+	RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
+
+	/* cancel any pending Host to MCU command */
+	RAL_WRITE(sc, RT2661_H2M_MAILBOX_CSR, 0);
+	RAL_WRITE(sc, RT2661_M2H_CMD_DONE_CSR, 0xffffffff);
+	RAL_WRITE(sc, RT2661_HOST_CMD_CSR, 0);
+
+	/* write 8051's microcode */
+	RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET | RT2661_MCU_SEL);
+	RAL_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size);
+	RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET);
+
+	/* kick 8051's ass */
+	RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, 0);
+
+	/* wait for 8051 to initialize */
+	for (ntries = 0; ntries < 500; ntries++) {
+		if (RAL_READ(sc, RT2661_MCU_CNTL_CSR) & RT2661_MCU_READY)
+			break;
+		DELAY(100);
+	}
+	if (ntries == 500) {
+		printf("timeout waiting for MCU to initialize\n");
+		return EIO;
+	}
+	return 0;
+}
+
+#ifdef notyet
+/*
+ * Dynamically tune Rx sensitivity (BBP register 17) based on average RSSI and
+ * false CCA count.  This function is called periodically (every seconds) when
+ * in the RUN state.  Values taken from the reference driver.
+ */
+static void
+rt2661_rx_tune(struct rt2661_softc *sc)
+{
+	uint8_t bbp17;
+	uint16_t cca;
+	int lo, hi, dbm;
+
+	/*
+	 * Tuning range depends on operating band and on the presence of an
+	 * external low-noise amplifier.
+	 */
+	lo = 0x20;
+	if (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan))
+		lo += 0x08;
+	if ((IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan) && sc->ext_2ghz_lna) ||
+	    (IEEE80211_IS_CHAN_5GHZ(sc->sc_curchan) && sc->ext_5ghz_lna))
+		lo += 0x10;
+	hi = lo + 0x20;
+
+	/* retrieve false CCA count since last call (clear on read) */
+	cca = RAL_READ(sc, RT2661_STA_CSR1) & 0xffff;
+
+	if (dbm >= -35) {
+		bbp17 = 0x60;
+	} else if (dbm >= -58) {
+		bbp17 = hi;
+	} else if (dbm >= -66) {
+		bbp17 = lo + 0x10;
+	} else if (dbm >= -74) {
+		bbp17 = lo + 0x08;
+	} else {
+		/* RSSI < -74dBm, tune using false CCA count */
+
+		bbp17 = sc->bbp17; /* current value */
+
+		hi -= 2 * (-74 - dbm);
+		if (hi < lo)
+			hi = lo;
+
+		if (bbp17 > hi) {
+			bbp17 = hi;
+
+		} else if (cca > 512) {
+			if (++bbp17 > hi)
+				bbp17 = hi;
+		} else if (cca < 100) {
+			if (--bbp17 < lo)
+				bbp17 = lo;
+		}
+	}
+
+	if (bbp17 != sc->bbp17) {
+		rt2661_bbp_write(sc, 17, bbp17);
+		sc->bbp17 = bbp17;
+	}
+}
+
+/*
+ * Enter/Leave radar detection mode.
+ * This is for 802.11h additional regulatory domains.
+ */
+static void
+rt2661_radar_start(struct rt2661_softc *sc)
+{
+	uint32_t tmp;
+
+	/* disable Rx */
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR0);
+	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp | RT2661_DISABLE_RX);
+
+	rt2661_bbp_write(sc, 82, 0x20);
+	rt2661_bbp_write(sc, 83, 0x00);
+	rt2661_bbp_write(sc, 84, 0x40);
+
+	/* save current BBP registers values */
+	sc->bbp18 = rt2661_bbp_read(sc, 18);
+	sc->bbp21 = rt2661_bbp_read(sc, 21);
+	sc->bbp22 = rt2661_bbp_read(sc, 22);
+	sc->bbp16 = rt2661_bbp_read(sc, 16);
+	sc->bbp17 = rt2661_bbp_read(sc, 17);
+	sc->bbp64 = rt2661_bbp_read(sc, 64);
+
+	rt2661_bbp_write(sc, 18, 0xff);
+	rt2661_bbp_write(sc, 21, 0x3f);
+	rt2661_bbp_write(sc, 22, 0x3f);
+	rt2661_bbp_write(sc, 16, 0xbd);
+	rt2661_bbp_write(sc, 17, sc->ext_5ghz_lna ? 0x44 : 0x34);
+	rt2661_bbp_write(sc, 64, 0x21);
+
+	/* restore Rx filter */
+	RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp);
+}
+
+static int
+rt2661_radar_stop(struct rt2661_softc *sc)
+{
+	uint8_t bbp66;
+
+	/* read radar detection result */
+	bbp66 = rt2661_bbp_read(sc, 66);
+
+	/* restore BBP registers values */
+	rt2661_bbp_write(sc, 16, sc->bbp16);
+	rt2661_bbp_write(sc, 17, sc->bbp17);
+	rt2661_bbp_write(sc, 18, sc->bbp18);
+	rt2661_bbp_write(sc, 21, sc->bbp21);
+	rt2661_bbp_write(sc, 22, sc->bbp22);
+	rt2661_bbp_write(sc, 64, sc->bbp64);
+
+	return bbp66 == 1;
+}
+#endif
+
+static int
+rt2661_prepare_beacon(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	struct ieee80211_beacon_offsets bo;
+	struct rt2661_tx_desc desc;
+	struct mbuf *m0;
+	int rate;
+
+	m0 = ieee80211_beacon_alloc(ic->ic_bss, &bo);
+	if (m0 == NULL) {
+		device_printf(sc->sc_dev, "could not allocate beacon frame\n");
+		return ENOBUFS;
+	}
+
+	/* send beacons at the lowest available rate */
+	rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan) ? 12 : 2;
+
+	rt2661_setup_tx_desc(sc, &desc, RT2661_TX_TIMESTAMP, RT2661_TX_HWSEQ,
+	    m0->m_pkthdr.len, rate, NULL, 0, RT2661_QID_MGT);
+
+	/* copy the first 24 bytes of Tx descriptor into NIC memory */
+	RAL_WRITE_REGION_1(sc, RT2661_HW_BEACON_BASE0, (uint8_t *)&desc, 24);
+
+	/* copy beacon header and payload into NIC memory */
+	RAL_WRITE_REGION_1(sc, RT2661_HW_BEACON_BASE0 + 24,
+	    mtod(m0, uint8_t *), m0->m_pkthdr.len);
+
+	m_freem(m0);
+
+	return 0;
+}
+
+/*
+ * Enable TSF synchronization and tell h/w to start sending beacons for IBSS
+ * and HostAP operating modes.
+ */
+static void
+rt2661_enable_tsf_sync(struct rt2661_softc *sc)
+{
+	struct ieee80211com *ic = &sc->sc_ic;
+	uint32_t tmp;
+
+	if (ic->ic_opmode != IEEE80211_M_STA) {
+		/*
+		 * Change default 16ms TBTT adjustment to 8ms.
+		 * Must be done before enabling beacon generation.
+		 */
+		RAL_WRITE(sc, RT2661_TXRX_CSR10, 1 << 12 | 8);
+	}
+
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000;
+
+	/* set beacon interval (in 1/16ms unit) */
+	tmp |= ic->ic_bss->ni_intval * 16;
+
+	tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT;
+	if (ic->ic_opmode == IEEE80211_M_STA)
+		tmp |= RT2661_TSF_MODE(1);
+	else
+		tmp |= RT2661_TSF_MODE(2) | RT2661_GENERATE_BEACON;
+
+	RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp);
+}
+
+/*
+ * Retrieve the "Received Signal Strength Indicator" from the raw values
+ * contained in Rx descriptors.  The computation depends on which band the
+ * frame was received.  Correction values taken from the reference driver.
+ */
+static int
+rt2661_get_rssi(struct rt2661_softc *sc, uint8_t raw)
+{
+	int lna, agc, rssi;
+
+	lna = (raw >> 5) & 0x3;
+	agc = raw & 0x1f;
+
+	if (lna == 0) {
+		/*
+		 * No mapping available.
+		 *
+		 * NB: Since RSSI is relative to noise floor, -1 is
+		 *     adequate for caller to know error happened.
+		 */
+		return -1;
+	}
+
+	rssi = (2 * agc) - RT2661_NOISE_FLOOR;
+
+	if (IEEE80211_IS_CHAN_2GHZ(sc->sc_curchan)) {
+		rssi += sc->rssi_2ghz_corr;
+
+		if (lna == 1)
+			rssi -= 64;
+		else if (lna == 2)
+			rssi -= 74;
+		else if (lna == 3)
+			rssi -= 90;
+	} else {
+		rssi += sc->rssi_5ghz_corr;
+
+		if (lna == 1)
+			rssi -= 64;
+		else if (lna == 2)
+			rssi -= 86;
+		else if (lna == 3)
+			rssi -= 100;
+	}
+	return rssi;
+}
+
+static void
+rt2661_scan_start(struct ieee80211com *ic)
+{
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2661_softc *sc = ifp->if_softc;
+	uint32_t tmp;
+
+	/* abort TSF synchronization */
+	tmp = RAL_READ(sc, RT2661_TXRX_CSR9);
+	RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0xffffff);
+	rt2661_set_bssid(sc, ifp->if_broadcastaddr);
+}
+
+static void
+rt2661_scan_end(struct ieee80211com *ic)
+{
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2661_softc *sc = ifp->if_softc;
+
+	rt2661_enable_tsf_sync(sc);
+	/* XXX keep local copy */
+	rt2661_set_bssid(sc, ic->ic_bss->ni_bssid);
+}
+
+static void
+rt2661_set_channel(struct ieee80211com *ic)
+{
+	struct ifnet *ifp = ic->ic_ifp;
+	struct rt2661_softc *sc = ifp->if_softc;
+
+	RAL_LOCK(sc);
+	rt2661_set_chan(sc, ic->ic_curchan);
+	RAL_UNLOCK(sc);
+
+}


More information about the Midnightbsd-cvs mailing list