Copy the ralink 2860 source code into place.

git-svn-id: file:///srv/svn/repos/haiku/haiku/trunk@39085 a95241bf-73f2-0310-859d-f6bbb57e9c96
This commit is contained in:
Colin Günther
2010-10-23 20:13:39 +00:00
parent a461e21f03
commit 974d4226ff
21 changed files with 10949 additions and 0 deletions
@@ -0,0 +1,18 @@
SRCS = device_if.h \
bus_if.h \
pci_if.h \
rt2860_io.c \
rt2860_read_eeprom.c \
rt2860_led.c \
rt2860_rf.c \
rt2860_amrr.c \
rt2860.c
KMOD = rt2860
DEBUG_FLAGS = -g
WERROR =
CFLAGS += -DRT2860_DEBUG
.include <bsd.kmod.mk>
File diff suppressed because it is too large Load Diff
@@ -0,0 +1,215 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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/param.h>
#include <sys/kernel.h>
#include <sys/module.h>
#include <sys/socket.h>
#include <sys/sysctl.h>
#include <net/if.h>
#include <net/if_media.h>
#include <net80211/ieee80211_var.h>
#include "rt2860_amrr.h"
/*
* Defines and macros
*/
#define RT2860_AMRR_IS_SUCCESS(amrr_node) ((amrr_node)->retrycnt < (amrr_node)->txcnt / 10)
#define RT2860_AMRR_IS_FAILURE(amrr_node) ((amrr_node)->retrycnt > (amrr_node)->txcnt / 3)
#define RT2860_AMRR_IS_ENOUGH(amrr_node) ((amrr_node)->txcnt > 10)
/*
* Static function prototypes
*/
static int rt2860_amrr_update(struct rt2860_amrr *amrr,
struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni);
/*
* rt2860_amrr_init
*/
void rt2860_amrr_init(struct rt2860_amrr *amrr, struct ieee80211vap *vap,
int ntxpath, int min_success_threshold, int max_success_threshold, int msecs)
{
int t;
amrr->ntxpath = ntxpath;
amrr->min_success_threshold = min_success_threshold;
amrr->max_success_threshold = max_success_threshold;
if (msecs < 100)
msecs = 100;
t = msecs_to_ticks(msecs);
amrr->interval = (t < 1) ? 1 : t;
}
/*
* rt2860_amrr_cleanup
*/
void rt2860_amrr_cleanup(struct rt2860_amrr *amrr)
{
}
/*
* rt2860_amrr_node_init
*/
void rt2860_amrr_node_init(struct rt2860_amrr *amrr,
struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni)
{
const struct ieee80211_rateset *rs;
amrr_node->amrr = amrr;
amrr_node->success = 0;
amrr_node->recovery = 0;
amrr_node->txcnt = 0;
amrr_node->retrycnt = 0;
amrr_node->success_threshold = amrr->min_success_threshold;
if (ni->ni_flags & IEEE80211_NODE_HT)
{
rs = (const struct ieee80211_rateset *) &ni->ni_htrates;
for (amrr_node->rate_index = rs->rs_nrates - 1;
amrr_node->rate_index > 0 && (rs->rs_rates[amrr_node->rate_index] & IEEE80211_RATE_VAL) > 4;
amrr_node->rate_index--) ;
ni->ni_txrate = rs->rs_rates[amrr_node->rate_index] | IEEE80211_RATE_MCS;
}
else
{
rs = &ni->ni_rates;
for (amrr_node->rate_index = rs->rs_nrates - 1;
amrr_node->rate_index > 0 && (rs->rs_rates[amrr_node->rate_index] & IEEE80211_RATE_VAL) > 72;
amrr_node->rate_index--) ;
ni->ni_txrate = rs->rs_rates[amrr_node->rate_index] & IEEE80211_RATE_VAL;
}
amrr_node->ticks = ticks;
}
/*
* rt2860_amrr_choose
*/
int rt2860_amrr_choose(struct ieee80211_node *ni,
struct rt2860_amrr_node *amrr_node)
{
struct rt2860_amrr *amrr;
int rate_index;
amrr = amrr_node->amrr;
if (RT2860_AMRR_IS_ENOUGH(amrr_node) &&
(ticks - amrr_node->ticks) > amrr->interval)
{
rate_index = rt2860_amrr_update(amrr, amrr_node, ni);
if (rate_index != amrr_node->rate_index)
{
if (ni->ni_flags & IEEE80211_NODE_HT)
ni->ni_txrate = ni->ni_htrates.rs_rates[rate_index] | IEEE80211_RATE_MCS;
else
ni->ni_txrate = ni->ni_rates.rs_rates[rate_index] & IEEE80211_RATE_VAL;
amrr_node->rate_index = rate_index;
}
amrr_node->ticks = ticks;
}
else
{
rate_index = amrr_node->rate_index;
}
return rate_index;
}
/*
* rt2860_amrr_update
*/
static int rt2860_amrr_update(struct rt2860_amrr *amrr,
struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni)
{
const struct ieee80211_rateset *rs;
int rate_index;
KASSERT(RT2860_AMRR_IS_ENOUGH(amrr_node),
("not enough Tx count: txcnt=%d",
amrr_node->txcnt));
if (ni->ni_flags & IEEE80211_NODE_HT)
rs = (const struct ieee80211_rateset *) &ni->ni_htrates;
else
rs = &ni->ni_rates;
rate_index = amrr_node->rate_index;
if (RT2860_AMRR_IS_SUCCESS(amrr_node))
{
amrr_node->success++;
if ((amrr_node->success >= amrr_node->success_threshold) &&
(rate_index + 1 < rs->rs_nrates) &&
(!(ni->ni_flags & IEEE80211_NODE_HT) || (rs->rs_rates[rate_index + 1] & IEEE80211_RATE_VAL) < (amrr->ntxpath * 8)))
{
amrr_node->recovery = 1;
amrr_node->success = 0;
rate_index++;
}
else
{
amrr_node->recovery = 0;
}
}
else if (RT2860_AMRR_IS_FAILURE(amrr_node))
{
amrr_node->success = 0;
if (rate_index > 0)
{
if (amrr_node->recovery)
{
amrr_node->success_threshold *= 2;
if (amrr_node->success_threshold > amrr->max_success_threshold)
amrr_node->success_threshold = amrr->max_success_threshold;
}
else
{
amrr_node->success_threshold = amrr->min_success_threshold;
}
rate_index--;
}
amrr_node->recovery = 0;
}
amrr_node->txcnt = 0;
amrr_node->retrycnt = 0;
return rate_index;
}
@@ -0,0 +1,80 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_AMRR_H_
#define _RT2860_AMRR_H_
#define RT2860_AMRR_MIN_SUCCESS_THRESHOLD 1
#define RT2860_AMRR_MAX_SUCCESS_THRESHOLD 15
struct rt2860_amrr
{
int ntxpath;
unsigned int min_success_threshold;
unsigned int max_success_threshold;
int interval;
};
struct rt2860_amrr_node
{
struct rt2860_amrr *amrr;
int rate_index;
int ticks;
unsigned int txcnt;
unsigned int success;
unsigned int success_threshold;
unsigned int recovery;
unsigned int retrycnt;
};
void rt2860_amrr_init(struct rt2860_amrr *amrr, struct ieee80211vap *vap,
int ntxpath, int min_success_threshold, int max_success_threshold, int msecs);
void rt2860_amrr_cleanup(struct rt2860_amrr *amrr);
void rt2860_amrr_node_init(struct rt2860_amrr *amrr,
struct rt2860_amrr_node *amrr_node, struct ieee80211_node *ni);
int rt2860_amrr_choose(struct ieee80211_node *ni,
struct rt2860_amrr_node *amrr_node);
static __inline void rt2860_amrr_tx_complete(struct rt2860_amrr_node *amrr_node,
int ok, int retries)
{
amrr_node->txcnt++;
if (ok)
amrr_node->success++;
amrr_node->retrycnt += retries;
}
static __inline void rt2860_amrr_tx_update(struct rt2860_amrr_node *amrr_node,
int txcnt, int success, int retrycnt)
{
amrr_node->txcnt = txcnt;
amrr_node->success = success;
amrr_node->retrycnt = retrycnt;
}
#endif /* #ifndef _RT2860_AMRR_H_ */
@@ -0,0 +1,53 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_DEBUG_H_
#define _RT2860_DEBUG_H_
#ifdef RT2860_DEBUG
enum
{
RT2860_DEBUG_EEPROM = 0x00000001,
RT2860_DEBUG_RX = 0x00000002,
RT2860_DEBUG_TX = 0x00000004,
RT2860_DEBUG_INTR = 0x00000008,
RT2860_DEBUG_STATE = 0x00000010,
RT2860_DEBUG_CHAN = 0x00000020,
RT2860_DEBUG_NODE = 0x00000040,
RT2860_DEBUG_KEY = 0x00000080,
RT2860_DEBUG_PROT = 0x00000100,
RT2860_DEBUG_WME = 0x00000200,
RT2860_DEBUG_BEACON = 0x00000400,
RT2860_DEBUG_BA = 0x00000800,
RT2860_DEBUG_STATS = 0x00001000,
RT2860_DEBUG_RATE = 0x00002000,
RT2860_DEBUG_PERIODIC = 0x00004000,
RT2860_DEBUG_WATCHDOG = 0x00008000,
RT2860_DEBUG_ANY = 0xffffffff
};
#define RT2860_DPRINTF(sc, m, fmt, ...) do { if ((sc)->debug & (m)) printf(fmt, __VA_ARGS__); } while (0)
#else
#define RT2860_DPRINTF(sc, m, fmt, ...)
#endif /* #ifdef RT2860_DEBUG */
#endif /* #ifndef _RT2860_DEBUG_H_ */
@@ -0,0 +1,78 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_EEPROM_H_
#define _RT2860_EEPROM_H_
#define RT2860_EEPROM_VERSION 0x0002
#define RT2860_EEPROM_ADDRESS01 0x0004
#define RT2860_EEPROM_ADDRESS23 0x0006
#define RT2860_EEPROM_ADDRESS45 0x0008
#define RT2860_EEPROM_POWERSAVE_LEVEL 0x0022
#define RT2860_EEPROM_ANTENNA 0x0034
#define RT2860_EEPROM_NIC_CONFIG 0x0036
#define RT2860_EEPROM_COUNTRY 0x0038
#define RT2860_EEPROM_RF_FREQ_OFF 0x003a
#define RT2860_EEPROM_LED1_OFF 0x003c
#define RT2860_EEPROM_LED2_OFF 0x003e
#define RT2860_EEPROM_LED3_OFF 0x0040
#define RT2860_EEPROM_LNA_GAIN 0x0044
#define RT2860_EEPROM_RSSI_OFF_2GHZ_BASE 0x0046
#define RT2860_EEPROM_RSSI_OFF_5GHZ_BASE 0x0046
#define RT2860_EEPROM_TXPOW_RATE_DELTA 0x0050
#define RT2860_EEPROM_TXPOW1_2GHZ_BASE 0x0052
#define RT2860_EEPROM_TXPOW2_2GHZ_BASE 0x0060
#define RT2860_EEPROM_TSSI_2GHZ_BASE 0x006e
#define RT2860_EEPROM_TXPOW1_5GHZ_BASE 0x0078
#define RT2860_EEPROM_TXPOW2_5GHZ_BASE 0x00a6
#define RT2860_EEPROM_TSSI_5GHZ_BASE 0x00d4
#define RT2860_EEPROM_TXPOW_RATE_BASE 0x00de
#define RT2860_EEPROM_BBP_BASE 0x00f0
#define RT2860_EEPROM_RF_2820 1 /* 2.4GHz 2T3R */
#define RT2860_EEPROM_RF_2850 2 /* 2.4/5GHz 2T3R */
#define RT2860_EEPROM_RF_2720 3 /* 2.4GHz 1T2R */
#define RT2860_EEPROM_RF_2750 4 /* 2.4G/5GHz 1T2R */
/*
* RT2860_EEPROM_NIC_CONFIG flags
*/
#define RT2860_EEPROM_EXT_LNA_5GHZ (1 << 3)
#define RT2860_EEPROM_EXT_LNA_2GHZ (1 << 2)
#define RT2860_EEPROM_TX_AGC_CNTL (1 << 1)
#define RT2860_EEPROM_HW_RADIO_CNTL (1 << 0)
#define RT2860_EEPROM_LED_POLARITY (1 << 7)
#define RT2860_EEPROM_LED_MODE_MASK 0x7f
#define RT2860_EEPROM_LED_CNTL_DEFAULT 0x01
#define RT2860_EEPROM_LED1_OFF_DEFAULT 0x5555
#define RT2860_EEPROM_LED2_OFF_DEFAULT 0x2221
#define RT2860_EEPROM_LED3_OFF_DEFAULT 0xa9f8
#define RT2860_EEPROM_RSSI_OFF_MIN -10
#define RT2860_EEPROM_RSSI_OFF_MAX 10
#define RT2860_EEPROM_TXPOW_2GHZ_MIN 0
#define RT2860_EEPROM_TXPOW_2GHZ_MAX 31
#define RT2860_EEPROM_TXPOW_2GHZ_DEFAULT 5
#define RT2860_EEPROM_TXPOW_5GHZ_MIN -7
#define RT2860_EEPROM_TXPOW_5GHZ_MAX 15
#define RT2860_EEPROM_TXPOW_5GHZ_DEFAULT 5
#endif /* #ifndef _RT2860_EEPROM_H_ */
@@ -0,0 +1,557 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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 "rt2860_io.h"
#include "rt2860_reg.h"
/*
* Defines and macros
*/
/*
* RT2860_IO_EEPROM_RAISE_CLK
*/
#define RT2860_IO_EEPROM_RAISE_CLK(sc, val) \
do \
{ \
(val) |= RT2860_REG_EESK; \
\
rt2860_io_mac_write((sc), RT2860_REG_EEPROM_CSR, (val)); \
\
DELAY(1); \
} while (0)
/*
* RT2860_IO_EEPROM_LOWER_CLK
*/
#define RT2860_IO_EEPROM_LOWER_CLK(sc, val) \
do \
{ \
(val) &= ~RT2860_REG_EESK; \
\
rt2860_io_mac_write((sc), RT2860_REG_EEPROM_CSR, (val)); \
\
DELAY(1); \
} while (0)
#define RT2860_IO_BYTE_CRC16(byte, crc) \
((uint16_t) (((crc) << 8) ^ rt2860_io_ccitt16[(((crc) >> 8) ^ (byte)) & 255]))
/*
* Static function prototypes
*/
static void rt2860_io_eeprom_shiftout_bits(struct rt2860_softc *sc,
uint16_t val, uint16_t count);
static uint16_t rt2860_io_eeprom_shiftin_bits(struct rt2860_softc *sc);
static uint8_t rt2860_io_byte_rev(uint8_t byte);
/*
* Static variables
*/
static const uint16_t rt2860_io_ccitt16[] =
{
0x0000, 0x1021, 0x2042, 0x3063, 0x4084, 0x50a5, 0x60c6, 0x70e7,
0x8108, 0x9129, 0xa14a, 0xb16b, 0xc18c, 0xd1ad, 0xe1ce, 0xf1ef,
0x1231, 0x0210, 0x3273, 0x2252, 0x52b5, 0x4294, 0x72f7, 0x62d6,
0x9339, 0x8318, 0xb37b, 0xa35a, 0xd3bd, 0xc39c, 0xf3ff, 0xe3de,
0x2462, 0x3443, 0x0420, 0x1401, 0x64e6, 0x74c7, 0x44a4, 0x5485,
0xa56a, 0xb54b, 0x8528, 0x9509, 0xe5ee, 0xf5cf, 0xc5ac, 0xd58d,
0x3653, 0x2672, 0x1611, 0x0630, 0x76d7, 0x66f6, 0x5695, 0x46b4,
0xb75b, 0xa77a, 0x9719, 0x8738, 0xf7df, 0xe7fe, 0xd79d, 0xc7bc,
0x48c4, 0x58e5, 0x6886, 0x78a7, 0x0840, 0x1861, 0x2802, 0x3823,
0xc9cc, 0xd9ed, 0xe98e, 0xf9af, 0x8948, 0x9969, 0xa90a, 0xb92b,
0x5af5, 0x4ad4, 0x7ab7, 0x6a96, 0x1a71, 0x0a50, 0x3a33, 0x2a12,
0xdbfd, 0xcbdc, 0xfbbf, 0xeb9e, 0x9b79, 0x8b58, 0xbb3b, 0xab1a,
0x6ca6, 0x7c87, 0x4ce4, 0x5cc5, 0x2c22, 0x3c03, 0x0c60, 0x1c41,
0xedae, 0xfd8f, 0xcdec, 0xddcd, 0xad2a, 0xbd0b, 0x8d68, 0x9d49,
0x7e97, 0x6eb6, 0x5ed5, 0x4ef4, 0x3e13, 0x2e32, 0x1e51, 0x0e70,
0xff9f, 0xefbe, 0xdfdd, 0xcffc, 0xbf1b, 0xaf3a, 0x9f59, 0x8f78,
0x9188, 0x81a9, 0xb1ca, 0xa1eb, 0xd10c, 0xc12d, 0xf14e, 0xe16f,
0x1080, 0x00a1, 0x30c2, 0x20e3, 0x5004, 0x4025, 0x7046, 0x6067,
0x83b9, 0x9398, 0xa3fb, 0xb3da, 0xc33d, 0xd31c, 0xe37f, 0xf35e,
0x02b1, 0x1290, 0x22f3, 0x32d2, 0x4235, 0x5214, 0x6277, 0x7256,
0xb5ea, 0xa5cb, 0x95a8, 0x8589, 0xf56e, 0xe54f, 0xd52c, 0xc50d,
0x34e2, 0x24c3, 0x14a0, 0x0481, 0x7466, 0x6447, 0x5424, 0x4405,
0xa7db, 0xb7fa, 0x8799, 0x97b8, 0xe75f, 0xf77e, 0xc71d, 0xd73c,
0x26d3, 0x36f2, 0x0691, 0x16b0, 0x6657, 0x7676, 0x4615, 0x5634,
0xd94c, 0xc96d, 0xf90e, 0xe92f, 0x99c8, 0x89e9, 0xb98a, 0xa9ab,
0x5844, 0x4865, 0x7806, 0x6827, 0x18c0, 0x08e1, 0x3882, 0x28a3,
0xcb7d, 0xdb5c, 0xeb3f, 0xfb1e, 0x8bf9, 0x9bd8, 0xabbb, 0xbb9a,
0x4a75, 0x5a54, 0x6a37, 0x7a16, 0x0af1, 0x1ad0, 0x2ab3, 0x3a92,
0xfd2e, 0xed0f, 0xdd6c, 0xcd4d, 0xbdaa, 0xad8b, 0x9de8, 0x8dc9,
0x7c26, 0x6c07, 0x5c64, 0x4c45, 0x3ca2, 0x2c83, 0x1ce0, 0x0cc1,
0xef1f, 0xff3e, 0xcf5d, 0xdf7c, 0xaf9b, 0xbfba, 0x8fd9, 0x9ff8,
0x6e17, 0x7e36, 0x4e55, 0x5e74, 0x2e93, 0x3eb2, 0x0ed1, 0x1ef0
};
/*
* rt2860_io_mac_read
*/
uint32_t rt2860_io_mac_read(struct rt2860_softc *sc, uint16_t reg)
{
return bus_space_read_4(sc->bst, sc->bsh, reg);
}
/*
* rt2860_io_mac_read_multi
*/
void rt2860_io_mac_read_multi(struct rt2860_softc *sc,
uint16_t reg, void *buf, size_t len)
{
bus_space_read_region_1(sc->bst, sc->bsh, reg, buf, len);
}
/*
* rt2860_io_mac_write
*/
void rt2860_io_mac_write(struct rt2860_softc *sc,
uint16_t reg, uint32_t val)
{
bus_space_write_4(sc->bst, sc->bsh, reg, val);
}
/*
* rt2860_io_mac_write_multi
*/
void rt2860_io_mac_write_multi(struct rt2860_softc *sc,
uint16_t reg, const void *buf, size_t len)
{
bus_space_write_region_1(sc->bst, sc->bsh, reg, buf, len);
}
/*
* rt2860_io_mac_set_region_4
*/
void rt2860_io_mac_set_region_4(struct rt2860_softc *sc,
uint16_t reg, uint32_t val, size_t len)
{
int i;
for (i = 0; i < len; i += sizeof(uint32_t))
rt2860_io_mac_write(sc, reg + i, val);
}
/*
* rt2860_io_eeprom_read
*/
uint16_t rt2860_io_eeprom_read(struct rt2860_softc *sc, uint16_t addr)
{
uint32_t tmp;
uint16_t val;
addr = (addr >> 1);
tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
tmp &= ~(RT2860_REG_EEDI | RT2860_REG_EEDO | RT2860_REG_EESK);
tmp |= RT2860_REG_EECS;
rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
if (((sc->mac_rev & 0xffff0000) != 0x30710000) &&
((sc->mac_rev & 0xffff0000) != 0x30900000) &&
((sc->mac_rev & 0xffff0000) != 0x35720000) &&
((sc->mac_rev & 0xffff0000) != 0x33900000))
{
RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
}
rt2860_io_eeprom_shiftout_bits(sc, RT2860_REG_EEOP_READ, 3);
rt2860_io_eeprom_shiftout_bits(sc, addr, sc->eeprom_addr_num);
val = rt2860_io_eeprom_shiftin_bits(sc);
tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
tmp &= ~(RT2860_REG_EECS | RT2860_REG_EEDI);
rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
return val;
}
/*
* rt2860_io_eeprom_read_multi
*/
void rt2860_io_eeprom_read_multi(struct rt2860_softc *sc,
uint16_t addr, void *buf, size_t len)
{
uint16_t *ptr;
int i;
len += len % sizeof(uint16_t);
ptr = buf;
i = 0;
do
{
*ptr++ = rt2860_io_eeprom_read(sc, addr + i);
i += sizeof(uint16_t);
len -= sizeof(uint16_t);
} while (len > 0);
}
/*
* rt2860_io_bbp_read
*/
uint8_t rt2860_io_bbp_read(struct rt2860_softc *sc, uint8_t reg)
{
int ntries;
uint32_t tmp;
for (ntries = 0; ntries < 100; ntries++)
{
if (!(rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT) &
RT2860_REG_BBP_CSR_BUSY))
break;
DELAY(1);
}
if (ntries == 100)
{
printf("%s: could not read from BBP through MCU: reg=0x%02x\n",
device_get_nameunit(sc->dev), reg);
return 0;
}
tmp = RT2860_REG_BBP_RW_MODE_PARALLEL |
RT2860_REG_BBP_CSR_BUSY |
RT2860_REG_BBP_CSR_READ |
((reg & RT2860_REG_BBP_REG_MASK) << RT2860_REG_BBP_REG_SHIFT);
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, tmp);
rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_BBP,
RT2860_REG_H2M_TOKEN_NO_INTR, 0);
DELAY(1000);
for (ntries = 0; ntries < 100; ntries++)
{
tmp = rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT);
if (!(tmp & RT2860_REG_BBP_CSR_BUSY))
return ((tmp >> RT2860_REG_BBP_VAL_SHIFT) &
RT2860_REG_BBP_VAL_MASK);
DELAY(1);
}
printf("%s: could not read from BBP through MCU: reg=0x%02x\n",
device_get_nameunit(sc->dev), reg);
return 0;
}
/*
* rt2860_io_bbp_write
*/
void rt2860_io_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val)
{
int ntries;
uint32_t tmp;
for (ntries = 0; ntries < 100; ntries++)
{
if (!(rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT) &
RT2860_REG_BBP_CSR_BUSY))
break;
DELAY(1);
}
if (ntries == 100)
{
printf("%s: could not write to BBP through MCU: reg=0x%02x\n",
device_get_nameunit(sc->dev), reg);
return;
}
tmp = RT2860_REG_BBP_RW_MODE_PARALLEL |
RT2860_REG_BBP_CSR_BUSY |
((reg & RT2860_REG_BBP_REG_MASK) << RT2860_REG_BBP_REG_SHIFT) |
((val & RT2860_REG_BBP_VAL_MASK) << RT2860_REG_BBP_VAL_SHIFT);
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, tmp);
rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_BBP,
RT2860_REG_H2M_TOKEN_NO_INTR, 0);
DELAY(1000);
}
/*
* rt2860_io_rf_write
*/
void rt2860_io_rf_write(struct rt2860_softc *sc, uint8_t reg, uint32_t val)
{
int ntries;
for (ntries = 0; ntries < 100; ntries++)
if (!(rt2860_io_mac_read(sc, RT2860_REG_RF_CSR_CFG0) &
RT2860_REG_RF_BUSY))
break;
if (ntries == 100)
{
printf("%s: could not write to RF: reg=0x%02x\n",
device_get_nameunit(sc->dev), reg);
return;
}
rt2860_io_mac_write(sc, RT2860_REG_RF_CSR_CFG0, val);
}
/*
* rt2860_io_mcu_cmd
*/
void rt2860_io_mcu_cmd(struct rt2860_softc *sc, uint8_t cmd,
uint8_t token, uint16_t arg)
{
uint32_t tmp;
int ntries;
for (ntries = 0; ntries < 100; ntries++)
{
if (!(rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX) &
RT2860_REG_H2M_BUSY))
break;
DELAY(2);
}
if (ntries == 100)
{
printf("%s: could not read H2M: cmd=0x%02x\n",
device_get_nameunit(sc->dev), cmd);
return;
}
tmp = RT2860_REG_H2M_BUSY | (token << 16) | arg;
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX, tmp);
rt2860_io_mac_write(sc, RT2860_REG_H2M_HOST_CMD, cmd);
}
/*
* rt2860_io_mcu_cmd_check
*/
int rt2860_io_mcu_cmd_check(struct rt2860_softc *sc, uint8_t cid)
{
uint32_t tmp, mask, status;
int result, ntries;
result = -1;
for (ntries = 0; ntries < 200; ntries++)
{
tmp = rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_CID);
if (((cid >> RT2860_REG_H2M_CID0_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
{
mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID0_SHIFT);
break;
}
else if (((tmp >> RT2860_REG_H2M_CID1_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
{
mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID1_SHIFT);
break;
}
else if (((tmp >> RT2860_REG_H2M_CID2_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
{
mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID2_SHIFT);
break;
}
else if (((tmp >> RT2860_REG_H2M_CID3_SHIFT) & RT2860_REG_H2M_CID_MASK) == cid)
{
mask = (RT2860_REG_H2M_CID_MASK << RT2860_REG_H2M_CID3_SHIFT);
break;
}
DELAY(100);
}
status = rt2860_io_mac_read(sc, RT2860_REG_H2M_MAILBOX_STATUS);
if (ntries < 200)
{
status &= mask;
if ((status == 0x1) ||
(status == 0x100) ||
(status == 0x10000) ||
(status == 0x1000000))
result = 0;
}
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_STATUS, 0xffffffff);
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_CID, 0xffffffff);
return result;
}
/*
* rt2860_io_mcu_load_ucode
*/
int rt2860_io_mcu_load_ucode(struct rt2860_softc *sc,
const uint8_t *ucode, size_t len)
{
int i, ntries;
uint16_t crc;
for (i = 0, crc = 0xffff; i < len - 2; i++)
crc = RT2860_IO_BYTE_CRC16(rt2860_io_byte_rev(ucode[i]), crc);
if (ucode[len - 2] != rt2860_io_byte_rev(crc >> 8) ||
ucode[len - 1] != rt2860_io_byte_rev(crc))
{
printf("%s: wrong microcode crc\n",
device_get_nameunit(sc->dev));
return EINVAL;
}
rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, RT2860_REG_HST_PM_SEL);
rt2860_io_mac_write_multi(sc, RT2860_REG_MCU_UCODE_BASE, ucode, len);
rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, 0);
rt2860_io_mac_write(sc, RT2860_REG_PBF_SYS_CTRL, RT2860_REG_MCU_RESET);
/* initialize BBP R/W access agent */
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX_BBP_AGENT, 0);
rt2860_io_mac_write(sc, RT2860_REG_H2M_MAILBOX, 0);
for (ntries = 0; ntries < 1000; ntries++)
{
if (rt2860_io_mac_read(sc, RT2860_REG_PBF_SYS_CTRL) &
RT2860_REG_MCU_READY)
break;
DELAY(1000);
}
if (ntries == 1000)
{
printf("%s: timeout waiting for MCU to initialize\n",
device_get_nameunit(sc->dev));
return ETIMEDOUT;
}
return 0;
}
/*
* rt2860_io_eeprom_shiftout_bits
*/
static void rt2860_io_eeprom_shiftout_bits(struct rt2860_softc *sc,
uint16_t val, uint16_t count)
{
uint32_t mask, tmp;
mask = (1 << (count - 1));
tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
tmp &= ~(RT2860_REG_EEDO | RT2860_REG_EEDI);
do
{
tmp &= ~RT2860_REG_EEDI;
if(val & mask)
tmp |= RT2860_REG_EEDI;
rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
mask = (mask >> 1);
} while (mask);
tmp &= ~RT2860_REG_EEDI;
rt2860_io_mac_write(sc, RT2860_REG_EEPROM_CSR, tmp);
}
/*
* rt2860_io_eeprom_shiftin_bits
*/
static uint16_t rt2860_io_eeprom_shiftin_bits(struct rt2860_softc *sc)
{
uint32_t tmp;
uint16_t val;
int i;
val = 0;
tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
tmp &= ~(RT2860_REG_EEDO | RT2860_REG_EEDI);
for(i = 0; i < 16; i++)
{
val = (val << 1);
RT2860_IO_EEPROM_RAISE_CLK(sc, tmp);
tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
RT2860_IO_EEPROM_LOWER_CLK(sc, tmp);
tmp &= ~RT2860_REG_EEDI;
if(tmp & RT2860_REG_EEDO)
val |= 1;
}
return val;
}
/*
* rt2860_io_byte_rev
*/
static uint8_t rt2860_io_byte_rev(uint8_t byte)
{
int i;
uint8_t tmp;
for(i = 0, tmp = 0; ; i++)
{
if(byte & 0x80)
tmp |= 0x80;
if(i == 7)
break;
byte <<= 1;
tmp >>= 1;
}
return tmp;
}
@@ -0,0 +1,69 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_IO_H_
#define _RT2860_IO_H_
#include "rt2860_softc.h"
#define RT2860_IO_MCU_CMD_SLEEP 0x30
#define RT2860_IO_MCU_CMD_WAKEUP 0x31
#define RT2860_IO_MCU_CMD_RADIOOFF 0x35
#define RT2860_IO_MCU_CMD_LEDS 0x50
#define RT2860_IO_MCU_CMD_LED_BRIGHTNESS 0x51
#define RT2860_IO_MCU_CMD_LED1 0x52
#define RT2860_IO_MCU_CMD_LED2 0x53
#define RT2860_IO_MCU_CMD_LED3 0x54
#define RT2860_IO_MCU_CMD_BOOT 0x72
#define RT2860_IO_MCU_CMD_BBP 0x80
#define RT2860_IO_MCU_CMD_POWERSAVE_LEVEL 0x83
uint32_t rt2860_io_mac_read(struct rt2860_softc *sc, uint16_t reg);
void rt2860_io_mac_read_multi(struct rt2860_softc *sc,
uint16_t reg, void *buf, size_t len);
void rt2860_io_mac_write(struct rt2860_softc *sc,
uint16_t reg, uint32_t val);
void rt2860_io_mac_write_multi(struct rt2860_softc *sc,
uint16_t reg, const void *buf, size_t len);
void rt2860_io_mac_set_region_4(struct rt2860_softc *sc,
uint16_t reg, uint32_t val, size_t len);
uint16_t rt2860_io_eeprom_read(struct rt2860_softc *sc, uint16_t addr);
void rt2860_io_eeprom_read_multi(struct rt2860_softc *sc,
uint16_t addr, void *buf, size_t len);
uint8_t rt2860_io_bbp_read(struct rt2860_softc *sc, uint8_t reg);
void rt2860_io_bbp_write(struct rt2860_softc *sc, uint8_t reg, uint8_t val);
void rt2860_io_rf_write(struct rt2860_softc *sc, uint8_t reg, uint32_t val);
void rt2860_io_mcu_cmd(struct rt2860_softc *sc, uint8_t cmd,
uint8_t token, uint16_t arg);
int rt2860_io_mcu_cmd_check(struct rt2860_softc *sc, uint8_t cid);
int rt2860_io_mcu_load_ucode(struct rt2860_softc *sc,
const uint8_t *ucode, size_t len);
#endif /* #ifndef _RT2860_IO_H_ */
@@ -0,0 +1,51 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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 "rt2860_led.h"
#include "rt2860_reg.h"
#include "rt2860_eeprom.h"
#include "rt2860_io.h"
/*
* rt2860_led_brightness
*/
void rt2860_led_brightness(struct rt2860_softc *sc, uint8_t brightness)
{
uint8_t polarity;
uint16_t tmp;
polarity = (sc->led_cntl & RT2860_EEPROM_LED_POLARITY) ? 1 : 0;
tmp = (polarity << 8) | brightness;
rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LED_BRIGHTNESS,
RT2860_REG_H2M_TOKEN_NO_INTR, tmp);
}
/*
* rt2860_led_cmd
*/
void rt2860_led_cmd(struct rt2860_softc *sc, uint8_t cmd)
{
uint16_t tmp;
tmp = (cmd << 8) | (sc->led_cntl & RT2860_EEPROM_LED_MODE_MASK);
rt2860_io_mcu_cmd(sc, RT2860_IO_MCU_CMD_LEDS,
RT2860_REG_H2M_TOKEN_NO_INTR, tmp);
}
@@ -0,0 +1,33 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_LED_H_
#define _RT2860_LED_H_
#include "rt2860_softc.h"
#define RT2860_LED_CMD_RADIO_OFF 0
#define RT2860_LED_CMD_RADIO_ON (1 << 5)
#define RT2860_LED_CMD_LINK_2GHZ (1 << 6)
#define RT2860_LED_CMD_LINK_5GHZ (1 << 7)
void rt2860_led_brightness(struct rt2860_softc *sc, uint8_t brightness);
void rt2860_led_cmd(struct rt2860_softc *sc, uint8_t cmd);
#endif /* #ifndef _RT2870_LED_H_ */
@@ -0,0 +1,493 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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 "rt2860_read_eeprom.h"
#include "rt2860_reg.h"
#include "rt2860_eeprom.h"
#include "rt2860_io.h"
#include "rt2860_debug.h"
/*
* rt2860_read_eeprom
*/
void rt2860_read_eeprom(struct rt2860_softc *sc)
{
uint32_t tmp;
uint16_t val;
int i;
/* read EEPROM address number */
tmp = rt2860_io_mac_read(sc, RT2860_REG_EEPROM_CSR);
if((tmp & 0x30) == 0)
sc->eeprom_addr_num = 6;
else if((tmp & 0x30) == 0x10)
sc->eeprom_addr_num = 8;
else
sc->eeprom_addr_num = 8;
/* read EEPROM version */
sc->eeprom_rev = rt2860_io_eeprom_read(sc, RT2860_EEPROM_VERSION);
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM rev=0x%04x\n",
device_get_nameunit(sc->dev), sc->eeprom_rev);
/* read MAC address */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS01);
sc->mac_addr[0] = (val & 0xff);
sc->mac_addr[1] = (val >> 8);
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS23);
sc->mac_addr[2] = (val & 0xff);
sc->mac_addr[3] = (val >> 8);
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ADDRESS45);
sc->mac_addr[4] = (val & 0xff);
sc->mac_addr[5] = (val >> 8);
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM mac address=%s\n",
device_get_nameunit(sc->dev), ether_sprintf(sc->mac_addr));
/* read RF information */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_ANTENNA);
if (val == 0xffff)
{
printf("%s: invalid EEPROM antenna info\n",
device_get_nameunit(sc->dev));
sc->rf_rev = RT2860_EEPROM_RF_2820;
sc->ntxpath = 1;
sc->nrxpath = 2;
}
else
{
sc->rf_rev = (val >> 8) & 0xf;
sc->ntxpath = (val >> 4) & 0xf;
sc->nrxpath = (val & 0xf);
}
if ((sc->mac_rev != 0x28830300) && (sc->nrxpath > 2))
{
/* only 2 Rx streams for RT2860 series */
sc->nrxpath = 2;
}
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM RF rev=0x%04x, paths=%dT%dR\n",
device_get_nameunit(sc->dev), sc->rf_rev, sc->ntxpath, sc->nrxpath);
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_NIC_CONFIG);
sc->hw_radio_cntl = ((val & RT2860_EEPROM_HW_RADIO_CNTL) ? 1 : 0);
sc->tx_agc_cntl = ((val & RT2860_EEPROM_TX_AGC_CNTL) ? 1 : 0);
sc->ext_lna_2ghz = ((val & RT2860_EEPROM_EXT_LNA_2GHZ) ? 1 : 0);
sc->ext_lna_5ghz = ((val & RT2860_EEPROM_EXT_LNA_5GHZ) ? 1 : 0);
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM NIC config: HW radio cntl=%d, Tx AGC cntl=%d, ext LNA gains=%d/%d\n",
device_get_nameunit(sc->dev),
sc->hw_radio_cntl, sc->tx_agc_cntl, sc->ext_lna_2ghz, sc->ext_lna_5ghz);
/* read country code */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_COUNTRY);
sc->country_2ghz = (val >> 8) & 0xff;
sc->country_5ghz = (val & 0xff);
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM country code=%d/%d\n",
device_get_nameunit(sc->dev), sc->country_2ghz, sc->country_5ghz);
/* read RF frequency offset */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RF_FREQ_OFF);
if ((val & 0xff) != 0xff)
{
sc->rf_freq_off = (val & 0xff);
}
else
{
printf("%s: invalid EEPROM RF freq offset\n",
device_get_nameunit(sc->dev));
sc->rf_freq_off = 0;
}
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM freq offset=0x%02x\n",
device_get_nameunit(sc->dev), sc->rf_freq_off);
/* read LEDs operating mode */
if (((val >> 8) & 0xff) != 0xff)
{
sc->led_cntl = ((val >> 8) & 0xff);
sc->led_off[0] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED1_OFF);
sc->led_off[1] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED2_OFF);
sc->led_off[2] = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LED3_OFF);
}
else
{
printf("%s: invalid EEPROM LED settings\n",
device_get_nameunit(sc->dev));
sc->led_cntl = RT2860_EEPROM_LED_CNTL_DEFAULT;
sc->led_off[0] = RT2860_EEPROM_LED1_OFF_DEFAULT;
sc->led_off[1] = RT2860_EEPROM_LED2_OFF_DEFAULT;
sc->led_off[2] = RT2860_EEPROM_LED3_OFF_DEFAULT;
}
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM LED cntl=0x%02x, LEDs=0x%04x/0x%04x/0x%04x\n",
device_get_nameunit(sc->dev), sc->led_cntl,
sc->led_off[0], sc->led_off[1], sc->led_off[2]);
/* read RSSI offsets and LNA gains */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_LNA_GAIN);
sc->lna_gain[0] = (val & 0xff);
sc->lna_gain[1] = (val >> 8) & 0xff;
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_2GHZ_BASE);
sc->rssi_off_2ghz[0] = (val & 0xff);
sc->rssi_off_2ghz[1] = (val >> 8) & 0xff;
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_2GHZ_BASE + sizeof(uint16_t));
sc->rssi_off_2ghz[2] = (val & 0xff);
sc->lna_gain[2] = (val >> 8) & 0xff;
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_5GHZ_BASE);
sc->rssi_off_5ghz[0] = (val & 0xff);
sc->rssi_off_5ghz[1] = (val >> 8) & 0xff;
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_RSSI_OFF_5GHZ_BASE + sizeof(uint16_t));
sc->rssi_off_5ghz[2] = (val & 0xff);
sc->lna_gain[3] = (val >> 8) & 0xff;
for (i = 2; i < RT2860_SOFTC_LNA_GAIN_COUNT; i++)
{
if (sc->lna_gain[i] == 0x00 || sc->lna_gain[i] == (int8_t) 0xff)
{
printf("%s: invalid EEPROM LNA gain #%d: 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->lna_gain[i]);
sc->lna_gain[i] = sc->lna_gain[1];
}
}
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM LNA gains=0x%02x/0x%02x/0x%02x/0x%02x\n",
device_get_nameunit(sc->dev),
sc->lna_gain[0], sc->lna_gain[1], sc->lna_gain[2], sc->lna_gain[3]);
for (i = 0; i < RT2860_SOFTC_RSSI_OFF_COUNT; i++)
{
if (sc->rssi_off_2ghz[i] < RT2860_EEPROM_RSSI_OFF_MIN ||
sc->rssi_off_2ghz[i] > RT2860_EEPROM_RSSI_OFF_MAX)
{
printf("%s: invalid EEPROM RSSI offset #%d (2GHz): 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->rssi_off_2ghz[i]);
sc->rssi_off_2ghz[i] = 0;
}
if (sc->rssi_off_5ghz[i] < RT2860_EEPROM_RSSI_OFF_MIN ||
sc->rssi_off_5ghz[i] > RT2860_EEPROM_RSSI_OFF_MAX)
{
printf("%s: invalid EEPROM RSSI offset #%d (5GHz): 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->rssi_off_5ghz[i]);
sc->rssi_off_5ghz[i] = 0;
}
}
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM RSSI offsets 2GHz=%d/%d/%d\n",
device_get_nameunit(sc->dev),
sc->rssi_off_2ghz[0], sc->rssi_off_2ghz[1], sc->rssi_off_2ghz[2]);
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM RSSI offsets 5GHz=%d/%d/%d\n",
device_get_nameunit(sc->dev),
sc->rssi_off_5ghz[0], sc->rssi_off_5ghz[1], sc->rssi_off_5ghz[2]);
/* read Tx power settings for 2GHz channels */
for (i = 0; i < 14; i += 2)
{
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW1_2GHZ_BASE + i / 2);
sc->txpow1[i + 0] = (int8_t) (val & 0xff);
sc->txpow1[i + 1] = (int8_t) (val >> 8);
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW2_2GHZ_BASE + i / 2);
sc->txpow2[i + 0] = (int8_t) (val & 0xff);
sc->txpow2[i + 1] = (int8_t) (val >> 8);
}
/* read Tx power settings for 5GHz channels */
for (; i < RT2860_SOFTC_TXPOW_COUNT; i += 2)
{
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW1_5GHZ_BASE + i / 2);
sc->txpow1[i + 0] = (int8_t) (val & 0xff);
sc->txpow1[i + 1] = (int8_t) (val >> 8);
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW2_5GHZ_BASE + i / 2);
sc->txpow2[i + 0] = (int8_t) (val & 0xff);
sc->txpow2[i + 1] = (int8_t) (val >> 8);
}
/* fix broken Tx power settings */
for (i = 0; i < 14; i++)
{
if (sc->txpow1[i] < RT2860_EEPROM_TXPOW_2GHZ_MIN ||
sc->txpow1[i] > RT2860_EEPROM_TXPOW_2GHZ_MAX)
{
printf("%s: invalid EEPROM Tx power1 #%d (2GHz): 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->txpow1[i]);
sc->txpow1[i] = RT2860_EEPROM_TXPOW_2GHZ_DEFAULT;
}
if (sc->txpow2[i] < RT2860_EEPROM_TXPOW_2GHZ_MIN ||
sc->txpow2[i] > RT2860_EEPROM_TXPOW_2GHZ_MAX)
{
printf("%s: invalid EEPROM Tx power2 #%d (2GHz): 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->txpow2[i]);
sc->txpow2[i] = RT2860_EEPROM_TXPOW_2GHZ_DEFAULT;
}
}
for (; i < RT2860_SOFTC_TXPOW_COUNT; i++)
{
if (sc->txpow1[i] < RT2860_EEPROM_TXPOW_5GHZ_MIN ||
sc->txpow1[i] > RT2860_EEPROM_TXPOW_5GHZ_MAX)
{
printf("%s: invalid EEPROM Tx power1 #%d (5GHz): 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->txpow1[i]);
sc->txpow1[i] = RT2860_EEPROM_TXPOW_5GHZ_DEFAULT;
}
if (sc->txpow2[i] < RT2860_EEPROM_TXPOW_5GHZ_MIN ||
sc->txpow2[i] > RT2860_EEPROM_TXPOW_5GHZ_MAX)
{
printf("%s: invalid EEPROM Tx power2 #%d (5GHz): 0x%02x\n",
device_get_nameunit(sc->dev), i, sc->txpow2[i]);
sc->txpow2[i] = RT2860_EEPROM_TXPOW_5GHZ_DEFAULT;
}
}
/* read Tx power per rate deltas */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TXPOW_RATE_DELTA);
sc->txpow_rate_delta_2ghz = 0;
sc->txpow_rate_delta_5ghz = 0;
if ((val & 0xff) != 0xff)
{
if (val & 0x80)
sc->txpow_rate_delta_2ghz = (val & 0xf);
if (!(val & 0x40))
sc->txpow_rate_delta_2ghz = -sc->txpow_rate_delta_2ghz;
}
val >>= 8;
if ((val & 0xff) != 0xff)
{
if (val & 0x80)
sc->txpow_rate_delta_5ghz = (val & 0xf);
if (!(val & 0x40))
sc->txpow_rate_delta_5ghz = -sc->txpow_rate_delta_5ghz;
}
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM Tx power per rate deltas=%d(2MHz), %d(5MHz)\n",
device_get_nameunit(sc->dev),
sc->txpow_rate_delta_2ghz, sc->txpow_rate_delta_5ghz);
/* read Tx power per rate */
for (i = 0; i < RT2860_SOFTC_TXPOW_RATE_COUNT; i++)
{
rt2860_io_eeprom_read_multi(sc, RT2860_EEPROM_TXPOW_RATE_BASE + i * sizeof(uint32_t),
&tmp, sizeof(uint32_t));
sc->txpow_rate_20mhz[i] = tmp;
sc->txpow_rate_40mhz_2ghz[i] =
rt2860_read_eeprom_txpow_rate_add_delta(tmp, sc->txpow_rate_delta_2ghz);
sc->txpow_rate_40mhz_5ghz[i] =
rt2860_read_eeprom_txpow_rate_add_delta(tmp, sc->txpow_rate_delta_5ghz);
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM Tx power per rate #%d=0x%08x(20MHz), 0x%08x(40MHz/2GHz), 0x%08x(40MHz/5GHz)\n",
device_get_nameunit(sc->dev), i,
sc->txpow_rate_20mhz[i], sc->txpow_rate_40mhz_2ghz[i], sc->txpow_rate_40mhz_5ghz[i]);
}
if (sc->tx_agc_cntl)
sc->tx_agc_cntl_2ghz = sc->tx_agc_cntl_5ghz = 1;
/* read factory-calibrated samples for temperature compensation */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE);
sc->tssi_2ghz[0] = (val & 0xff); /* [-4] */
sc->tssi_2ghz[1] = (val >> 8); /* [-3] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + sizeof(uint16_t));
sc->tssi_2ghz[2] = (val & 0xff); /* [-2] */
sc->tssi_2ghz[3] = (val >> 8); /* [-1] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 2 * sizeof(uint16_t));
sc->tssi_2ghz[4] = (val & 0xff); /* [0] */
sc->tssi_2ghz[5] = (val >> 8); /* [+1] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 3 * sizeof(uint16_t));
sc->tssi_2ghz[6] = (val & 0xff); /* [+2] */
sc->tssi_2ghz[7] = (val >> 8); /* [+3] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_2GHZ_BASE + 4 * sizeof(uint16_t));
sc->tssi_2ghz[8] = (val & 0xff); /* [+4] */
sc->tssi_step_2ghz = (val >> 8);
if (sc->tssi_2ghz[4] == 0xff)
sc->tx_agc_cntl_2ghz = 0;
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM TSSI 2GHz: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, "
"0x%02x, 0x%02x, step=%d\n",
device_get_nameunit(sc->dev),
sc->tssi_2ghz[0], sc->tssi_2ghz[1], sc->tssi_2ghz[2],
sc->tssi_2ghz[3], sc->tssi_2ghz[4], sc->tssi_2ghz[5],
sc->tssi_2ghz[6], sc->tssi_2ghz[7], sc->tssi_2ghz[8],
sc->tssi_step_2ghz);
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE);
sc->tssi_5ghz[0] = (val & 0xff); /* [-4] */
sc->tssi_5ghz[1] = (val >> 8); /* [-3] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + sizeof(uint16_t));
sc->tssi_5ghz[2] = (val & 0xff); /* [-2] */
sc->tssi_5ghz[3] = (val >> 8); /* [-1] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 2 * sizeof(uint16_t));
sc->tssi_5ghz[4] = (val & 0xff); /* [0] */
sc->tssi_5ghz[5] = (val >> 8); /* [+1] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 3 * sizeof(uint16_t));
sc->tssi_5ghz[6] = (val & 0xff); /* [+2] */
sc->tssi_5ghz[7] = (val >> 8); /* [+3] */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_TSSI_5GHZ_BASE + 4 * sizeof(uint16_t));
sc->tssi_5ghz[8] = (val & 0xff); /* [+4] */
sc->tssi_step_5ghz = (val >> 8);
if (sc->tssi_5ghz[4] == 0xff)
sc->tx_agc_cntl_5ghz = 0;
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM TSSI 5GHz: 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, 0x%02x, "
"0x%02x, 0x%02x, step=%d\n",
device_get_nameunit(sc->dev),
sc->tssi_5ghz[0], sc->tssi_5ghz[1], sc->tssi_5ghz[2],
sc->tssi_5ghz[3], sc->tssi_5ghz[4], sc->tssi_5ghz[5],
sc->tssi_5ghz[6], sc->tssi_5ghz[7], sc->tssi_5ghz[8],
sc->tssi_step_5ghz);
/* read default BBP settings */
rt2860_io_eeprom_read_multi(sc, RT2860_EEPROM_BBP_BASE,
sc->bbp_eeprom, RT2860_SOFTC_BBP_EEPROM_COUNT * sizeof(uint16_t));
/* read powersave level */
val = rt2860_io_eeprom_read(sc, RT2860_EEPROM_POWERSAVE_LEVEL);
sc->powersave_level = val & 0xff;
if ((sc->powersave_level & 0xff) == 0xff)
printf("%s: invalid EEPROM powersave level\n",
device_get_nameunit(sc->dev));
RT2860_DPRINTF(sc, RT2860_DEBUG_EEPROM,
"%s: EEPROM powersave level=0x%02x\n",
device_get_nameunit(sc->dev), sc->powersave_level);
}
/*
* rt2860_read_eeprom_txpow_rate_add_delta
*/
uint32_t rt2860_read_eeprom_txpow_rate_add_delta(uint32_t txpow_rate,
int8_t delta)
{
int8_t b4;
int i;
for (i = 0; i < 8; i++)
{
b4 = txpow_rate & 0xf;
b4 += delta;
if (b4 < 0)
b4 = 0;
else if (b4 > 0xf)
b4 = 0xf;
txpow_rate = (txpow_rate >> 4) | (b4 << 28);
}
return txpow_rate;
}
@@ -0,0 +1,29 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_READ_EEPROM_H_
#define _RT2860_READ_EEPROM_H_
#include "rt2860_softc.h"
void rt2860_read_eeprom(struct rt2860_softc *sc);
uint32_t rt2860_read_eeprom_txpow_rate_add_delta(uint32_t txpow_rate,
int8_t delta);
#endif /* #ifndef _RT2860_READ_EEPROM_H_ */
@@ -0,0 +1,409 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_REG_H_
#define _RT2860_REG_H_
#define RT2860_REG_EEPROM_CSR 0x0004
#define RT2860_REG_SCHDMA_INT_STATUS 0x0200
#define RT2860_REG_SCHDMA_INT_MASK 0x0204
#define RT2860_REG_SCHDMA_WPDMA_GLO_CFG 0x0208
#define RT2860_REG_SCHDMA_WPDMA_RST_IDX 0x020c
#define RT2860_REG_SCHDMA_DELAY_INT_CFG 0x0210
#define RT2860_REG_SCHDMA_WMM_AIFSN_CFG 0x0214
#define RT2860_REG_SCHDMA_WMM_CWMIN_CFG 0x0218
#define RT2860_REG_SCHDMA_WMM_CWMAX_CFG 0x021c
#define RT2860_REG_SCHDMA_WMM_TXOP0_CFG 0x0220
#define RT2860_REG_SCHDMA_WMM_TXOP1_CFG 0x0224
#define RT2860_REG_SCHDMA_GPIO_CTRL_CFG 0x0228
#define RT2860_REG_SCHDMA_RX_BASE_PTR 0x0290
#define RT2860_REG_SCHDMA_RX_MAX_CNT 0x0294
#define RT2860_REG_SCHDMA_RX_CALC_IDX 0x0298
#define RT2860_REG_SCHDMA_RX_DRX_IDX 0x029c
#define RT2860_REG_SCHDMA_TX_BASE_PTR(qid) (0x0230 + (qid) * 16)
#define RT2860_REG_SCHDMA_TX_MAX_CNT(qid) (0x0234 + (qid) * 16)
#define RT2860_REG_SCHDMA_TX_CTX_IDX(qid) (0x0238 + (qid) * 16)
#define RT2860_REG_SCHDMA_TX_DTX_IDX(qid) (0x023c + (qid) * 16)
#define RT2860_REG_PBF_SYS_CTRL 0x0400
#define RT2860_REG_PBF_CFG 0x0408
#define RT2860_REG_PBF_MAX_PCNT 0x040c
#define RT2860_REG_PBF_BCN_OFFSET0 0x042c
#define RT2860_REG_PBF_BCN_OFFSET1 0x0430
#define RT2860_REG_PBF_TXRXQ_PCNT 0x0438
#define RT2860_REG_MAC_CSR0 0x1000
#define RT2860_REG_SYS_CTRL 0x1004
#define RT2860_REG_ADDR_DW0 0x1008
#define RT2860_REG_ADDR_DW1 0x100c
#define RT2860_REG_BSSID_DW0 0x1010
#define RT2860_REG_BSSID_DW1 0x1014
#define RT2860_REG_MAX_LEN_CFG 0x1018
#define RT2860_REG_BBP_CSR_CFG 0x101c
#define RT2860_REG_RF_CSR_CFG0 0x1020
#define RT2860_REG_LED_CFG 0x102c
#define RT2860_REG_XIFS_TIME_CFG 0x1100
#define RT2860_REG_BKOFF_SLOT_CFG 0x1104
#define RT2860_REG_BCN_TIME_CFG 0x1114
#define RT2860_REG_TSF_TIMER_DW0 0x111c
#define RT2860_REG_TSF_TIMER_DW1 0x1120
#define RT2860_REG_TBTT_TIMER 0x1124
#define RT2860_REG_STATUS_CFG 0x1200
#define RT2860_REG_PWR_PIN_CFG 0x1204
#define RT2860_REG_AUTO_WAKEUP_CFG 0x1208
#define RT2860_REG_TX_EDCA_AC_CFG(aci) (0x1300 + (aci) * 4)
#define RT2860_REG_TX_PWR_CFG(ridx) (0x1314 + (ridx) * 4)
#define RT2860_REG_TX_PIN_CFG 0x1328
#define RT2860_REG_TX_BAND_CFG 0x132c
#define RT2860_REG_TX_SW_CFG0 0x1330
#define RT2860_REG_TX_SW_CFG1 0x1334
#define RT2860_REG_TX_TXOP_CTRL_CFG 0x1340
#define RT2860_REG_TX_RTS_CFG 0x1344
#define RT2860_REG_TX_TIMEOUT_CFG 0x1348
#define RT2860_REG_TX_RTY_CFG 0x134c
#define RT2860_REG_TX_LINK_CFG 0x1350
#define RT2860_REG_TX_HT_FBK_CFG0 0x1354
#define RT2860_REG_TX_HT_FBK_CFG1 0x1358
#define RT2860_REG_TX_LG_FBK_CFG0 0x135c
#define RT2860_REG_TX_LG_FBK_CFG1 0x1360
#define RT2860_REG_TX_CCK_PROT_CFG 0x1364
#define RT2860_REG_TX_OFDM_PROT_CFG 0x1368
#define RT2860_REG_TX_MM20_PROT_CFG 0x136c
#define RT2860_REG_TX_MM40_PROT_CFG 0x1370
#define RT2860_REG_TX_GF20_PROT_CFG 0x1374
#define RT2860_REG_TX_GF40_PROT_CFG 0x1378
#define RT2860_REG_TX_EXP_ACK_TIME 0x1380
#define RT2860_REG_RX_FILTER_CFG 0x1400
#define RT2860_REG_AUTO_RSP_CFG 0x1404
#define RT2860_REG_LEGACY_BASIC_RATE 0x1408
#define RT2860_REG_HT_BASIC_RATE 0x140c
#define RT2860_REG_HCCAPSMP_TXOP_HLDR_ET 0x1608
#define RT2860_REG_RX_STA_CNT0 0x1700
#define RT2860_REG_RX_STA_CNT1 0x1704
#define RT2860_REG_RX_STA_CNT2 0x1708
#define RT2860_REG_TX_STA_CNT0 0x170c
#define RT2860_REG_TX_STA_CNT1 0x1710
#define RT2860_REG_TX_STA_CNT2 0x1714
#define RT2860_REG_TX_STA_FIFO 0x1718
#define RT2860_REG_TX_AGG_CNT 0x171c
#define RT2860_REG_TX_AGG_CNT0 0x1720
#define RT2860_REG_TX_AGG_CNT1 0x1724
#define RT2860_REG_TX_AGG_CNT2 0x1728
#define RT2860_REG_TX_AGG_CNT3 0x172c
#define RT2860_REG_TX_AGG_CNT4 0x1730
#define RT2860_REG_TX_AGG_CNT5 0x1734
#define RT2860_REG_TX_AGG_CNT6 0x1738
#define RT2860_REG_TX_AGG_CNT7 0x173c
#define RT2860_REG_TXRX_MPDU_DEN_CNT 0x1740
#define RT2860_REG_WCID(wcid) (0x1800 + (wcid) * 8)
#define RT2860_REG_PKEY(wcid) (0x4000 + (wcid) * 32)
#define RT2860_REG_IVEIV(wcid) (0x6000 + (wcid) * 8)
#define RT2860_REG_WCID_ATTR(wcid) (0x6800 + (wcid) * 4)
#define RT2860_REG_SKEY(vap, kidx) (0x6c00 + ((vap) * 4 + (kidx)) * 32)
#define RT2860_REG_SKEY_MODE(vap) (0x7000 + ((vap) / 2) * 4)
#define RT2860_REG_MCU_UCODE_BASE 0x2000
#define RT2860_REG_H2M_HOST_CMD 0x0404
#define RT2860_REG_H2M_MAILBOX 0x7010
#define RT2860_REG_H2M_MAILBOX_CID 0x7014
#define RT2860_REG_H2M_MAILBOX_STATUS 0x701c
#define RT2860_REG_H2M_MAILBOX_BBP_AGENT 0x7028
#define RT2860_REG_BEACON_BASE(vap) (0x7800 + (vap) * 512)
#define RT2860_REG_RF_R1 0
#define RT2860_REG_RF_R2 1
#define RT2860_REG_RF_R3 2
#define RT2860_REG_RF_R4 3
/*
* RT2860_REG_EEPROM_CSR flags
*/
#define RT2860_REG_EERL (1 << 7)
#define RT2860_REG_EEDO (1 << 3)
#define RT2860_REG_EEDI (1 << 2)
#define RT2860_REG_EECS (1 << 1)
#define RT2860_REG_EESK (1 << 0)
#define RT2860_REG_EEOP_READ 0x6
/*
* RT2860_REG_SCHDMA_INT_STATUS
* RT2860_REG_SCHDMA_INT_MASK flags
*/
#define RT2860_REG_INT_TX_COHERENT (1 << 17)
#define RT2860_REG_INT_RX_COHERENT (1 << 16)
#define RT2860_REG_INT_GP_TIMER (1 << 15)
#define RT2860_REG_INT_AUTO_WAKEUP (1 << 14)
#define RT2860_REG_INT_FIFO_STA_FULL (1 << 13)
#define RT2860_REG_INT_PRE_TBTT (1 << 12)
#define RT2860_REG_INT_TBTT (1 << 11)
#define RT2860_REG_INT_TXRX_COHERENT (1 << 10)
#define RT2860_REG_INT_MCU_CMD (1 << 9)
#define RT2860_REG_INT_TX_MGMT_DONE (1 << 8)
#define RT2860_REG_INT_TX_HCCA_DONE (1 << 7)
#define RT2860_REG_INT_TX_AC3_DONE (1 << 6)
#define RT2860_REG_INT_TX_AC2_DONE (1 << 5)
#define RT2860_REG_INT_TX_AC1_DONE (1 << 4)
#define RT2860_REG_INT_TX_AC0_DONE (1 << 3)
#define RT2860_REG_INT_RX_DONE (1 << 2)
#define RT2860_REG_INT_TX_DELAY_DONE (1 << 1)
#define RT2860_REG_INT_RX_DELAY_DONE (1 << 0)
/*
* RT2860_REG_SCHDMA_WPDMA_GLO_CFG flags
*/
#define RT2860_REG_TX_WB_DDONE (1 << 6)
#define RT2860_REG_RX_DMA_BUSY (1 << 3)
#define RT2860_REG_RX_DMA_ENABLE (1 << 2)
#define RT2860_REG_TX_DMA_BUSY (1 << 1)
#define RT2860_REG_TX_DMA_ENABLE (1 << 0)
#define RT2860_REG_WPDMA_BT_SIZE_SHIFT 4
#define RT2860_REG_WPDMA_BT_SIZE16 0
#define RT2860_REG_WPDMA_BT_SIZE32 1
#define RT2860_REG_WPDMA_BT_SIZE64 2
#define RT2860_REG_WPDMA_BT_SIZE128 3
/*
* RT2860_REG_SCHDMA_WPDMA_RST_IDX flags
*/
#define RT2860_REG_RST_IDX_RX (1 << 16)
#define RT2860_REG_RST_IDX_TX_MGMT (1 << 5)
#define RT2860_REG_RST_IDX_TX_HCCA (1 << 4)
#define RT2860_REG_RST_IDX_TX_AC3 (1 << 3)
#define RT2860_REG_RST_IDX_TX_AC2 (1 << 2)
#define RT2860_REG_RST_IDX_TX_AC1 (1 << 1)
#define RT2860_REG_RST_IDX_TX_AC0 (1 << 0)
/*
* RT2860_REG_SCHDMA_DELAY_INT_CFG flags
*/
#define RT2860_REG_INT_TX_DELAY_ENABLE (1 << 31)
#define RT2860_REG_INT_TX_MAX_PINT_SHIFT 24
#define RT2860_REG_INT_TX_MAX_PINT_MASK 0x7
#define RT2860_REG_INT_TX_MAX_PTIME_SHIFT 16
#define RT2860_REG_INT_TX_MAX_PTIME_MASK 0x8
#define RT2860_REG_INT_RX_DELAY_ENABLE (1 << 15)
#define RT2860_REG_INT_RX_MAX_PINT_SHIFT 8
#define RT2860_REG_INT_RX_MAX_PINT_MASK 0x7
#define RT2860_REG_INT_RX_MAX_PTIME_SHIFT 0
#define RT2860_REG_INT_RX_MAX_PTIME_MASK 0x8
/*
* RT2860_REG_PBF_SYS_CTRL flags
*/
#define RT2860_REG_HST_PM_SEL (1 << 16)
#define RT2860_REG_MCU_READY (1 << 7)
#define RT2860_REG_MCU_RESET (1 << 0)
/*
* RT2860_REG_PBF_TXRXQ_PCNT flags
*/
#define RT2860_REG_RXQ_PCNT_SHIFT 24
#define RT2860_REG_RXQ_PCNT_MASK 0xff
#define RT2860_REG_TX2Q_PCNT_SHIFT 16
#define RT2860_REG_TX2Q_PCNT_MASK 0xff
#define RT2860_REG_TX1Q_PCNT_SHIFT 8
#define RT2860_REG_TX1Q_PCNT_MASK 0xff
#define RT2860_REG_TX0Q_PCNT_SHIFT 0
#define RT2860_REG_TX0Q_PCNT_MASK 0xff
/*
* RT2860_REG_SYS_CTRL flags
*/
#define RT2860_REG_RX_ENABLE (1 << 3)
#define RT2860_REG_TX_ENABLE (1 << 2)
#define RT2860_REG_BBP_HRST (1 << 1)
#define RT2860_REG_MAC_SRST (1 << 0)
/*
* RT2860_REG_BBP_CSR_CFG flags
*/
#define RT2860_REG_BBP_RW_MODE_PARALLEL (1 << 19)
#define RT2860_REG_BBP_CSR_BUSY (1 << 17)
#define RT2860_REG_BBP_CSR_READ (1 << 16)
#define RT2860_REG_BBP_REG_SHIFT 8
#define RT2860_REG_BBP_REG_MASK 0xff
#define RT2860_REG_BBP_VAL_SHIFT 0
#define RT2860_REG_BBP_VAL_MASK 0xff
/*
* RT2860_REG_RF_CSR_CFG0 flags
*/
#define RT2860_REG_RF_BUSY (1 << 31)
/*
* RT2860_REG_BCN_TIME_CFG flags
*/
#define RT2860_REG_BCN_TX_ENABLE (1 << 20)
#define RT2860_REG_TBTT_TIMER_ENABLE (1 << 19)
#define RT2860_REG_TSF_TIMER_ENABLE (1 << 16)
#define RT2860_REG_TSF_SYNC_MODE_SHIFT 17
#define RT2860_REG_TSF_SYNC_MODE_MASK 0x3
#define RT2860_REG_TSF_SYNC_MODE_DISABLE 0
#define RT2860_REG_TSF_SYNC_MODE_STA 1
#define RT2860_REG_TSF_SYNC_MODE_IBSS 2
#define RT2860_REG_TSF_SYNC_MODE_HOSTAP 3
/*
* RT2860_REG_STATUS_CFG flags
*/
#define RT2860_REG_STATUS_RX_BUSY (1 << 1)
#define RT2860_REG_STATUS_TX_BUSY (1 << 0)
/*
* RT2860_REG_TX_PIN_CFG flags
*/
#define RT2860_REG_TRSW_ENABLE (1 << 18)
#define RT2860_REG_RFTR_ENABLE (1 << 16)
#define RT2860_REG_LNA_PE_G1_ENABLE (1 << 11)
#define RT2860_REG_LNA_PE_A1_ENABLE (1 << 10)
#define RT2860_REG_LNA_PE_G0_ENABLE (1 << 9)
#define RT2860_REG_LNA_PE_A0_ENABLE (1 << 8)
#define RT2860_REG_PA_PE_G1_ENABLE (1 << 3)
#define RT2860_REG_PA_PE_A1_ENABLE (1 << 2)
#define RT2860_REG_PA_PE_G0_ENABLE (1 << 1)
#define RT2860_REG_PA_PE_A0_ENABLE (1 << 0)
/*
* RT2860_REG_TX_BAND_CFG flags
*/
#define RT2860_REG_TX_BAND_BG (1 << 2)
#define RT2860_REG_TX_BAND_A (1 << 1)
#define RT2860_REG_TX_BAND_HT40_ABOVE (1 << 0)
#define RT2860_REG_TX_BAND_HT40_BELOW (0 << 0)
/*
* RT2860_REG_TX_RTS_CFG flags
*/
#define RT2860_REG_TX_RTS_THRESHOLD_SHIFT 8
#define RT2860_REG_TX_RTS_THRESHOLD_MASK 0xffff
/*
* RT2860_REG_TX_CCK_PROT_CFG
* RT2860_REG_TX_OFDM_PROT_CFG
* RT2860_REG_TX_MM20_PROT_CFG
* RT2860_REG_TX_MM40_PROT_CFG
* RT2860_REG_TX_GF20_PROT_CFG
* RT2860_REG_TX_GF40_PROT_CFG flags
*/
#define RT2860_REG_RTSTH_ENABLE (1 << 26)
#define RT2860_REG_TXOP_ALLOW_GF40 (1 << 25)
#define RT2860_REG_TXOP_ALLOW_GF20 (1 << 24)
#define RT2860_REG_TXOP_ALLOW_MM40 (1 << 23)
#define RT2860_REG_TXOP_ALLOW_MM20 (1 << 22)
#define RT2860_REG_TXOP_ALLOW_OFDM (1 << 21)
#define RT2860_REG_TXOP_ALLOW_CCK (1 << 20)
#define RT2860_REG_TXOP_ALLOW_ALL (0x3f << 20)
#define RT2860_REG_PROT_NAV_NONE (0 << 18)
#define RT2860_REG_PROT_NAV_SHORT (1 << 18)
#define RT2860_REG_PROT_NAV_LONG (2 << 18)
#define RT2860_REG_PROT_CTRL_NONE (0 << 16)
#define RT2860_REG_PROT_CTRL_RTS_CTS (1 << 16)
#define RT2860_REG_PROT_CTRL_CTS (2 << 16)
#define RT2860_REG_PROT_PHYMODE_SHIFT 14
#define RT2860_REG_PROT_PHYMODE_MASK 0x3
#define RT2860_REG_PROT_PHYMODE_CCK 0
#define RT2860_REG_PROT_PHYMODE_OFDM 1
#define RT2860_REG_PROT_MCS_SHIFT 0
#define RT2860_REG_PROT_MCS_MASK 0x7f
/*
* RT2860_REG_RX_FILTER_CFG flags
*/
#define RT2860_REG_RX_FILTER_DROP_CTRL_RSV (1 << 16)
#define RT2860_REG_RX_FILTER_DROP_BAR (1 << 15)
#define RT2860_REG_RX_FILTER_DROP_BA (1 << 14)
#define RT2860_REG_RX_FILTER_DROP_PSPOLL (1 << 13)
#define RT2860_REG_RX_FILTER_DROP_RTS (1 << 12)
#define RT2860_REG_RX_FILTER_DROP_CTS (1 << 11)
#define RT2860_REG_RX_FILTER_DROP_ACK (1 << 10)
#define RT2860_REG_RX_FILTER_DROP_CFEND (1 << 9)
#define RT2860_REG_RX_FILTER_DROP_CFACK (1 << 8)
#define RT2860_REG_RX_FILTER_DROP_DUPL (1 << 7)
#define RT2860_REG_RX_FILTER_DROP_BCAST (1 << 6)
#define RT2860_REG_RX_FILTER_DROP_MCAST (1 << 5)
#define RT2860_REG_RX_FILTER_DROP_VER_ERR (1 << 4)
#define RT2860_REG_RX_FILTER_DROP_NOT_MYBSS (1 << 3)
#define RT2860_REG_RX_FILTER_DROP_UC_NOME (1 << 2)
#define RT2860_REG_RX_FILTER_DROP_PHY_ERR (1 << 1)
#define RT2860_REG_RX_FILTER_DROP_CRC_ERR (1 << 0)
/*
* RT2860_REG_AUTO_RSP_CFG flags
*/
#define RT2860_REG_CCK_SHORT_ENABLE (1 << 4)
/*
* RT2860_REG_TX_STA_FIFO flags
*/
#define RT2860_REG_TX_STA_FIFO_MCS_SHIFT 16
#define RT2860_REG_TX_STA_FIFO_MCS_MASK 0x7f
#define RT2860_REG_TX_STA_FIFO_WCID_SHIFT 8
#define RT2860_REG_TX_STA_FIFO_WCID_MASK 0xff
#define RT2860_REG_TX_STA_FIFO_PID_SHIFT 1
#define RT2860_REG_TX_STA_FIFO_PID_MASK 0xf
#define RT2860_REG_TX_STA_FIFO_ACK_REQ (1 << 7)
#define RT2860_REG_TX_STA_FIFO_AGG (1 << 6)
#define RT2860_REG_TX_STA_FIFO_TX_OK (1 << 5)
#define RT2860_REG_TX_STA_FIFO_VALID (1 << 0)
/*
* RT2860_REG_WCID_ATTR flags
*/
#define RT2860_REG_VAP_SHIFT 4
#define RT2860_REG_VAP_MASK 0x7
#define RT2860_REG_CIPHER_MODE_SHIFT 1
#define RT2860_REG_CIPHER_MODE_MASK 0x7
#define RT2860_REG_CIPHER_MODE_NONE 0
#define RT2860_REG_CIPHER_MODE_WEP40 1
#define RT2860_REG_CIPHER_MODE_WEP104 2
#define RT2860_REG_CIPHER_MODE_TKIP 3
#define RT2860_REG_CIPHER_MODE_AES_CCMP 4
#define RT2860_REG_CIPHER_MODE_CKIP40 5
#define RT2860_REG_CIPHER_MODE_CKIP104 6
#define RT2860_REG_CIPHER_MODE_CKIP128 7
#define RT2860_REG_PKEY_ENABLE (1 << 0)
/*
* RT2860_REG_H2M_MAILBOX flags
*/
#define RT2860_REG_H2M_BUSY (1 << 24)
#define RT2860_REG_H2M_TOKEN_POWERSAVE 1
#define RT2860_REG_H2M_TOKEN_RADIOOFF 2
#define RT2860_REG_H2M_TOKEN_WAKEUP 3
#define RT2860_REG_H2M_TOKEN_NO_INTR 0xff
/*
* RT2860_REG_H2M_MAILBOX_CID flags
*/
#define RT2860_REG_H2M_CID0_SHIFT 0
#define RT2860_REG_H2M_CID1_SHIFT 8
#define RT2860_REG_H2M_CID2_SHIFT 16
#define RT2860_REG_H2M_CID3_SHIFT 24
#define RT2860_REG_H2M_CID_MASK 0xff
#endif /* #ifndef _RT2860_REG_H_ */
@@ -0,0 +1,391 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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 "rt2860_rf.h"
#include "rt2860_reg.h"
#include "rt2860_eeprom.h"
#include "rt2860_io.h"
#include "rt2860_debug.h"
/*
* Static variables
*/
static const struct rt2860_rf_prog
{
uint8_t chan;
uint32_t r1, r2, r3, r4;
} rt2860_rf_2850[] =
{
{ 1, 0x98402ecc, 0x984c0786, 0x9816b455, 0x9800510b },
{ 2, 0x98402ecc, 0x984c0786, 0x98168a55, 0x9800519f },
{ 3, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800518b },
{ 4, 0x98402ecc, 0x984c078a, 0x98168a55, 0x9800519f },
{ 5, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800518b },
{ 6, 0x98402ecc, 0x984c078e, 0x98168a55, 0x9800519f },
{ 7, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800518b },
{ 8, 0x98402ecc, 0x984c0792, 0x98168a55, 0x9800519f },
{ 9, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800518b },
{ 10, 0x98402ecc, 0x984c0796, 0x98168a55, 0x9800519f },
{ 11, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800518b },
{ 12, 0x98402ecc, 0x984c079a, 0x98168a55, 0x9800519f },
{ 13, 0x98402ecc, 0x984c079e, 0x98168a55, 0x9800518b },
{ 14, 0x98402ecc, 0x984c07a2, 0x98168a55, 0x98005193 },
{ 36, 0x98402ecc, 0x984c099a, 0x98158a55, 0x980ed1a3 },
{ 38, 0x98402ecc, 0x984c099e, 0x98158a55, 0x980ed193 },
{ 40, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed183 },
{ 44, 0x98402ec8, 0x984c0682, 0x98158a55, 0x980ed1a3 },
{ 46, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed18b },
{ 48, 0x98402ec8, 0x984c0686, 0x98158a55, 0x980ed19b },
{ 52, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed193 },
{ 54, 0x98402ec8, 0x984c068a, 0x98158a55, 0x980ed1a3 },
{ 56, 0x98402ec8, 0x984c068e, 0x98158a55, 0x980ed18b },
{ 60, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed183 },
{ 62, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed193 },
{ 64, 0x98402ec8, 0x984c0692, 0x98158a55, 0x980ed1a3 },
{ 100, 0x98402ec8, 0x984c06b2, 0x98178a55, 0x980ed783 },
{ 102, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed793 },
{ 104, 0x98402ec8, 0x985c06b2, 0x98578a55, 0x980ed1a3 },
{ 108, 0x98402ecc, 0x985c0a32, 0x98578a55, 0x980ed193 },
{ 110, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed183 },
{ 112, 0x98402ecc, 0x984c0a36, 0x98178a55, 0x980ed19b },
{ 116, 0x98402ecc, 0x984c0a3a, 0x98178a55, 0x980ed1a3 },
{ 118, 0x98402ecc, 0x984c0a3e, 0x98178a55, 0x980ed193 },
{ 120, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed183 },
{ 124, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed193 },
{ 126, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed15b },
{ 128, 0x98402ec4, 0x984c0382, 0x98178a55, 0x980ed1a3 },
{ 132, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed18b },
{ 134, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed193 },
{ 136, 0x98402ec4, 0x984c0386, 0x98178a55, 0x980ed19b },
{ 140, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed183 },
{ 149, 0x98402ec4, 0x984c038a, 0x98178a55, 0x980ed1a7 },
{ 151, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed187 },
{ 153, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed18f },
{ 157, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed19f },
{ 159, 0x98402ec4, 0x984c038e, 0x98178a55, 0x980ed1a7 },
{ 161, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed187 },
{ 165, 0x98402ec4, 0x984c0392, 0x98178a55, 0x980ed197 },
{ 184, 0x95002ccc, 0x9500491e, 0x9509be55, 0x950c0a0b },
{ 188, 0x95002ccc, 0x95004922, 0x9509be55, 0x950c0a13 },
{ 192, 0x95002ccc, 0x95004926, 0x9509be55, 0x950c0a1b },
{ 196, 0x95002ccc, 0x9500492a, 0x9509be55, 0x950c0a23 },
{ 208, 0x95002ccc, 0x9500493a, 0x9509be55, 0x950c0a13 },
{ 212, 0x95002ccc, 0x9500493e, 0x9509be55, 0x950c0a1b },
{ 216, 0x95002ccc, 0x95004982, 0x9509be55, 0x950c0a23 },
};
/*
* rt2860_rf_name
*/
const char *rt2860_rf_name(int rf_rev)
{
switch (rf_rev)
{
case RT2860_EEPROM_RF_2820:
return "RT2820";
case RT2860_EEPROM_RF_2850:
return "RT2850";
case RT2860_EEPROM_RF_2720:
return "RT2720";
case RT2860_EEPROM_RF_2750:
return "RT2750";
default:
return "unknown";
}
}
/*
* rt2860_rf_select_chan_group
*/
void rt2860_rf_select_chan_group(struct rt2860_softc *sc,
struct ieee80211_channel *c)
{
struct ifnet *ifp;
struct ieee80211com *ic;
int chan, group;
uint32_t tmp;
ifp = sc->ifp;
ic = ifp->if_l2com;
chan = ieee80211_chan2ieee(ic, c);
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return;
if (chan <= 14)
group = 0;
else if (chan <= 64)
group = 1;
else if (chan <= 128)
group = 2;
else
group = 3;
rt2860_io_bbp_write(sc, 62, 0x37 - sc->lna_gain[group]);
rt2860_io_bbp_write(sc, 63, 0x37 - sc->lna_gain[group]);
rt2860_io_bbp_write(sc, 64, 0x37 - sc->lna_gain[group]);
rt2860_io_bbp_write(sc, 86, 0x00);
if (group == 0)
{
if (sc->ext_lna_2ghz)
{
rt2860_io_bbp_write(sc, 82, 0x62);
rt2860_io_bbp_write(sc, 75, 0x46);
}
else
{
rt2860_io_bbp_write(sc, 82, 0x84);
rt2860_io_bbp_write(sc, 75, 0x50);
}
}
else
{
rt2860_io_bbp_write(sc, 82, 0xf2);
if (sc->ext_lna_5ghz)
rt2860_io_bbp_write(sc, 75, 0x46);
else
rt2860_io_bbp_write(sc, 75, 0x50);
}
if (group == 0)
{
tmp = 0x2e + sc->lna_gain[group];
}
else
{
if ((ic->ic_flags & IEEE80211_F_SCAN) || !IEEE80211_IS_CHAN_HT40(c))
tmp = 0x32 + sc->lna_gain[group] * 5 / 3;
else
tmp = 0x3a + sc->lna_gain[group] * 5 / 3;
}
rt2860_io_bbp_write(sc, 66, tmp);
tmp = RT2860_REG_RFTR_ENABLE |
RT2860_REG_TRSW_ENABLE |
RT2860_REG_LNA_PE_G1_ENABLE |
RT2860_REG_LNA_PE_A1_ENABLE |
RT2860_REG_LNA_PE_G0_ENABLE |
RT2860_REG_LNA_PE_A0_ENABLE;
if (group == 0)
tmp |= RT2860_REG_PA_PE_G1_ENABLE |
RT2860_REG_PA_PE_G0_ENABLE;
else
tmp |= RT2860_REG_PA_PE_A1_ENABLE |
RT2860_REG_PA_PE_A0_ENABLE;
if (sc->ntxpath == 1)
tmp &= ~(RT2860_REG_PA_PE_G1_ENABLE | RT2860_REG_PA_PE_A1_ENABLE);
if (sc->nrxpath == 1)
tmp &= ~(RT2860_REG_LNA_PE_G1_ENABLE | RT2860_REG_LNA_PE_A1_ENABLE);
rt2860_io_mac_write(sc, RT2860_REG_TX_PIN_CFG, tmp);
tmp = rt2860_io_mac_read(sc, RT2860_REG_TX_BAND_CFG);
tmp &= ~(RT2860_REG_TX_BAND_BG | RT2860_REG_TX_BAND_A | RT2860_REG_TX_BAND_HT40_ABOVE);
if (group == 0)
tmp |= RT2860_REG_TX_BAND_BG;
else
tmp |= RT2860_REG_TX_BAND_A;
/* set central channel position */
if (IEEE80211_IS_CHAN_HT40U(c))
tmp |= RT2860_REG_TX_BAND_HT40_BELOW;
else if (IEEE80211_IS_CHAN_HT40D(c))
tmp |= RT2860_REG_TX_BAND_HT40_ABOVE;
else
tmp |= RT2860_REG_TX_BAND_HT40_BELOW;
rt2860_io_mac_write(sc, RT2860_REG_TX_BAND_CFG, tmp);
/* set bandwidth (20MHz or 40MHz) */
tmp = rt2860_io_bbp_read(sc, 4);
tmp &= ~0x18;
if (IEEE80211_IS_CHAN_HT40(c))
tmp |= 0x10;
rt2860_io_bbp_write(sc, 4, tmp);
/* set central channel position */
tmp = rt2860_io_bbp_read(sc, 3);
tmp &= ~0x20;
if (IEEE80211_IS_CHAN_HT40D(c))
tmp |= 0x20;
rt2860_io_bbp_write(sc, 3, tmp);
if (sc->mac_rev == 0x28600100)
{
if (!IEEE80211_IS_CHAN_HT40(c))
{
rt2860_io_bbp_write(sc, 69, 0x16);
rt2860_io_bbp_write(sc, 70, 0x08);
rt2860_io_bbp_write(sc, 73, 0x12);
}
else
{
rt2860_io_bbp_write(sc, 69, 0x1a);
rt2860_io_bbp_write(sc, 70, 0x0a);
rt2860_io_bbp_write(sc, 73, 0x16);
}
}
}
/*
* rt2860_rf_set_chan
*/
void rt2860_rf_set_chan(struct rt2860_softc *sc,
struct ieee80211_channel *c)
{
struct ifnet *ifp;
struct ieee80211com *ic;
const struct rt2860_rf_prog *prog;
uint32_t r1, r2, r3, r4;
int8_t txpow1, txpow2;
int i, chan;
ifp = sc->ifp;
ic = ifp->if_l2com;
prog = rt2860_rf_2850;
/* get central channel position */
chan = ieee80211_chan2ieee(ic, c);
if (IEEE80211_IS_CHAN_HT40U(c))
chan += 2;
else if (IEEE80211_IS_CHAN_HT40D(c))
chan -= 2;
RT2860_DPRINTF(sc, RT2860_DEBUG_CHAN,
"%s: RF set channel: channel=%u, HT%s%s\n",
device_get_nameunit(sc->dev),
ieee80211_chan2ieee(ic, c),
!IEEE80211_IS_CHAN_HT(c) ? " disabled" :
IEEE80211_IS_CHAN_HT20(c) ? "20":
IEEE80211_IS_CHAN_HT40U(c) ? "40U" : "40D",
(ic->ic_flags & IEEE80211_F_SCAN) ? ", scanning" : "");
if (chan == 0 || chan == IEEE80211_CHAN_ANY)
return;
for (i = 0; prog[i].chan != chan; i++);
r1 = prog[i].r1;
r2 = prog[i].r2;
r3 = prog[i].r3;
r4 = prog[i].r4;
txpow1 = sc->txpow1[i];
txpow2 = sc->txpow2[i];
if (sc->ntxpath == 1)
r2 |= (1 << 14);
if (sc->nrxpath == 2)
r2 |= (1 << 6);
else if (sc->nrxpath == 1)
r2 |= (1 << 17) | (1 << 6);
if (IEEE80211_IS_CHAN_2GHZ(c))
{
r3 = (r3 & 0xffffc1ff) | (txpow1 << 9);
r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15) | (txpow2 << 6);
}
else
{
r3 = r3 & 0xffffc1ff;
r4 = (r4 & ~0x001f87c0) | (sc->rf_freq_off << 15);
if (txpow1 >= RT2860_EEPROM_TXPOW_5GHZ_MIN && txpow1 < 0)
{
txpow1 = (-RT2860_EEPROM_TXPOW_5GHZ_MIN + txpow1);
if (txpow1 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
txpow1 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
r3 |= (txpow1 << 10);
}
else
{
if (txpow1 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
txpow1 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
r3 |= (txpow1 << 10) | (1 << 9);
}
if (txpow2 >= RT2860_EEPROM_TXPOW_5GHZ_MIN && txpow2 < 0)
{
txpow2 = (-RT2860_EEPROM_TXPOW_5GHZ_MIN + txpow2);
if (txpow2 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
txpow2 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
r4 |= (txpow2 << 7);
}
else
{
if (txpow2 > RT2860_EEPROM_TXPOW_5GHZ_MAX)
txpow2 = RT2860_EEPROM_TXPOW_5GHZ_MAX;
r4 |= (txpow2 << 7) | (1 << 6);
}
}
if (!(ic->ic_flags & IEEE80211_F_SCAN) && IEEE80211_IS_CHAN_HT40(c))
r4 |= (1 << 21);
rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 & ~(1 << 2));
rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);
DELAY(200);
rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 | (1 << 2));
rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);
DELAY(200);
rt2860_io_rf_write(sc, RT2860_REG_RF_R1, r1);
rt2860_io_rf_write(sc, RT2860_REG_RF_R2, r2);
rt2860_io_rf_write(sc, RT2860_REG_RF_R3, r3 & ~(1 << 2));
rt2860_io_rf_write(sc, RT2860_REG_RF_R4, r4);
rt2860_rf_select_chan_group(sc, c);
DELAY(1000);
}
@@ -0,0 +1,32 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_RF_H_
#define _RT2860_RF_H_
#include "rt2860_softc.h"
const char *rt2860_rf_name(int rf_rev);
void rt2860_rf_select_chan_group(struct rt2860_softc *sc,
struct ieee80211_channel *c);
void rt2860_rf_set_chan(struct rt2860_softc *sc,
struct ieee80211_channel *c);
#endif /* #ifndef _RT2860_RF_H_ */
@@ -0,0 +1,62 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_RXDESC_H_
#define _RT2860_RXDESC_H_
#define RT2860_RXDESC_SDL0_DDONE (1 << 15)
#define RT2860_RXDESC_FLAGS_LAST_AMSDU (1 << 19)
#define RT2860_RXDESC_FLAGS_CIPHER_ALG (1 << 18)
#define RT2860_RXDESC_FLAGS_PLCP_RSSIL (1 << 17)
#define RT2860_RXDESC_FLAGS_DECRYPTED (1 << 16)
#define RT2860_RXDESC_FLAGS_AMPDU (1 << 15)
#define RT2860_RXDESC_FLAGS_L2PAD (1 << 14)
#define RT2860_RXDESC_FLAGS_RSSI (1 << 13)
#define RT2860_RXDESC_FLAGS_HTC (1 << 12)
#define RT2860_RXDESC_FLAGS_AMSDU (1 << 11)
#define RT2860_RXDESC_FLAGS_CRC_ERR (1 << 8)
#define RT2860_RXDESC_FLAGS_MYBSS (1 << 7)
#define RT2860_RXDESC_FLAGS_BCAST (1 << 6)
#define RT2860_RXDESC_FLAGS_MCAST (1 << 5)
#define RT2860_RXDESC_FLAGS_U2M (1 << 4)
#define RT2860_RXDESC_FLAGS_FRAG (1 << 3)
#define RT2860_RXDESC_FLAGS_NULL_DATA (1 << 2)
#define RT2860_RXDESC_FLAGS_DATA (1 << 1)
#define RT2860_RXDESC_FLAGS_BA (1 << 0)
#define RT2860_RXDESC_FLAGS_CIPHER_ERR_SHIFT 9
#define RT2860_RXDESC_FLAGS_CIPHER_ERR_MASK 0x3
#define RT2860_RXDESC_FLAGS_CIPHER_ERR_NONE 0
#define RT2860_RXDESC_FLAGS_CIPHER_ERR_ICV 1
#define RT2860_RXDESC_FLAGS_CIPHER_ERR_MIC 2
#define RT2860_RXDESC_FLAGS_CIPHER_ERR_INVALID_KEY 3
#define RT2860_RXDESC_FLAGS_PLCP_SIGNAL_SHIFT 20
#define RT2860_RXDESC_FLAGS_PLCP_SIGNAL_MASK 0xfff
struct rt2860_rxdesc
{
uint32_t sdp0;
uint16_t sdl1;
uint16_t sdl0;
uint32_t sdp1;
uint32_t flags;
} __packed;
#endif /* #ifndef _RT2860_RXDESC_H_ */
@@ -0,0 +1,79 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_RXWI_H_
#define _RT2860_RXWI_H_
#define RT2860_RXWI_KEYIDX_SHIFT 0
#define RT2860_RXWI_KEYIDX_MASK 0x3
#define RT2860_RXWI_BSSIDX_SHIFT 2
#define RT2860_RXWI_BSSIDX_MASK 0x7
#define RT2860_RXWI_UDF_SHIFT 5
#define RT2860_RXWI_UDF_MASK 0x7
#define RT2860_RXWI_SIZE_SHIFT 0
#define RT2860_RXWI_SIZE_MASK 0xfff
#define RT2860_RXWI_TID_SHIFT 12
#define RT2860_RXWI_TID_MASK 0xf
#define RT2860_RXWI_FRAG_SHIFT 0
#define RT2860_RXWI_FRAG_MASK 0xf
#define RT2860_RXWI_SEQ_SHIFT 4
#define RT2860_RXWI_SEQ_MASK 0xfff
#define RT2860_RXWI_MCS_SHIFT 0
#define RT2860_RXWI_MCS_MASK 0x7f
#define RT2860_RXWI_MCS_SHOTPRE (1 << 3)
#define RT2860_RXWI_BW_SHIFT 7
#define RT2860_RXWI_BW_MASK 0x1
#define RT2860_RXWI_BW_20 0
#define RT2860_RXWI_BW_40 1
#define RT2860_RXWI_SHORTGI_SHIFT 0
#define RT2860_RXWI_SHORTGI_MASK 0x1
#define RT2860_RXWI_STBC_SHIFT 1
#define RT2860_RXWI_STBC_MASK 0x3
#define RT2860_RXWI_PHYMODE_SHIFT 6
#define RT2860_RXWI_PHYMODE_MASK 0x3
#define RT2860_RXWI_PHYMODE_CCK 0
#define RT2860_RXWI_PHYMODE_OFDM 1
#define RT2860_RXWI_PHYMODE_HT_MIXED 2
#define RT2860_RXWI_PHYMODE_HT_GF 3
struct rt2860_rxwi
{
uint8_t wcid;
uint8_t udf_bssidx_keyidx;
uint16_t tid_size;
uint16_t seq_frag;
uint8_t bw_mcs;
uint8_t phymode_stbc_shortgi;
uint8_t rssi[3];
uint8_t reserved1;
uint8_t snr[2];
uint16_t reserved2;
} __packed;
#endif /* #ifndef _RT2860_RXWI_H_ */
@@ -0,0 +1,412 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_SOFTC_H_
#define _RT2860_SOFTC_H_
#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/taskqueue.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_input.h>
#include <net80211/ieee80211_radiotap.h>
#include <net80211/ieee80211_regdomain.h>
#include <dev/pci/pcireg.h>
#include <dev/pci/pcivar.h>
#include "rt2860_rxdesc.h"
#include "rt2860_txdesc.h"
#include "rt2860_txwi.h"
#include "rt2860_amrr.h"
#define RT2860_SOFTC_LOCK(sc) mtx_lock(&(sc)->lock)
#define RT2860_SOFTC_UNLOCK(sc) mtx_unlock(&(sc)->lock)
#define RT2860_SOFTC_ASSERT_LOCKED(sc) mtx_assert(&(sc)->lock, MA_OWNED)
#define RT2860_SOFTC_TX_RING_LOCK(ring) mtx_lock(&(ring)->lock)
#define RT2860_SOFTC_TX_RING_UNLOCK(ring) mtx_unlock(&(ring)->lock)
#define RT2860_SOFTC_TX_RING_ASSERT_LOCKED(ring) mtx_assert(&(ring)->lock, MA_OWNED)
#define RT2860_SOFTC_FLAGS_UCODE_LOADED (1 << 0)
#define RT2860_SOFTC_LED_OFF_COUNT 3
#define RT2860_SOFTC_RSSI_OFF_COUNT 3
#define RT2860_SOFTC_LNA_GAIN_COUNT 4
#define RT2860_SOFTC_TXPOW_COUNT 50
#define RT2860_SOFTC_TXPOW_RATE_COUNT 5
#define RT2860_SOFTC_TSSI_COUNT 9
#define RT2860_SOFTC_BBP_EEPROM_COUNT 8
#define RT2860_SOFTC_RSSI_COUNT 3
#define RT2860_SOFTC_STAID_COUNT 64
#define RT2860_SOFTC_TX_RING_COUNT 6
#define RT2860_SOFTC_RX_RING_DATA_COUNT 128
#define RT2860_SOFTC_MAX_SCATTER 10
#define RT2860_SOFTC_TX_RING_DATA_COUNT 256
#define RT2860_SOFTC_TX_RING_DESC_COUNT \
(RT2860_SOFTC_TX_RING_DATA_COUNT * RT2860_SOFTC_MAX_SCATTER)
#define RT2860_SOFTC_RX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_DBM_ANTSIGNAL) | \
(1 << IEEE80211_RADIOTAP_DBM_ANTNOISE) | \
(1 << IEEE80211_RADIOTAP_ANTENNA) | \
(1 << IEEE80211_RADIOTAP_DB_ANTSIGNAL) | \
(1 << IEEE80211_RADIOTAP_XCHANNEL))
#define RT2860_SOFTC_TX_RADIOTAP_PRESENT \
((1 << IEEE80211_RADIOTAP_FLAGS) | \
(1 << IEEE80211_RADIOTAP_RATE) | \
(1 << IEEE80211_RADIOTAP_XCHANNEL))
struct rt2860_softc_rx_data
{
bus_dmamap_t dma_map;
struct mbuf *m;
};
struct rt2860_softc_rx_ring
{
bus_dma_tag_t desc_dma_tag;
bus_dmamap_t desc_dma_map;
bus_addr_t desc_phys_addr;
struct rt2860_rxdesc *desc;
bus_dma_tag_t data_dma_tag;
bus_dmamap_t spare_dma_map;
struct rt2860_softc_rx_data data[RT2860_SOFTC_RX_RING_DATA_COUNT];
int cur;
};
struct rt2860_softc_tx_data
{
bus_dmamap_t dma_map;
struct ieee80211_node *ni;
struct mbuf *m;
};
struct rt2860_softc_tx_ring
{
struct mtx lock;
bus_dma_tag_t desc_dma_tag;
bus_dmamap_t desc_dma_map;
bus_addr_t desc_phys_addr;
struct rt2860_txdesc *desc;
int desc_queued;
int desc_cur;
int desc_next;
bus_dma_tag_t seg0_dma_tag;
bus_dmamap_t seg0_dma_map;
bus_addr_t seg0_phys_addr;
uint8_t *seg0;
bus_dma_tag_t data_dma_tag;
struct rt2860_softc_tx_data data[RT2860_SOFTC_TX_RING_DATA_COUNT];
int data_queued;
int data_cur;
int data_next;
int qid;
};
struct rt2860_softc_node
{
struct ieee80211_node ni;
uint8_t staid;
uint8_t last_rssi[RT2860_SOFTC_RSSI_COUNT];
int8_t last_rssi_dbm[RT2860_SOFTC_RSSI_COUNT];
};
struct rt2860_softc_vap
{
struct ieee80211vap vap;
struct ieee80211_beacon_offsets beacon_offsets;
struct mbuf *beacon_mbuf;
struct rt2860_txwi beacon_txwi;
struct rt2860_amrr amrr;
int (*newstate)(struct ieee80211vap *vap,
enum ieee80211_state nstate, int arg);
};
struct rt2860_softc_rx_radiotap_header
{
struct ieee80211_radiotap_header ihdr;
uint8_t flags;
uint8_t rate;
int8_t dbm_antsignal;
int8_t dbm_antnoise;
uint8_t antenna;
uint8_t antsignal;
uint8_t pad[2];
uint32_t chan_flags;
uint16_t chan_freq;
uint8_t chan_ieee;
int8_t chan_maxpow;
} __packed;
struct rt2860_softc_tx_radiotap_header
{
struct ieee80211_radiotap_header ihdr;
uint8_t flags;
uint8_t rate;
uint8_t pad[2];
uint32_t chan_flags;
uint16_t chan_freq;
uint8_t chan_ieee;
int8_t chan_maxpow;
} __packed;
struct rt2860_softc
{
struct mtx lock;
uint32_t flags;
device_t dev;
int mem_rid;
struct resource *mem;
int irq_rid;
struct resource *irq;
void *irqh;
bus_space_tag_t bst;
bus_space_handle_t bsh;
struct ifnet *ifp;
int if_flags;
int nvaps;
int napvaps;
int nadhocvaps;
int nstavaps;
int nwdsvaps;
void (*node_cleanup)(struct ieee80211_node *ni);
int (*recv_action)(struct ieee80211_node *ni,
const struct ieee80211_frame *wh,
const uint8_t *frm, const uint8_t *efrm);
int (*send_action)(struct ieee80211_node *ni,
int cat, int act, void *sa);
int (*addba_response)(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap,
int status, int baparamset, int batimeout);
void (*addba_stop)(struct ieee80211_node *ni,
struct ieee80211_tx_ampdu *tap);
int (*ampdu_rx_start)(struct ieee80211_node *ni,
struct ieee80211_rx_ampdu *rap,
int baparamset, int batimeout, int baseqctl);
void (*ampdu_rx_stop)(struct ieee80211_node *ni,
struct ieee80211_rx_ampdu *rap);
struct rt2860_amrr_node amrr_node[RT2860_SOFTC_STAID_COUNT];
uint32_t mac_rev;
uint8_t eeprom_addr_num;
uint16_t eeprom_rev;
uint8_t rf_rev;
uint8_t mac_addr[IEEE80211_ADDR_LEN];
uint8_t ntxpath;
uint8_t nrxpath;
int hw_radio_cntl;
int tx_agc_cntl;
int ext_lna_2ghz;
int ext_lna_5ghz;
uint8_t country_2ghz;
uint8_t country_5ghz;
uint8_t rf_freq_off;
uint8_t led_cntl;
uint16_t led_off[RT2860_SOFTC_LED_OFF_COUNT];
int8_t rssi_off_2ghz[RT2860_SOFTC_RSSI_OFF_COUNT];
int8_t rssi_off_5ghz[RT2860_SOFTC_RSSI_OFF_COUNT];
int8_t lna_gain[RT2860_SOFTC_LNA_GAIN_COUNT];
int8_t txpow1[RT2860_SOFTC_TXPOW_COUNT];
int8_t txpow2[RT2860_SOFTC_TXPOW_COUNT];
int8_t txpow_rate_delta_2ghz;
int8_t txpow_rate_delta_5ghz;
uint32_t txpow_rate_20mhz[RT2860_SOFTC_TXPOW_RATE_COUNT];
uint32_t txpow_rate_40mhz_2ghz[RT2860_SOFTC_TXPOW_RATE_COUNT];
uint32_t txpow_rate_40mhz_5ghz[RT2860_SOFTC_TXPOW_RATE_COUNT];
int tx_agc_cntl_2ghz;
int tx_agc_cntl_5ghz;
uint8_t tssi_2ghz[RT2860_SOFTC_TSSI_COUNT];
uint8_t tssi_step_2ghz;
uint8_t tssi_5ghz[RT2860_SOFTC_TSSI_COUNT];
uint8_t tssi_step_5ghz;
struct
{
uint8_t val;
uint8_t reg;
} __packed bbp_eeprom[RT2860_SOFTC_BBP_EEPROM_COUNT];
uint16_t powersave_level;
uint8_t staid_mask[RT2860_SOFTC_STAID_COUNT / NBBY];
uint32_t intr_enable_mask;
uint32_t intr_disable_mask;
uint32_t intr_pending_mask;
struct task rx_done_task;
int rx_process_limit;
struct task tx_done_task;
struct task fifo_sta_full_task;
struct task periodic_task;
struct callout periodic_ch;
unsigned long periodic_round;
struct taskqueue *taskqueue;
struct rt2860_softc_rx_ring rx_ring;
struct rt2860_softc_tx_ring tx_ring[RT2860_SOFTC_TX_RING_COUNT];
int tx_ring_mgtqid;
struct callout tx_watchdog_ch;
int tx_timer;
struct rt2860_softc_rx_radiotap_header rxtap;
struct rt2860_softc_tx_radiotap_header txtap;
/* statistic counters */
unsigned long interrupts;
unsigned long tx_coherent_interrupts;
unsigned long rx_coherent_interrupts;
unsigned long txrx_coherent_interrupts;
unsigned long fifo_sta_full_interrupts;
unsigned long rx_interrupts;
unsigned long rx_delay_interrupts;
unsigned long tx_interrupts[RT2860_SOFTC_TX_RING_COUNT];
unsigned long tx_delay_interrupts;
unsigned long pre_tbtt_interrupts;
unsigned long tbtt_interrupts;
unsigned long mcu_cmd_interrupts;
unsigned long auto_wakeup_interrupts;
unsigned long gp_timer_interrupts;
unsigned long tx_data_queue_full[RT2860_SOFTC_TX_RING_COUNT];
unsigned long tx_watchdog_timeouts;
unsigned long tx_defrag_packets;
unsigned long no_tx_desc_avail;
unsigned long rx_mbuf_alloc_errors;
unsigned long rx_mbuf_dmamap_errors;
unsigned long tx_queue_not_empty[2];
unsigned long tx_beacons;
unsigned long tx_noretryok;
unsigned long tx_retryok;
unsigned long tx_failed;
unsigned long tx_underflows;
unsigned long tx_zerolen;
unsigned long tx_nonagg;
unsigned long tx_agg;
unsigned long tx_ampdu;
unsigned long tx_mpdu_zero_density;
unsigned long tx_ampdu_sessions;
unsigned long rx_packets;
unsigned long rx_ampdu;
unsigned long rx_ampdu_retries;
unsigned long rx_mpdu_zero_density;
unsigned long rx_ampdu_sessions;
unsigned long rx_amsdu;
unsigned long rx_crc_errors;
unsigned long rx_phy_errors;
unsigned long rx_false_ccas;
unsigned long rx_plcp_errors;
unsigned long rx_dup_packets;
unsigned long rx_fifo_overflows;
unsigned long rx_cipher_no_errors;
unsigned long rx_cipher_icv_errors;
unsigned long rx_cipher_mic_errors;
unsigned long rx_cipher_invalid_key_errors;
int tx_stbc;
#ifdef RT2860_DEBUG
int debug;
#endif
};
#endif /* #ifndef _RT2860_SOFTC_H_ */
@@ -0,0 +1,48 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_TXDESC_H_
#define _RT2860_TXDESC_H_
#define RT2860_TXDESC_SDL1_BURST (1 << 15)
#define RT2860_TXDESC_SDL1_LASTSEG (1 << 14)
#define RT2860_TXDESC_SDL0_DDONE (1 << 15)
#define RT2860_TXDESC_SDL0_LASTSEG (1 << 14)
#define RT2860_TXDESC_FLAGS_SHIFT 0
#define RT2860_TXDESC_FLAGS_MASK 0xf9
#define RT2860_TXDESC_FLAGS_WI_VALID (1 << 0)
#define RT2860_TXDESC_QSEL_SHIFT 1
#define RT2860_TXDESC_QSEL_MASK 0x3
#define RT2860_TXDESC_QSEL_MGMT 0
#define RT2860_TXDESC_QSEL_HCCA 1
#define RT2860_TXDESC_QSEL_EDCA 2
struct rt2860_txdesc
{
uint32_t sdp0;
uint16_t sdl1;
uint16_t sdl0;
uint32_t sdp1;
uint8_t reserved[3];
uint8_t qsel_flags;
} __packed;
#endif /* #ifndef _RT2860_TXDESC_H_ */
@@ -0,0 +1,92 @@
/*-
* Copyright (c) 2009-2010 Alexander Egorenkov <egorenar@gmail.com>
* Copyright (c) 2009 Damien Bergamini <damien.bergamini@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.
*/
#ifndef _RT2860_TXWI_H_
#define _RT2860_TXWI_H_
#define RT2860_TXWI_FLAGS_SHIFT 0
#define RT2860_TXWI_FLAGS_MASK 0x1f
#define RT2860_TXWI_FLAGS_AMPDU (1 << 4)
#define RT2860_TXWI_FLAGS_TS (1 << 3)
#define RT2860_TXWI_FLAGS_CFACK (1 << 2)
#define RT2860_TXWI_FLAGS_MIMOPS (1 << 1)
#define RT2860_TXWI_FLAGS_FRAG (1 << 0)
#define RT2860_TXWI_MPDU_DENSITY_SHIFT 5
#define RT2860_TXWI_MPDU_DENSITY_MASK 0x7
#define RT2860_TXWI_TXOP_SHIFT 0
#define RT2860_TXWI_TXOP_MASK 0x3
#define RT2860_TXWI_TXOP_HT 0
#define RT2860_TXWI_TXOP_PIFS 1
#define RT2860_TXWI_TXOP_SIFS 2
#define RT2860_TXWI_TXOP_BACKOFF 3
#define RT2860_TXWI_MCS_SHIFT 0
#define RT2860_TXWI_MCS_MASK 0x7f
#define RT2860_TXWI_MCS_SHOTPRE (1 << 3)
#define RT2860_TXWI_BW_SHIFT 7
#define RT2860_TXWI_BW_MASK 0x1
#define RT2860_TXWI_BW_20 0
#define RT2860_TXWI_BW_40 1
#define RT2860_TXWI_SHORTGI_SHIFT 0
#define RT2860_TXWI_SHORTGI_MASK 0x1
#define RT2860_TXWI_STBC_SHIFT 1
#define RT2860_TXWI_STBC_MASK 0x3
#define RT2860_TXWI_IFS_SHIFT 3
#define RT2860_TXWI_IFS_MASK 0x1
#define RT2860_TXWI_PHYMODE_SHIFT 6
#define RT2860_TXWI_PHYMODE_MASK 0x3
#define RT2860_TXWI_PHYMODE_CCK 0
#define RT2860_TXWI_PHYMODE_OFDM 1
#define RT2860_TXWI_PHYMODE_HT_MIXED 2
#define RT2860_TXWI_PHYMODE_HT_GF 3
#define RT2860_TXWI_XFLAGS_SHIFT 0
#define RT2860_TXWI_XFLAGS_MASK 0x3
#define RT2860_TXWI_XFLAGS_NSEQ (1 << 1)
#define RT2860_TXWI_XFLAGS_ACK (1 << 0)
#define RT2860_TXWI_BAWIN_SIZE_SHIFT 2
#define RT2860_TXWI_BAWIN_SIZE_MASK 0x3f
#define RT2860_TXWI_MPDU_LEN_SHIFT 0
#define RT2860_TXWI_MPDU_LEN_MASK 0xfff
#define RT2860_TXWI_PID_SHIFT 12
#define RT2860_TXWI_PID_MASK 0xf
struct rt2860_txwi
{
uint8_t mpdu_density_flags;
uint8_t txop;
uint8_t bw_mcs;
uint8_t phymode_ifs_stbc_shortgi;
uint8_t bawin_size_xflags;
uint8_t wcid;
uint16_t pid_mpdu_len;
uint32_t iv;
uint32_t eiv;
} __packed;
#endif /* #ifndef _RT2860_TXWI_H_ */
@@ -0,0 +1,566 @@
/*
Copyright (c) 2007, Ralink Technology Corporation
All rights reserved.
Redistribution. Redistribution and use in binary form, without
modification, are permitted provided that the following conditions are
met:
* Redistributions must reproduce the above copyright notice and the
following disclaimer in the documentation and/or other materials
provided with the distribution.
* Neither the name of Ralink Technology Corporation nor the names of its
suppliers may be used to endorse or promote products derived from this
software without specific prior written permission.
* No reverse engineering, decompilation, or disassembly of this software
is permitted.
Limited patent license. Ralink Technology Corporation grants a world-wide,
royalty-free, non-exclusive license under patents it now or hereafter
owns or controls to make, have made, use, import, offer to sell and
sell ("Utilize") this software, but solely to the extent that any
such patent is necessary to Utilize the software alone, or in
combination with an operating system licensed under an approved Open
Source license as listed by the Open Source Initiative at
http://opensource.org/licenses. The patent license shall not apply to
any other combinations which include this software. No hardware per
se is licensed hereunder.
DISCLAIMER. THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING,
BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
DAMAGE.
*/
#ifndef _RT2860_UCODE_H_
#define _RT2860_UCODE_H_
/*
* RT2860 microcode v26
*/
static const uint8_t rt2860_ucode[] =
{
0x02, 0x03, 0x5b, 0x02, 0x02, 0xa6, 0x22, 0x22, 0xff, 0xff, 0xff, 0x02, 0x01, 0x2c, 0xff, 0xff,
0xff, 0xff, 0xff, 0x02, 0x00, 0x1e, 0xff, 0xff, 0xff, 0xff, 0xff, 0x02, 0x00, 0xdd, 0xc0, 0xe0,
0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x18, 0xc2, 0xaf, 0x30, 0x45, 0x03,
0x12, 0x10, 0x09, 0x90, 0x04, 0x16, 0xe0, 0x30, 0xe3, 0x03, 0x74, 0x08, 0xf0, 0x90, 0x04, 0x14,
0xe0, 0x20, 0xe7, 0x03, 0x02, 0x00, 0xcb, 0x74, 0x80, 0xf0, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x36,
0x90, 0x04, 0x04, 0xe0, 0x24, 0xcf, 0x60, 0x30, 0x14, 0x60, 0x42, 0x24, 0xe2, 0x60, 0x47, 0x14,
0x60, 0x55, 0x24, 0x21, 0x70, 0x60, 0xe5, 0x55, 0x24, 0xfe, 0x60, 0x07, 0x14, 0x60, 0x08, 0x24,
0x02, 0x70, 0x08, 0x7d, 0x01, 0x80, 0x28, 0x7d, 0x02, 0x80, 0x24, 0x90, 0x70, 0x10, 0xe0, 0xf5,
0x50, 0x85, 0x36, 0x40, 0xd2, 0x01, 0x80, 0x3e, 0xe5, 0x55, 0x64, 0x03, 0x60, 0x04, 0xe5, 0x55,
0x70, 0x04, 0x7d, 0x02, 0x80, 0x09, 0x85, 0x36, 0x41, 0xd2, 0x02, 0x80, 0x29, 0xad, 0x55, 0xaf,
0x36, 0x12, 0x02, 0x82, 0x80, 0x20, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x47, 0x90, 0x70, 0x11, 0xe0,
0xf5, 0x44, 0x12, 0x10, 0x25, 0x80, 0x06, 0x90, 0x70, 0x10, 0xe0, 0xf5, 0x45, 0xe4, 0xfd, 0xaf,
0x36, 0x12, 0x02, 0x82, 0xd2, 0x04, 0x90, 0x70, 0x13, 0xe4, 0xf0, 0x90, 0x70, 0x13, 0xe4, 0xf0,
0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0,
0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0xe8, 0xc0, 0xe0, 0xe9, 0xc0, 0xe0, 0xea, 0xc0, 0xe0,
0xeb, 0xc0, 0xe0, 0xec, 0xc0, 0xe0, 0xed, 0xc0, 0xe0, 0xee, 0xc0, 0xe0, 0xef, 0xc0, 0xe0, 0xc2,
0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x12, 0xd2, 0xaf, 0xd0, 0xe0, 0xff, 0xd0, 0xe0, 0xfe, 0xd0,
0xe0, 0xfd, 0xd0, 0xe0, 0xfc, 0xd0, 0xe0, 0xfb, 0xd0, 0xe0, 0xfa, 0xd0, 0xe0, 0xf9, 0xd0, 0xe0,
0xf8, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc0, 0xe0, 0xc0, 0xf0,
0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x10, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10,
0x0c, 0x30, 0x58, 0x0a, 0xe5, 0x54, 0x60, 0x04, 0x15, 0x54, 0x80, 0x02, 0xc2, 0x58, 0x30, 0x59,
0x0a, 0xe5, 0x50, 0x60, 0x04, 0x15, 0x50, 0x80, 0x02, 0xc2, 0x59, 0xd5, 0x53, 0x07, 0x30, 0x60,
0x04, 0x15, 0x46, 0xd2, 0x04, 0x30, 0x45, 0x03, 0x12, 0x10, 0x0f, 0xc2, 0x8d, 0xd2, 0xaf, 0xd0,
0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x70, 0x2a, 0xe0, 0x30, 0xe1,
0x43, 0xc2, 0xaf, 0x90, 0x70, 0x28, 0xe0, 0x90, 0x10, 0x1c, 0xf0, 0x90, 0x70, 0x29, 0xe0, 0x90,
0x10, 0x1d, 0xf0, 0x90, 0x70, 0x2a, 0xe0, 0x90, 0x10, 0x1e, 0xf0, 0x90, 0x10, 0x1c, 0xe0, 0xf5,
0x37, 0x90, 0x10, 0x1e, 0xe0, 0x20, 0xe1, 0xf3, 0x90, 0x10, 0x1c, 0xe0, 0x90, 0x70, 0x28, 0xf0,
0x90, 0x10, 0x1d, 0xe0, 0x90, 0x70, 0x29, 0xf0, 0x90, 0x10, 0x1e, 0xe0, 0x90, 0x70, 0x2a, 0xf0,
0xc2, 0x05, 0xd2, 0xaf, 0x22, 0x12, 0x02, 0xc8, 0x30, 0x45, 0x03, 0x12, 0x10, 0x03, 0x30, 0x01,
0x06, 0x20, 0x09, 0x03, 0x12, 0x10, 0x1c, 0x30, 0x02, 0x06, 0x20, 0x0a, 0x03, 0x12, 0x10, 0x1f,
0x30, 0x03, 0x06, 0x20, 0x0b, 0x03, 0x12, 0x10, 0x1f, 0x30, 0x04, 0x06, 0x20, 0x0c, 0x03, 0x12,
0x10, 0x22, 0x20, 0x13, 0x09, 0x20, 0x11, 0x06, 0xe5, 0x2b, 0x45, 0x2c, 0x60, 0x03, 0xd3, 0x80,
0x01, 0xc3, 0x92, 0xa9, 0x12, 0x03, 0x1c, 0x80, 0xbf, 0xc2, 0x43, 0xd2, 0x45, 0xe4, 0xf5, 0x20,
0xf5, 0x21, 0xf5, 0x53, 0xf5, 0x46, 0xf5, 0x2b, 0xf5, 0x2c, 0xc2, 0x42, 0xf5, 0x51, 0xf5, 0x52,
0xf5, 0x55, 0x90, 0x04, 0x18, 0x74, 0x80, 0xf0, 0x90, 0x04, 0x1a, 0x74, 0x08, 0xf0, 0xc2, 0x1a,
0xc2, 0x18, 0xc2, 0x1b, 0x22, 0xc8, 0xef, 0xc8, 0xe6, 0xfa, 0x08, 0xe6, 0x4a, 0x60, 0x0c, 0xc8,
0xef, 0xc8, 0x08, 0xe6, 0x16, 0x18, 0x70, 0x01, 0x16, 0xc3, 0x22, 0xed, 0x24, 0xff, 0xfd, 0xec,
0x34, 0xff, 0xc8, 0xef, 0xc8, 0xf6, 0x08, 0xc6, 0xed, 0xc6, 0xd3, 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, 0xef, 0xf4, 0x60, 0x1f, 0xe4, 0xfe, 0x12, 0x03, 0x67, 0xe0, 0xb4, 0xff, 0x12, 0x12,
0x03, 0x67, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0,
0x22, 0x0e, 0xbe, 0x04, 0xe3, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0,
0x75, 0xd0, 0x08, 0xc2, 0xaf, 0x30, 0x45, 0x03, 0x12, 0x10, 0x06, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0,
0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc2, 0xaf, 0x12, 0x00, 0x06, 0x12, 0x02, 0x09,
0x12, 0x02, 0xe1, 0xe4, 0xf5, 0x22, 0xf5, 0x47, 0x90, 0x04, 0x00, 0x74, 0x80, 0xf0, 0xd2, 0xaf,
0x22, 0x75, 0x89, 0x02, 0xe4, 0xf5, 0x8c, 0xf5, 0x8a, 0xf5, 0x88, 0xf5, 0xb8, 0xf5, 0xe8, 0x75,
0x90, 0x18, 0xd2, 0x8c, 0x75, 0xa8, 0x05, 0x22, 0xef, 0x60, 0x03, 0x1f, 0x80, 0xfa, 0x22, 0xff,
0xc0, 0x26, 0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x0a, 0x22, 0xc0, 0x26,
0x74, 0x03, 0xc0, 0xe0, 0xc0, 0x82, 0xc0, 0x83, 0x75, 0x26, 0x18, 0x22, 0x30, 0x45, 0x03, 0x12,
0x10, 0x15, 0xe5, 0x20, 0x70, 0x03, 0x20, 0x10, 0x03, 0x30, 0x11, 0x03, 0x43, 0x87, 0x01, 0x22,
0xce, 0xef, 0xce, 0xee, 0x60, 0x08, 0x7f, 0xff, 0x12, 0x02, 0xf8, 0x1e, 0x80, 0xf5, 0x22, 0xc8,
0xef, 0xc8, 0xe6, 0x60, 0x03, 0x16, 0xc3, 0x22, 0xed, 0x14, 0xf6, 0xd3, 0x22, 0xc8, 0xef, 0xc8,
0xe6, 0x60, 0x06, 0x16, 0xe6, 0x24, 0xff, 0xb3, 0x22, 0xc3, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8,
0xfd, 0x75, 0x81, 0x5f, 0x02, 0x01, 0xc5, 0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5,
0x83, 0x22, 0xef, 0x90, 0x03, 0x7b, 0x93, 0x90, 0x03, 0x00, 0x73, 0x0a, 0x18, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
0xff, 0xff, 0xff, 0x02, 0x10, 0x28, 0x02, 0x10, 0x3b, 0x02, 0x10, 0x3c, 0x02, 0x13, 0xbc, 0x02,
0x13, 0xbd, 0x02, 0x14, 0x72, 0x02, 0x14, 0x73, 0xc3, 0x22, 0xff, 0xff, 0x02, 0x19, 0x4a, 0x02,
0x1a, 0xf4, 0x02, 0x15, 0x6c, 0x02, 0x14, 0xa7, 0x30, 0x05, 0x06, 0x20, 0x0d, 0x03, 0x12, 0x01,
0x7a, 0x30, 0x06, 0x06, 0x20, 0x0e, 0x03, 0x12, 0x1c, 0x2e, 0x22, 0x22, 0x90, 0x04, 0x14, 0xe0,
0x20, 0xe7, 0x03, 0x02, 0x13, 0xbb, 0x90, 0x70, 0x12, 0xe0, 0xf5, 0x56, 0x90, 0x04, 0x04, 0xe0,
0x12, 0x02, 0x5c, 0x10, 0xfb, 0x30, 0x10, 0xd2, 0x31, 0x10, 0x93, 0x33, 0x10, 0xa1, 0x34, 0x10,
0xb4, 0x35, 0x10, 0xab, 0x36, 0x11, 0x09, 0x50, 0x11, 0x4e, 0x51, 0x11, 0x57, 0x52, 0x11, 0x57,
0x53, 0x11, 0x57, 0x54, 0x11, 0x93, 0x55, 0x11, 0xf0, 0x56, 0x12, 0x43, 0x70, 0x12, 0x69, 0x71,
0x12, 0x92, 0x72, 0x13, 0x3e, 0x73, 0x13, 0x61, 0x80, 0x13, 0x88, 0x83, 0x13, 0xa0, 0x84, 0x00,
0x00, 0x13, 0xbb, 0xd2, 0x18, 0xd2, 0x61, 0x75, 0x35, 0x2a, 0x75, 0x32, 0x0b, 0x75, 0x33, 0xb8,
0x22, 0xc2, 0x18, 0x90, 0x01, 0x14, 0xe0, 0x54, 0xfd, 0xf0, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf5,
0x3c, 0x02, 0x13, 0xb5, 0xe5, 0x55, 0xb4, 0x02, 0x0f, 0xe5, 0x58, 0x30, 0xe0, 0x06, 0x90, 0x01,
0x0d, 0x74, 0x08, 0xf0, 0x7d, 0x01, 0x80, 0x02, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x02,
0x13, 0xb5, 0x20, 0x02, 0x03, 0x30, 0x03, 0x0a, 0x7d, 0x02, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x02,
0x13, 0xb5, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x0c, 0x90, 0x01, 0x0c, 0xe0, 0x44, 0x02, 0xf0,
0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x85, 0x56, 0x41, 0xd2, 0x02, 0x22, 0x90, 0x70, 0x11, 0xe0, 0xf4,
0x70, 0x03, 0x02, 0x13, 0xbb, 0xe0, 0xf5, 0x30, 0x22, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x07,
0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0xbb, 0x90, 0x70, 0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x0a,
0x0d, 0x90, 0x70, 0x11, 0xe0, 0xb4, 0x08, 0x06, 0x75, 0x4e, 0x01, 0x75, 0x4f, 0x84, 0x90, 0x70,
0x10, 0xe0, 0x54, 0x7f, 0xff, 0xbf, 0x02, 0x12, 0x90, 0x70, 0x11, 0xe0, 0x64, 0x08, 0x60, 0x04,
0xe0, 0xb4, 0x20, 0x06, 0x75, 0x4e, 0x03, 0x75, 0x4f, 0x20, 0xe4, 0xf5, 0x27, 0x22, 0x90, 0x70,
0x11, 0xe0, 0x24, 0xff, 0x92, 0x47, 0x22, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x07, 0xe5, 0x55,
0x60, 0x03, 0x02, 0x13, 0x49, 0x90, 0x04, 0x04, 0xe0, 0x25, 0xe0, 0x24, 0x5d, 0xf5, 0x57, 0x90,
0x70, 0x10, 0xe0, 0xff, 0x74, 0x47, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0x90, 0x70, 0x11, 0xe0,
0xff, 0x74, 0x48, 0x25, 0x57, 0xf8, 0xc6, 0xef, 0xc6, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x82,
0x02, 0x13, 0xb5, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13,
0x49, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x1d, 0xe5, 0x47, 0x64, 0x08, 0x60, 0x17, 0xe5, 0x47, 0x64,
0x09, 0x60, 0x11, 0xe5, 0x47, 0x64, 0x0a, 0x60, 0x0b, 0xe5, 0x47, 0x64, 0x0b, 0x60, 0x05, 0xe5,
0x47, 0xb4, 0x0c, 0x08, 0x90, 0x70, 0x11, 0xe0, 0x54, 0x0f, 0xf5, 0x3a, 0xe5, 0x47, 0xb4, 0x09,
0x08, 0xe5, 0x3a, 0xb4, 0x03, 0x03, 0xe4, 0xf5, 0x46, 0xe5, 0x47, 0xb4, 0x0a, 0x08, 0xe5, 0x3a,
0xb4, 0x01, 0x03, 0xe4, 0xf5, 0x46, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x82, 0xd2, 0x04, 0x22,
0x90, 0x70, 0x11, 0xe0, 0xf4, 0xff, 0x90, 0x70, 0x10, 0xe0, 0x5f, 0xff, 0x90, 0x70, 0x11, 0xe0,
0x55, 0x27, 0x4f, 0x90, 0x70, 0x18, 0xf0, 0x90, 0x70, 0x11, 0xe0, 0x90, 0x70, 0x19, 0xf0, 0xe4,
0xfd, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x30, 0x15, 0x03, 0xd2, 0x14, 0x22, 0x90, 0x70, 0x18, 0xe0,
0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e, 0x90, 0x02,
0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90, 0x02, 0x28,
0xef, 0xf0, 0x22, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x07, 0xe5, 0x55, 0x60, 0x03, 0x02, 0x13,
0x49, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0, 0xfd, 0xed, 0xf8, 0xe6, 0xf5, 0x57,
0xfd, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x02, 0x13, 0xb5, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x07,
0xe5, 0x55, 0x60, 0x03, 0x02, 0x13, 0x49, 0x90, 0x70, 0x10, 0xe0, 0xfe, 0x90, 0x70, 0x11, 0xe0,
0xfd, 0xed, 0xf5, 0x82, 0x8e, 0x83, 0xe0, 0xf5, 0x57, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x02,
0x13, 0xb5, 0x90, 0x10, 0x00, 0xe0, 0xf5, 0x57, 0xe4, 0xf5, 0x58, 0xf5, 0x59, 0x90, 0x10, 0x03,
0xe0, 0xb4, 0x28, 0x05, 0x75, 0x58, 0x01, 0x80, 0x3c, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x30, 0x05,
0x75, 0x58, 0x02, 0x80, 0x30, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x33, 0x05, 0x75, 0x58, 0x04, 0x80,
0x24, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x35, 0x0c, 0x90, 0x10, 0x02, 0xe0, 0xb4, 0x72, 0x05, 0x75,
0x58, 0x08, 0x80, 0x11, 0x90, 0x10, 0x03, 0xe0, 0xb4, 0x35, 0x0a, 0x90, 0x10, 0x02, 0xe0, 0xb4,
0x93, 0x03, 0x75, 0x58, 0x10, 0xe5, 0x58, 0x30, 0xe1, 0x19, 0x90, 0x05, 0x08, 0xe0, 0x44, 0x01,
0xf0, 0xfd, 0x90, 0x05, 0x05, 0xe0, 0x54, 0xfb, 0xf0, 0x44, 0x04, 0xf0, 0xed, 0x54, 0xfe, 0x90,
0x05, 0x08, 0xf0, 0xe4, 0xf5, 0x4e, 0xf5, 0x4f, 0x75, 0x3a, 0xff, 0xc2, 0x1a, 0xc2, 0x18, 0xc2,
0x1b, 0xf5, 0x34, 0x90, 0x05, 0xa4, 0x74, 0x11, 0xf0, 0xa3, 0x74, 0xff, 0xf0, 0xa3, 0x74, 0x03,
0xf0, 0xe4, 0xf5, 0x30, 0xc2, 0x19, 0x90, 0x01, 0x0d, 0xe0, 0x44, 0x40, 0xf0, 0x75, 0x3c, 0xff,
0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x82, 0xe4, 0x90, 0x70, 0x32, 0xf0, 0x80, 0x77, 0xe5, 0x34,
0xd3, 0x94, 0x01, 0x40, 0x0b, 0xe5, 0x55, 0x60, 0x07, 0x7d, 0x03, 0xaf, 0x56, 0x02, 0x02, 0x82,
0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x93, 0xe4, 0xfd, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x80,
0x54, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x0d, 0xe5, 0x55, 0x60, 0x09, 0x7d, 0x03, 0xaf, 0x56,
0x12, 0x02, 0x82, 0x80, 0x40, 0x90, 0x70, 0x10, 0xe0, 0x24, 0xff, 0x92, 0x4a, 0xd2, 0x05, 0xad,
0x57, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x80, 0x2d, 0xe4, 0xf5, 0x34, 0xf5, 0x30, 0x90, 0x70, 0x10,
0xe0, 0xf4, 0x60, 0x03, 0xe0, 0xf5, 0x34, 0xad, 0x57, 0xaf, 0x56, 0x12, 0x02, 0x82, 0x80, 0x15,
0xd2, 0x19, 0x05, 0x2f, 0xe5, 0x2f, 0xb4, 0x1a, 0x03, 0xe4, 0xf5, 0x2f, 0xd2, 0x04, 0xad, 0x57,
0xaf, 0x56, 0x12, 0x02, 0x82, 0x90, 0x04, 0x14, 0x74, 0x80, 0xf0, 0x22, 0x22, 0xe5, 0x34, 0xc3,
0x94, 0x03, 0x40, 0x17, 0xe5, 0x55, 0xb4, 0x02, 0x12, 0xe5, 0x30, 0x60, 0x0e, 0x30, 0x60, 0x0b,
0x74, 0xfd, 0x25, 0x46, 0xf5, 0x46, 0xd2, 0x04, 0xe4, 0xf5, 0x53, 0xe5, 0x53, 0x60, 0x03, 0x02,
0x14, 0x71, 0x30, 0x60, 0x21, 0xb2, 0x4d, 0x30, 0x4d, 0x1c, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40,
0x11, 0xe5, 0x55, 0xb4, 0x02, 0x0c, 0xe5, 0x30, 0x60, 0x08, 0x74, 0x03, 0x25, 0x46, 0xf5, 0x46,
0x80, 0x02, 0x05, 0x46, 0xc2, 0x04, 0xe5, 0x4f, 0x45, 0x4e, 0x60, 0x08, 0xe5, 0x4f, 0x15, 0x4f,
0x70, 0x02, 0x15, 0x4e, 0x30, 0x1a, 0x49, 0x7f, 0x32, 0x7d, 0xb8, 0x7c, 0x0b, 0x12, 0x02, 0x35,
0x50, 0x06, 0x90, 0x04, 0x10, 0x74, 0x40, 0xf0, 0x7f, 0x35, 0x7d, 0x32, 0x12, 0x03, 0x3f, 0x50,
0x09, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf7, 0xf0, 0xd2, 0x06, 0xe5, 0x35, 0xd3, 0x94, 0x2d, 0x40,
0x30, 0x30, 0x1b, 0x2d, 0xc2, 0x1b, 0xa2, 0x18, 0x92, 0x1a, 0x20, 0x1a, 0x24, 0x90, 0x04, 0x09,
0xe0, 0x54, 0xdd, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x08, 0xf0, 0xc2, 0x61, 0xd2, 0x03, 0x22,
0xe4, 0xf5, 0x35, 0xa2, 0x18, 0x92, 0x1a, 0x30, 0x1a, 0x07, 0x90, 0x04, 0x09, 0xe0, 0x44, 0x22,
0xf0, 0x22, 0x22, 0x30, 0x14, 0x30, 0x90, 0x70, 0x19, 0xe0, 0x55, 0x27, 0xff, 0x90, 0x70, 0x18,
0xe0, 0x4f, 0xf5, 0x27, 0x90, 0x02, 0x29, 0xe0, 0xff, 0x90, 0x70, 0x19, 0xe0, 0xfe, 0xef, 0x5e,
0x90, 0x02, 0x29, 0xf0, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
0x02, 0x28, 0xef, 0xf0, 0xc2, 0x14, 0x22, 0xc2, 0x4b, 0xc2, 0x4c, 0xe5, 0x44, 0x12, 0x02, 0x5c,
0x14, 0xc9, 0x00, 0x15, 0x57, 0x04, 0x15, 0x53, 0x08, 0x15, 0x33, 0x10, 0x14, 0xdd, 0x20, 0x14,
0xfd, 0x60, 0x15, 0x0e, 0xa0, 0x00, 0x00, 0x15, 0x59, 0x85, 0x48, 0x43, 0x85, 0x4a, 0x42, 0x85,
0x4c, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x60, 0x03, 0x02, 0x15, 0x59, 0x80, 0x1b, 0xe5, 0x48, 0xc4,
0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4a, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4c, 0xc4, 0x54, 0x0f,
0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x61, 0x53, 0x43, 0x0f, 0x80, 0x5c, 0x85, 0x49, 0x43,
0x85, 0x4b, 0x42, 0x85, 0x4d, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x4d, 0x80, 0x1b, 0xe5, 0x49,
0xc4, 0x54, 0x0f, 0xf5, 0x43, 0xe5, 0x4b, 0xc4, 0x54, 0x0f, 0xf5, 0x42, 0xe5, 0x4d, 0xc4, 0x54,
0x0f, 0xf5, 0x5e, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x30, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x10, 0xf5,
0x43, 0x80, 0x26, 0xe5, 0x47, 0x64, 0x04, 0x60, 0x05, 0xe5, 0x47, 0xb4, 0x05, 0x06, 0x43, 0x5e,
0x04, 0x75, 0x42, 0x09, 0xe5, 0x47, 0xb4, 0x06, 0x10, 0xe5, 0x43, 0x54, 0x0f, 0x44, 0x30, 0xf5,
0x43, 0x80, 0x06, 0xd2, 0x4b, 0x80, 0x02, 0xd2, 0x4c, 0xe4, 0xf5, 0x2a, 0xe5, 0x42, 0xc4, 0x54,
0xf0, 0xff, 0xe5, 0x43, 0x54, 0x0f, 0x4f, 0xf5, 0x5f, 0xd2, 0x60, 0x22, 0xd2, 0x15, 0xe5, 0x47,
0x24, 0xf5, 0x60, 0x0b, 0x24, 0xcb, 0x60, 0x07, 0x24, 0x40, 0x70, 0x06, 0xc2, 0x15, 0x22, 0x12,
0x19, 0x15, 0x12, 0x15, 0x8e, 0xc2, 0x15, 0xc2, 0xaf, 0xc2, 0x04, 0xd2, 0xaf, 0x22, 0xc2, 0xaf,
0x90, 0x04, 0x14, 0xe0, 0x54, 0x0e, 0x60, 0x04, 0xd2, 0x1c, 0x80, 0x08, 0xe5, 0x4e, 0x45, 0x4f,
0x24, 0xff, 0x92, 0x1c, 0xd2, 0xaf, 0x90, 0x04, 0x14, 0xe0, 0xa2, 0xe4, 0x92, 0x1d, 0x74, 0x1e,
0xf0, 0xe5, 0x5f, 0x54, 0x0f, 0xf5, 0x2d, 0xe5, 0x2a, 0x70, 0x13, 0x30, 0x1c, 0x05, 0xe5, 0x5f,
0x20, 0xe5, 0x0b, 0x30, 0x1d, 0x29, 0xe5, 0x5f, 0x54, 0x30, 0x64, 0x30, 0x70, 0x21, 0xe5, 0x2a,
0x70, 0x15, 0xe5, 0x34, 0xc3, 0x94, 0x03, 0x40, 0x09, 0xe5, 0x30, 0x60, 0x05, 0x75, 0x2a, 0x05,
0x80, 0x07, 0x75, 0x2a, 0x0c, 0x80, 0x02, 0x15, 0x2a, 0xd2, 0x6c, 0xd2, 0x6d, 0x80, 0x0f, 0xe5,
0x5f, 0x30, 0xe6, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0xe5, 0x47,
0x64, 0x03, 0x70, 0x21, 0x30, 0x4b, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x18, 0xe5, 0x2a, 0x70,
0x03, 0x30, 0x4c, 0x11, 0xc2, 0x4c, 0xe5, 0x2a, 0x70, 0x05, 0x75, 0x2a, 0x07, 0x80, 0x02, 0x15,
0x2a, 0xd2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47, 0xb4, 0x09, 0x14, 0xe5, 0x44, 0x20, 0xe3, 0x0b, 0xe5,
0x3a, 0x64, 0x02, 0x60, 0x05, 0xe5, 0x3a, 0xb4, 0x03, 0x04, 0xc2, 0x6c, 0xd2, 0x6d, 0xe5, 0x47,
0xb4, 0x0a, 0x13, 0xe5, 0x3a, 0xb4, 0x01, 0x06, 0xc2, 0x6c, 0xd2, 0x6d, 0x80, 0x08, 0xe5, 0x3a,
0x70, 0x04, 0xd2, 0x6c, 0xc2, 0x6d, 0x20, 0x69, 0x07, 0xe5, 0x5e, 0x20, 0xe0, 0x02, 0xb2, 0x68,
0x20, 0x6b, 0x07, 0xe5, 0x5e, 0x20, 0xe1, 0x02, 0xb2, 0x6a, 0x20, 0x6d, 0x07, 0xe5, 0x5e, 0x20,
0xe2, 0x02, 0xb2, 0x6c, 0x75, 0x2e, 0x40, 0x20, 0x69, 0x04, 0xa2, 0x68, 0x80, 0x45, 0x30, 0x68,
0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f,
0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00,
0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe0, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f,
0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee,
0x6f, 0x24, 0xff, 0x92, 0x73, 0x92, 0x72, 0x20, 0x6b, 0x04, 0xa2, 0x6a, 0x80, 0x45, 0x30, 0x6a,
0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x3c, 0x30, 0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f,
0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x2f, 0xb4, 0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00,
0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d, 0xe5, 0x5e, 0x20, 0xe1, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f,
0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee,
0x6f, 0x24, 0xff, 0x92, 0x75, 0x92, 0x74, 0x20, 0x6d, 0x04, 0xa2, 0x6c, 0x80, 0x26, 0xe5, 0x47,
0x64, 0x0a, 0x70, 0x22, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x17, 0xe5, 0x3a, 0xb4,
0x01, 0x06, 0xe5, 0x46, 0xa2, 0xe3, 0x80, 0x53, 0xe5, 0x46, 0x20, 0xe4, 0x03, 0x30, 0xe5, 0x03,
0xd3, 0x80, 0x01, 0xc3, 0x80, 0x45, 0x30, 0x6c, 0x06, 0xe5, 0x46, 0xa2, 0xe2, 0x80, 0x3c, 0x30,
0x19, 0x1c, 0xe5, 0x5e, 0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x2f, 0xb4,
0x19, 0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x80, 0x1d, 0xe5, 0x5e,
0x20, 0xe2, 0x04, 0x7f, 0x01, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x46, 0x54, 0xf0, 0xfe, 0xbe, 0xf0,
0x04, 0x7e, 0x01, 0x80, 0x02, 0x7e, 0x00, 0xee, 0x6f, 0x24, 0xff, 0x92, 0x71, 0x92, 0x70, 0x90,
0x10, 0x00, 0xe0, 0x90, 0x10, 0x2c, 0xf0, 0x90, 0x10, 0x03, 0xe0, 0xc3, 0x94, 0x30, 0x40, 0x14,
0xa2, 0x71, 0x92, 0x77, 0xa2, 0x70, 0x92, 0x76, 0xe5, 0x2e, 0x13, 0x13, 0x54, 0x3f, 0xf5, 0x2e,
0xc2, 0x77, 0xd2, 0x76, 0x90, 0x10, 0x2f, 0xe5, 0x2e, 0xf0, 0xe5, 0x47, 0x64, 0x06, 0x70, 0x39,
0x90, 0x02, 0x29, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x43, 0xc4, 0x54, 0x0f, 0x14, 0x60, 0x0c, 0x24,
0xfe, 0x60, 0x0c, 0x24, 0x03, 0x70, 0x13, 0xc2, 0x38, 0x80, 0x0f, 0xd2, 0x38, 0x80, 0x0b, 0xe5,
0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x38, 0x30, 0x47, 0x05, 0xaf, 0x27, 0x02,
0x19, 0x0f, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x19, 0x0f, 0xe5, 0x47, 0x64, 0x07, 0x60, 0x0f, 0xe5,
0x47, 0x64, 0x08, 0x60, 0x09, 0xe5, 0x47, 0x64, 0x09, 0x60, 0x03, 0x02, 0x18, 0x8e, 0x90, 0x02,
0x29, 0xe0, 0x54, 0xfc, 0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x22, 0x14, 0x60, 0x25, 0x14, 0x60, 0x2d,
0x24, 0xfc, 0x60, 0x49, 0x24, 0xf9, 0x60, 0x14, 0x24, 0x0e, 0x70, 0x50, 0xe5, 0x46, 0x13, 0x13,
0x54, 0x3f, 0x75, 0xf0, 0x03, 0x84, 0xe5, 0xf0, 0x24, 0xff, 0x80, 0x3a, 0xd2, 0x39, 0xc2, 0x38,
0x80, 0x3e, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x1d, 0xc3, 0x80, 0x1a, 0xe5, 0x46, 0x30,
0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94, 0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e,
0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24, 0xff, 0x92, 0x38, 0xc2, 0x39, 0x80, 0x13, 0xe5, 0x46, 0x30,
0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39, 0xc2, 0x38, 0x80, 0x04, 0xc2, 0x38, 0xc2, 0x39,
0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x02, 0x19, 0x0f, 0xe5, 0x47,
0x64, 0x0c, 0x60, 0x06, 0xe5, 0x47, 0x64, 0x0b, 0x70, 0x7a, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xfd,
0xf0, 0xe5, 0x3a, 0x14, 0x60, 0x20, 0x14, 0x60, 0x21, 0x14, 0x60, 0x2b, 0x24, 0xfc, 0x60, 0x45,
0x24, 0xf9, 0x60, 0x12, 0x24, 0x0e, 0x70, 0x4a, 0xe5, 0x46, 0x13, 0x13, 0x54, 0x3f, 0x75, 0xf0,
0x03, 0x84, 0xe5, 0xf0, 0x80, 0x29, 0xd2, 0x39, 0x80, 0x3a, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3,
0x80, 0x01, 0xc3, 0x92, 0x39, 0x80, 0x2d, 0xe5, 0x46, 0x30, 0xe2, 0x0d, 0x54, 0x38, 0xc3, 0x94,
0x30, 0x50, 0x06, 0x7e, 0x00, 0x7f, 0x01, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xee, 0x4f, 0x24,
0xff, 0x92, 0x39, 0x80, 0x0f, 0xe5, 0x46, 0x30, 0xe2, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x92, 0x39,
0x80, 0x02, 0xc2, 0x39, 0x30, 0x47, 0x04, 0xaf, 0x27, 0x80, 0x04, 0xe5, 0x27, 0xf4, 0xff, 0x90,
0x02, 0x28, 0xef, 0xf0, 0x22, 0xe5, 0x47, 0xb4, 0x0b, 0x10, 0x90, 0x02, 0x29, 0xe0, 0x54, 0xeb,
0xf0, 0xe5, 0x27, 0x54, 0xeb, 0x45, 0x45, 0xf5, 0x27, 0x22, 0xe4, 0x90, 0x02, 0x29, 0xf0, 0x30,
0x47, 0x04, 0xaf, 0x45, 0x80, 0x04, 0xe5, 0x45, 0xf4, 0xff, 0x90, 0x02, 0x28, 0xef, 0xf0, 0x22,
0x8f, 0x50, 0xd2, 0x59, 0x22, 0x8f, 0x54, 0xd2, 0x58, 0x22, 0xe4, 0xf5, 0x37, 0xc2, 0xaf, 0xe5,
0x51, 0x14, 0x60, 0x4a, 0x14, 0x60, 0x6b, 0x24, 0x02, 0x60, 0x03, 0x02, 0x1a, 0xd5, 0xd2, 0x59,
0x75, 0x55, 0x01, 0x20, 0x1a, 0x1c, 0x90, 0x02, 0x08, 0xe0, 0x54, 0xfe, 0xf0, 0xe0, 0x20, 0xe1,
0x23, 0x90, 0x04, 0x34, 0xe0, 0xb4, 0x02, 0x1c, 0xa3, 0xe0, 0xb4, 0x02, 0x17, 0xa3, 0xe0, 0xb4,
0x02, 0x12, 0x7f, 0x20, 0x12, 0x19, 0x40, 0x90, 0x10, 0x04, 0xe0, 0x54, 0xf3, 0xf0, 0x75, 0x51,
0x01, 0x02, 0x1a, 0xd5, 0xe5, 0x50, 0x70, 0x06, 0x75, 0x37, 0x03, 0x02, 0x1a, 0xd5, 0x90, 0x12,
0x00, 0xe0, 0x54, 0x03, 0x70, 0x15, 0x7f, 0x20, 0x12, 0x19, 0x40, 0x20, 0x1a, 0x07, 0x90, 0x02,
0x08, 0xe0, 0x54, 0xfb, 0xf0, 0x75, 0x51, 0x02, 0x02, 0x1a, 0xd5, 0xe5, 0x50, 0x70, 0x03, 0x02,
0x1a, 0xd0, 0x20, 0x1a, 0x15, 0x90, 0x02, 0x08, 0xe0, 0x30, 0xe3, 0x03, 0x02, 0x1a, 0xcc, 0x90,
0x04, 0x37, 0xe0, 0x64, 0x22, 0x60, 0x03, 0x02, 0x1a, 0xcc, 0x90, 0x12, 0x04, 0x74, 0x0a, 0xf0,
0xe5, 0x58, 0x30, 0xe3, 0x15, 0xe4, 0x90, 0x05, 0x00, 0xf0, 0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74,
0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03, 0x30, 0x90, 0x13, 0x28, 0xe0, 0x90, 0x70,
0x1a, 0xf0, 0x90, 0x13, 0x29, 0xe0, 0x90, 0x70, 0x1b, 0xf0, 0x90, 0x13, 0x2b, 0xe0, 0x90, 0x70,
0x22, 0xf0, 0x90, 0x13, 0x28, 0xe0, 0x54, 0xf0, 0xf0, 0xa3, 0xe0, 0x54, 0xf0, 0xf0, 0x90, 0x13,
0x2b, 0xe0, 0x54, 0xcc, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x17, 0xe5, 0x34, 0x70, 0x13, 0xe5, 0x3c,
0xf4, 0x90, 0x13, 0x2a, 0x60, 0x05, 0xe0, 0x54, 0xf3, 0x80, 0x11, 0xe0, 0x54, 0xfb, 0xf0, 0x80,
0x14, 0xe5, 0x3c, 0xf4, 0x90, 0x13, 0x2a, 0x60, 0x08, 0xe0, 0x54, 0xf2, 0x45, 0x3c, 0xf0, 0x80,
0x04, 0xe0, 0x54, 0xfa, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x10, 0xf0, 0xe5,
0x34, 0xd3, 0x94, 0x01, 0x40, 0x09, 0xe5, 0x30, 0x70, 0x05, 0x75, 0x8c, 0x40, 0x80, 0x03, 0x75,
0x8c, 0x80, 0x90, 0x04, 0x01, 0xe0, 0x54, 0xfd, 0xf0, 0x20, 0x1a, 0x07, 0x90, 0x12, 0x04, 0xe0,
0x44, 0x04, 0xf0, 0xe5, 0x58, 0x30, 0xe0, 0x06, 0x90, 0x01, 0x0d, 0xe0, 0xf5, 0x31, 0xe5, 0x34,
0xd3, 0x94, 0x01, 0x40, 0x2c, 0x90, 0x01, 0x0d, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x58, 0x20, 0xe3,
0x0c, 0xe5, 0x34, 0xb4, 0x03, 0x07, 0x90, 0x12, 0x04, 0xe0, 0x54, 0xfd, 0xf0, 0x20, 0x02, 0x11,
0x20, 0x03, 0x0e, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x01, 0x0c, 0xe0, 0x54, 0xfd,
0xf0, 0x75, 0x37, 0x01, 0x75, 0x55, 0x02, 0xe4, 0xf5, 0x51, 0x80, 0x09, 0xe5, 0x50, 0x70, 0x05,
0x75, 0x37, 0x03, 0xf5, 0x51, 0xe5, 0x37, 0x60, 0x18, 0xc2, 0x01, 0xe4, 0xf5, 0x51, 0xc2, 0x59,
0x20, 0x1a, 0x0e, 0xad, 0x37, 0xaf, 0x40, 0x12, 0x1b, 0xfa, 0xe5, 0x37, 0xb4, 0x03, 0x02, 0xd2,
0x03, 0xd2, 0xaf, 0x22, 0xc2, 0xaf, 0x30, 0x01, 0x0e, 0xe4, 0xf5, 0x51, 0xc2, 0x59, 0xc2, 0x01,
0x7d, 0x02, 0xaf, 0x40, 0x12, 0x1b, 0xfa, 0xe5, 0x52, 0x14, 0x60, 0x56, 0x14, 0x60, 0x33, 0x24,
0x02, 0x60, 0x03, 0x02, 0x1b, 0xf7, 0xe5, 0x34, 0xd3, 0x94, 0x01, 0x40, 0x1f, 0x90, 0x01, 0x0c,
0xe0, 0x44, 0x02, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x12, 0x04, 0xe0, 0x44, 0x02, 0xf0,
0x7f, 0x32, 0x12, 0x03, 0x30, 0x90, 0x01, 0x0d, 0xe0, 0x54, 0xfe, 0xf0, 0x75, 0x52, 0x02, 0x75,
0x55, 0x03, 0xe5, 0x58, 0x30, 0xe0, 0x06, 0x90, 0x01, 0x0d, 0xe5, 0x31, 0xf0, 0x90, 0x12, 0x04,
0xe0, 0x54, 0xfb, 0xf0, 0x7f, 0x20, 0x12, 0x19, 0x45, 0x75, 0x52, 0x01, 0x75, 0x55, 0x03, 0x02,
0x1b, 0xf7, 0xe5, 0x54, 0x60, 0x03, 0x02, 0x1b, 0xf7, 0x90, 0x04, 0x01, 0xe0, 0x44, 0x0e, 0xf0,
0x20, 0x1a, 0x04, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0xf5, 0x8c, 0xe5, 0x58, 0x54, 0x18, 0x60, 0x1e,
0x90, 0x70, 0x1a, 0xe0, 0x90, 0x13, 0x28, 0xf0, 0x90, 0x70, 0x1b, 0xe0, 0x90, 0x13, 0x29, 0xf0,
0xa3, 0x74, 0x05, 0xf0, 0x90, 0x70, 0x22, 0xe0, 0x90, 0x13, 0x2b, 0xf0, 0x80, 0x11, 0x90, 0x13,
0x28, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x0f, 0xf0, 0xa3, 0xe0, 0x44, 0x05, 0xf0, 0x90,
0x12, 0x04, 0x74, 0x03, 0xf0, 0xe5, 0x58, 0x30, 0xe3, 0x16, 0x90, 0x05, 0x00, 0x74, 0xe2, 0xf0,
0xa3, 0x74, 0x08, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0x74, 0x03, 0xf0, 0x7f, 0x01, 0x12, 0x03, 0x30,
0x20, 0x1a, 0x07, 0x90, 0x02, 0x08, 0xe0, 0x44, 0x05, 0xf0, 0x90, 0x10, 0x04, 0xe0, 0x44, 0x0c,
0xf0, 0xe4, 0xf5, 0x52, 0xf5, 0x55, 0x30, 0x02, 0x09, 0xc2, 0x02, 0x7d, 0x01, 0xaf, 0x41, 0x12,
0x1b, 0xfa, 0x30, 0x03, 0x02, 0xc2, 0x03, 0xd2, 0xaf, 0x22, 0xef, 0xf4, 0x60, 0x2d, 0xe4, 0xfe,
0x74, 0x14, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x19, 0x74, 0x14,
0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x70, 0xf5, 0x83, 0xef, 0xf0, 0x74, 0x1c, 0x2e, 0xf5, 0x82, 0xe4,
0x34, 0x70, 0xf5, 0x83, 0xed, 0xf0, 0x22, 0x0e, 0xbe, 0x04, 0xd5, 0x22, 0x22, 0x22, 0x30, 0x1a,
0x77, 0x90, 0x04, 0x37, 0xe0, 0x20, 0xe5, 0x6c, 0x90, 0x04, 0x28, 0xe0, 0xf5, 0x38, 0xa3, 0xe0,
0xf5, 0x37, 0xf5, 0x39, 0xe4, 0xf5, 0x25, 0xe5, 0x39, 0x75, 0xf0, 0x80, 0xa4, 0x24, 0x00, 0xff,
0xe5, 0xf0, 0x34, 0x80, 0xfe, 0xe5, 0x37, 0x65, 0x39, 0x70, 0x05, 0xfc, 0x7d, 0x28, 0x80, 0x04,
0x7c, 0x00, 0x7d, 0x00, 0xef, 0x2d, 0xff, 0xee, 0x3c, 0xfe, 0x12, 0x1c, 0xa9, 0x50, 0x07, 0x90,
0x01, 0x14, 0xe0, 0x44, 0x02, 0xf0, 0xe5, 0x39, 0x65, 0x38, 0x60, 0x10, 0xe4, 0x25, 0x39, 0xff,
0xe4, 0x34, 0x80, 0x8f, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x39, 0x80, 0xbb, 0x90, 0x04, 0x10, 0x74,
0x01, 0xf0, 0x90, 0x04, 0x28, 0xe5, 0x38, 0xf0, 0xa3, 0xe5, 0x37, 0xf0, 0x90, 0x04, 0x11, 0x74,
0x01, 0xf0, 0x80, 0x8d, 0xc2, 0x06, 0xd2, 0x1b, 0x22, 0xe5, 0x25, 0xc3, 0x94, 0x06, 0x50, 0x19,
0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xb4, 0xff, 0x07, 0x05, 0x25, 0xe4, 0xf5, 0x24, 0x80, 0x2e, 0xe4,
0xf5, 0x25, 0x8f, 0x82, 0x8e, 0x83, 0xf0, 0x80, 0x24, 0xe5, 0x24, 0x75, 0xf0, 0x06, 0x84, 0x74,
0x08, 0x25, 0xf0, 0xf5, 0x82, 0xe4, 0x34, 0x10, 0xf5, 0x83, 0xe0, 0xfd, 0x8f, 0x82, 0x8e, 0x83,
0xe0, 0x6d, 0x70, 0x06, 0x05, 0x25, 0x05, 0x24, 0x80, 0x03, 0xe4, 0xf5, 0x25, 0x0f, 0xbf, 0x00,
0x01, 0x0e, 0xef, 0x54, 0x7f, 0x60, 0x07, 0xe5, 0x25, 0xc3, 0x94, 0x2a, 0x40, 0xab, 0xe5, 0x25,
0xb4, 0x2a, 0x03, 0xd3, 0x80, 0x01, 0xc3, 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, 0x1a, 0x53, 0x88,
};
#endif /* #ifndef _RT2860_UCODE_H_ */