From 3569e353ca63336d80ab0143dd9669b0b9e6b123 Mon Sep 17 00:00:00 2001 From: sam Date: Sun, 20 Apr 2008 20:35:46 +0000 Subject: Multi-bss (aka vap) support for 802.11 devices. Note this includes changes to all drivers and moves some device firmware loading to use firmware(9) and a separate module (e.g. ral). Also there no longer are separate wlan_scan* modules; this functionality is now bundled into the wlan module. Supported by: Hobnob and Marvell Reviewed by: many Obtained from: Atheros (some bits) --- sys/dev/ath/ah_osdep.c | 2 +- sys/dev/ath/ah_osdep.h | 2 +- sys/dev/ath/ath_rate/amrr/amrr.c | 146 +- sys/dev/ath/ath_rate/amrr/amrr.h | 4 +- sys/dev/ath/ath_rate/onoe/onoe.c | 117 +- sys/dev/ath/ath_rate/onoe/onoe.h | 5 +- sys/dev/ath/ath_rate/sample/sample.c | 132 +- sys/dev/ath/ath_rate/sample/sample.h | 3 +- sys/dev/ath/if_ath.c | 2181 ++++++++++------- sys/dev/ath/if_ath_pci.c | 2 +- sys/dev/ath/if_athioctl.h | 2 +- sys/dev/ath/if_athrate.h | 4 +- sys/dev/ath/if_athvar.h | 118 +- sys/dev/if_ndis/if_ndis.c | 549 ++--- sys/dev/if_ndis/if_ndisvar.h | 9 +- sys/dev/ipw/if_ipw.c | 1041 ++++---- sys/dev/ipw/if_ipwvar.h | 52 +- sys/dev/iwi/if_iwi.c | 1072 ++++----- sys/dev/iwi/if_iwivar.h | 65 +- sys/dev/malo/if_malo.c | 597 ++--- sys/dev/malo/if_malo.h | 14 +- sys/dev/ral/if_ral_pci.c | 4 +- sys/dev/ral/if_ralrate.c | 192 -- sys/dev/ral/if_ralrate.h | 98 - sys/dev/ral/rt2560.c | 1221 +++++----- sys/dev/ral/rt2560reg.h | 2 + sys/dev/ral/rt2560var.h | 46 +- sys/dev/ral/rt2661.c | 1249 +++++----- sys/dev/ral/rt2661_ucode.h | 2268 ------------------ sys/dev/ral/rt2661var.h | 48 +- sys/dev/usb/if_rum.c | 978 ++++---- sys/dev/usb/if_rumvar.h | 45 +- sys/dev/usb/if_ural.c | 949 ++++---- sys/dev/usb/if_uralvar.h | 45 +- sys/dev/usb/if_zyd.c | 559 +++-- sys/dev/usb/if_zydreg.h | 21 +- sys/dev/wi/if_wavelan_ieee.h | 3 + sys/dev/wi/if_wi.c | 2869 ++++++---------------- sys/dev/wi/if_wi_pccard.c | 63 +- sys/dev/wi/if_wi_pci.c | 7 +- sys/dev/wi/if_wivar.h | 102 +- sys/dev/wi/spectrum24t_cf.h | 4327 ---------------------------------- sys/dev/wpi/if_wpi.c | 747 +++--- sys/dev/wpi/if_wpivar.h | 46 +- 44 files changed, 6630 insertions(+), 15376 deletions(-) delete mode 100644 sys/dev/ral/if_ralrate.c delete mode 100644 sys/dev/ral/if_ralrate.h delete mode 100644 sys/dev/ral/rt2661_ucode.h delete mode 100644 sys/dev/wi/spectrum24t_cf.h (limited to 'sys/dev') diff --git a/sys/dev/ath/ah_osdep.c b/sys/dev/ath/ah_osdep.c index dcc5765..249c260 100644 --- a/sys/dev/ath/ah_osdep.c +++ b/sys/dev/ath/ah_osdep.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/ath/ah_osdep.h b/sys/dev/ath/ah_osdep.h index a82bd02..2e2a561 100644 --- a/sys/dev/ath/ah_osdep.h +++ b/sys/dev/ath/ah_osdep.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/ath/ath_rate/amrr/amrr.c b/sys/dev/ath/ath_rate/amrr/amrr.c index 00ae568..c230bdf 100644 --- a/sys/dev/ath/ath_rate/amrr/amrr.c +++ b/sys/dev/ath/ath_rate/amrr/amrr.c @@ -46,6 +46,7 @@ __FBSDID("$FreeBSD$"); * Mathieu Lacage, Hossein Manshaei, Thierry Turletti */ #include "opt_inet.h" +#include "opt_wlan.h" #include #include @@ -65,7 +66,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include /* XXX for ether_sprintf */ #include @@ -80,21 +80,10 @@ __FBSDID("$FreeBSD$"); #include #include -#define AMRR_DEBUG -#ifdef AMRR_DEBUG -#define DPRINTF(sc, _fmt, ...) do { \ - if (sc->sc_debug & 0x10) \ - printf(_fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(sc, _fmt, ...) -#endif - static int ath_rateinterval = 1000; /* rate ctl interval (ms) */ static int ath_rate_max_success_threshold = 10; static int ath_rate_min_success_threshold = 1; -static void ath_ratectl(void *); static void ath_rate_update(struct ath_softc *, struct ieee80211_node *, int rate); static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); @@ -104,7 +93,6 @@ void ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) { /* NB: assumed to be zero'd by caller */ - ath_rate_update(sc, &an->an_node, 0); } void @@ -166,6 +154,11 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, amn->amn_tx_try3_cnt++; amn->amn_tx_failure_cnt++; } + if (amn->amn_interval != 0 && + ticks - amn->amn_ticks > amn->amn_interval) { + ath_rate_ctl(sc, &an->an_node); + amn->amn_ticks = ticks; + } } void @@ -176,7 +169,7 @@ ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) } static void -node_reset (struct amrr_node *amn) +node_reset(struct amrr_node *amn) { amn->amn_tx_try0_cnt = 0; amn->amn_tx_try1_cnt = 0; @@ -200,17 +193,18 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) { struct ath_node *an = ATH_NODE(ni); struct amrr_node *amn = ATH_NODE_AMRR(an); + struct ieee80211vap *vap = ni->ni_vap; const HAL_RATE_TABLE *rt = sc->sc_currates; u_int8_t rix; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); - DPRINTF(sc, "%s: set xmit rate for %s to %dM\n", - __func__, ether_sprintf(ni->ni_macaddr), + IEEE80211_NOTE(vap, IEEE80211_MSG_RATECTL, ni, + "%s: set xmit rate to %dM", __func__, ni->ni_rates.rs_nrates > 0 ? (ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0); - ni->ni_txrate = rate; + amn->amn_rix = rate; /* * Before associating a node has no rate set setup * so we can't calculate any transmit codes to use. @@ -219,8 +213,8 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) * lowest hardware rate. */ if (ni->ni_rates.rs_nrates > 0) { - amn->amn_tx_rix0 = sc->sc_rixmap[ - ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL]; + ni->ni_txrate = ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL; + amn->amn_tx_rix0 = sc->sc_rixmap[ni->ni_txrate]; amn->amn_tx_rate0 = rt->info[amn->amn_tx_rix0].rateCode; amn->amn_tx_rate0sp = amn->amn_tx_rate0 | rt->info[amn->amn_tx_rix0].shortPreamble; @@ -268,7 +262,12 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) amn->amn_tx_rate3 = amn->amn_tx_rate3sp = 0; } } - node_reset (amn); + node_reset(amn); + + amn->amn_interval = ath_rateinterval; + if (vap->iv_opmode == IEEE80211_M_STA) + amn->amn_interval /= 2; + amn->amn_interval = (amn->amn_interval * hz) / 1000; } /* @@ -278,11 +277,12 @@ static void ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ath_node *an = ATH_NODE(ni); + const struct ieee80211_txparam *tp = an->an_tp; int srate; KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { + if (tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { /* * No fixed rate is requested. For 11b start with * the highest negotiated rate; otherwise, for 11g @@ -308,7 +308,7 @@ ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) */ /* NB: the rate set is assumed sorted */ srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != ic->ic_fixed_rate; srate--) + for (; srate >= 0 && RATE(srate) != tp->ucastrate; srate--) ; } /* @@ -333,22 +333,20 @@ ath_rate_cb(void *arg, struct ieee80211_node *ni) * Reset the rate control state for each 802.11 state transition. */ void -ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) +ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state) { - struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = vap->iv_ic; + struct ath_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_node *ni; - if (state == IEEE80211_S_INIT) { - callout_stop(&asc->timer); + if (state == IEEE80211_S_INIT) return; - } - if (ic->ic_opmode == IEEE80211_M_STA) { + if (vap->iv_opmode == IEEE80211_M_STA) { /* * Reset local xmit state; this is really only * meaningful when operating in station mode. */ - ni = ic->ic_bss; + ni = vap->iv_bss; if (state == IEEE80211_S_RUN) { ath_rate_ctl_start(sc, ni); } else { @@ -362,20 +360,7 @@ ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) * tx rate state of each node. */ ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc); - ath_rate_update(sc, ic->ic_bss, 0); - } - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE && - state == IEEE80211_S_RUN) { - int interval; - /* - * Start the background rate control thread if we - * are not configured to use a fixed xmit rate. - */ - interval = ath_rateinterval; - if (ic->ic_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&asc->timer, (interval * hz) / 1000, - ath_ratectl, sc->sc_ifp); + ath_rate_update(sc, vap->iv_bss, 0); } } @@ -387,7 +372,7 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) { struct ath_softc *sc = arg; struct amrr_node *amn = ATH_NODE_AMRR(ATH_NODE (ni)); - int old_rate; + int rix; #define is_success(amn) \ (amn->amn_tx_try1_cnt < (amn->amn_tx_try0_cnt/10)) @@ -395,52 +380,53 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) (amn->amn_tx_try0_cnt > 10) #define is_failure(amn) \ (amn->amn_tx_try1_cnt > (amn->amn_tx_try0_cnt/3)) -#define is_max_rate(ni) \ -((ni->ni_txrate + 1) >= ni->ni_rates.rs_nrates) -#define is_min_rate(ni) \ -(ni->ni_txrate == 0) - old_rate = ni->ni_txrate; + rix = amn->amn_rix; - DPRINTF (sc, "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d\n", - amn->amn_tx_try0_cnt, - amn->amn_tx_try1_cnt, - amn->amn_tx_try2_cnt, - amn->amn_tx_try3_cnt, - amn->amn_success_threshold); + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "cnt0: %d cnt1: %d cnt2: %d cnt3: %d -- threshold: %d", + amn->amn_tx_try0_cnt, amn->amn_tx_try1_cnt, amn->amn_tx_try2_cnt, + amn->amn_tx_try3_cnt, amn->amn_success_threshold); if (is_success (amn) && is_enough (amn)) { amn->amn_success++; if (amn->amn_success == amn->amn_success_threshold && - !is_max_rate (ni)) { + rix + 1 < ni->ni_rates.rs_nrates) { amn->amn_recovery = 1; amn->amn_success = 0; - ni->ni_txrate++; - DPRINTF (sc, "increase rate to %d\n", ni->ni_txrate); + rix++; + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "increase rate to %d", rix); } else { amn->amn_recovery = 0; } } else if (is_failure (amn)) { amn->amn_success = 0; - if (!is_min_rate (ni)) { + if (rix > 0) { if (amn->amn_recovery) { /* recovery failure. */ amn->amn_success_threshold *= 2; amn->amn_success_threshold = min (amn->amn_success_threshold, (u_int)ath_rate_max_success_threshold); - DPRINTF (sc, "decrease rate recovery thr: %d\n", amn->amn_success_threshold); + IEEE80211_NOTE(ni->ni_vap, + IEEE80211_MSG_RATECTL, ni, + "decrease rate recovery thr: %d", + amn->amn_success_threshold); } else { /* simple failure. */ amn->amn_success_threshold = ath_rate_min_success_threshold; - DPRINTF (sc, "decrease rate normal thr: %d\n", amn->amn_success_threshold); + IEEE80211_NOTE(ni->ni_vap, + IEEE80211_MSG_RATECTL, ni, + "decrease rate normal thr: %d", + amn->amn_success_threshold); } amn->amn_recovery = 0; - ni->ni_txrate--; + rix--; } else { amn->amn_recovery = 0; } } - if (is_enough (amn) || old_rate != ni->ni_txrate) { + if (is_enough (amn) || rix != amn->amn_rix) { /* reset counters. */ amn->amn_tx_try0_cnt = 0; amn->amn_tx_try1_cnt = 0; @@ -448,33 +434,9 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) amn->amn_tx_try3_cnt = 0; amn->amn_tx_failure_cnt = 0; } - if (old_rate != ni->ni_txrate) { - ath_rate_update(sc, ni, ni->ni_txrate); - } -} - -static void -ath_ratectl(void *arg) -{ - struct ifnet *ifp = arg; - struct ath_softc *sc = ifp->if_softc; - struct amrr_softc *asc = (struct amrr_softc *) sc->sc_rc; - struct ieee80211com *ic = &sc->sc_ic; - int interval; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - sc->sc_stats.ast_rate_calls++; - - if (ic->ic_opmode == IEEE80211_M_STA) - ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */ - else - ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc); + if (rix != amn->amn_rix) { + ath_rate_update(sc, ni, rix); } - interval = ath_rateinterval; - if (ic->ic_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&asc->timer, (interval * hz) / 1000, - ath_ratectl, sc->sc_ifp); } static void @@ -504,7 +466,6 @@ ath_rate_attach(struct ath_softc *sc) if (asc == NULL) return NULL; asc->arc.arc_space = sizeof(struct amrr_node); - callout_init(&asc->timer, CALLOUT_MPSAFE); ath_rate_sysctlattach(sc); return &asc->arc; @@ -515,7 +476,6 @@ ath_rate_detach(struct ath_ratectrl *arc) { struct amrr_softc *asc = (struct amrr_softc *) arc; - callout_drain(&asc->timer); free(asc, M_DEVBUF); } diff --git a/sys/dev/ath/ath_rate/amrr/amrr.h b/sys/dev/ath/ath_rate/amrr/amrr.h index cb5d135..c97a007 100644 --- a/sys/dev/ath/ath_rate/amrr/amrr.h +++ b/sys/dev/ath/ath_rate/amrr/amrr.h @@ -43,11 +43,13 @@ /* per-device state */ struct amrr_softc { struct ath_ratectrl arc; /* base state */ - struct callout timer; /* periodic timer */ }; /* per-node state */ struct amrr_node { + int amn_rix; /* current rate index */ + int amn_ticks; /* time of last update */ + int amn_interval; /* update interval (ticks) */ /* AMRR statistics for this node */ u_int amn_tx_try0_cnt; u_int amn_tx_try1_cnt; diff --git a/sys/dev/ath/ath_rate/onoe/onoe.c b/sys/dev/ath/ath_rate/onoe/onoe.c index eb5759e..25bac09 100644 --- a/sys/dev/ath/ath_rate/onoe/onoe.c +++ b/sys/dev/ath/ath_rate/onoe/onoe.c @@ -34,6 +34,7 @@ __FBSDID("$FreeBSD$"); * Atsushi Onoe's rate control algorithm. */ #include "opt_inet.h" +#include "opt_wlan.h" #include #include @@ -68,19 +69,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define ONOE_DEBUG -#ifdef ONOE_DEBUG -enum { - ATH_DEBUG_RATE = 0x00000010, /* rate control */ -}; -#define DPRINTF(sc, _fmt, ...) do { \ - if (sc->sc_debug & ATH_DEBUG_RATE) \ - printf(_fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(sc, _fmt, ...) -#endif - /* * Default parameters for the rate control algorithm. These are * all tunable with sysctls. The rate controller runs periodically @@ -104,7 +92,6 @@ static int ath_rateinterval = 1000; /* rate ctl interval (ms) */ static int ath_rate_raise = 10; /* add credit threshold */ static int ath_rate_raise_threshold = 10; /* rate ctl raise threshold */ -static void ath_ratectl(void *); static void ath_rate_update(struct ath_softc *, struct ieee80211_node *, int rate); static void ath_rate_ctl_start(struct ath_softc *, struct ieee80211_node *); @@ -114,7 +101,6 @@ void ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) { /* NB: assumed to be zero'd by caller */ - ath_rate_update(sc, &an->an_node, 0); } void @@ -163,6 +149,10 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, on->on_tx_err++; on->on_tx_retr += ts->ts_shortretry + ts->ts_longretry; + if (on->on_interval != 0 && ticks - on->on_ticks > on->on_interval) { + ath_rate_ctl(sc, &an->an_node); + on->on_ticks = ticks; + } } void @@ -177,17 +167,17 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) { struct ath_node *an = ATH_NODE(ni); struct onoe_node *on = ATH_NODE_ONOE(an); + struct ieee80211vap *vap = ni->ni_vap; const HAL_RATE_TABLE *rt = sc->sc_currates; u_int8_t rix; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); - DPRINTF(sc, "%s: set xmit rate for %s to %dM\n", - __func__, ether_sprintf(ni->ni_macaddr), - ni->ni_rates.rs_nrates > 0 ? + IEEE80211_NOTE(vap, IEEE80211_MSG_RATECTL, ni, + "%s: set xmit rate to %dM", __func__, + ni->ni_rates.rs_nrates > 0 ? (ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL) / 2 : 0); - ni->ni_txrate = rate; /* * Before associating a node has no rate set setup * so we can't calculate any transmit codes to use. @@ -197,8 +187,9 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) */ if (ni->ni_rates.rs_nrates == 0) goto done; - on->on_tx_rix0 = sc->sc_rixmap[ - ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL]; + on->on_rix = rate; + ni->ni_txrate = ni->ni_rates.rs_rates[rate] & IEEE80211_RATE_VAL; + on->on_tx_rix0 = sc->sc_rixmap[ni->ni_txrate]; on->on_tx_rate0 = rt->info[on->on_tx_rix0].rateCode; on->on_tx_rate0sp = on->on_tx_rate0 | @@ -246,6 +237,11 @@ ath_rate_update(struct ath_softc *sc, struct ieee80211_node *ni, int rate) } done: on->on_tx_ok = on->on_tx_err = on->on_tx_retr = on->on_tx_upper = 0; + + on->on_interval = ath_rateinterval; + if (vap->iv_opmode == IEEE80211_M_STA) + on->on_interval /= 2; + on->on_interval = (on->on_interval * hz) / 1000; } /* @@ -255,11 +251,12 @@ static void ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ath_node *an = ATH_NODE(ni); + const struct ieee80211_txparam *tp = an->an_tp; int srate; KASSERT(ni->ni_rates.rs_nrates > 0, ("no rates")); - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { + if (tp == NULL || tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { /* * No fixed rate is requested. For 11b start with * the highest negotiated rate; otherwise, for 11g @@ -285,7 +282,7 @@ ath_rate_ctl_start(struct ath_softc *sc, struct ieee80211_node *ni) */ /* NB: the rate set is assumed sorted */ srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != ic->ic_fixed_rate; srate--) + for (; srate >= 0 && RATE(srate) != tp->ucastrate; srate--) ; } /* @@ -310,22 +307,20 @@ ath_rate_cb(void *arg, struct ieee80211_node *ni) * Reset the rate control state for each 802.11 state transition. */ void -ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) +ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state) { - struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = vap->iv_ic; + struct ath_softc *sc = ic->ic_ifp->if_softc; struct ieee80211_node *ni; - if (state == IEEE80211_S_INIT) { - callout_stop(&osc->timer); + if (state == IEEE80211_S_INIT) return; - } - if (ic->ic_opmode == IEEE80211_M_STA) { + if (vap->iv_opmode == IEEE80211_M_STA) { /* * Reset local xmit state; this is really only * meaningful when operating in station mode. */ - ni = ic->ic_bss; + ni = vap->iv_bss; if (state == IEEE80211_S_RUN) { ath_rate_ctl_start(sc, ni); } else { @@ -339,20 +334,7 @@ ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) * tx rate state of each node. */ ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_cb, sc); - ath_rate_update(sc, ic->ic_bss, 0); - } - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE && - state == IEEE80211_S_RUN) { - int interval; - /* - * Start the background rate control thread if we - * are not configured to use a fixed xmit rate. - */ - interval = ath_rateinterval; - if (ic->ic_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&osc->timer, (interval * hz) / 1000, - ath_ratectl, sc->sc_ifp); + ath_rate_update(sc, vap->iv_bss, 0); } } @@ -386,12 +368,11 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) on->on_tx_retr < (on->on_tx_ok * ath_rate_raise) / 100) dir = 1; - DPRINTF(sc, "%s: ok %d err %d retr %d upper %d dir %d\n", - ether_sprintf(ni->ni_macaddr), - on->on_tx_ok, on->on_tx_err, on->on_tx_retr, - on->on_tx_upper, dir); + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "ok %d err %d retr %d upper %d dir %d", + on->on_tx_ok, on->on_tx_err, on->on_tx_retr, on->on_tx_upper, dir); - nrate = ni->ni_txrate; + nrate = on->on_rix; switch (dir) { case 0: if (enough && on->on_tx_upper > 0) @@ -416,10 +397,10 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) break; } - if (nrate != ni->ni_txrate) { - DPRINTF(sc, "%s: %dM -> %dM (%d ok, %d err, %d retr)\n", - __func__, - (rs->rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL) / 2, + if (nrate != on->on_rix) { + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "%s: %dM -> %dM (%d ok, %d err, %d retr)", __func__, + ni->ni_txrate / 2, (rs->rs_rates[nrate] & IEEE80211_RATE_VAL) / 2, on->on_tx_ok, on->on_tx_err, on->on_tx_retr); ath_rate_update(sc, ni, nrate); @@ -428,30 +409,6 @@ ath_rate_ctl(void *arg, struct ieee80211_node *ni) } static void -ath_ratectl(void *arg) -{ - struct ifnet *ifp = arg; - struct ath_softc *sc = ifp->if_softc; - struct onoe_softc *osc = (struct onoe_softc *) sc->sc_rc; - struct ieee80211com *ic = &sc->sc_ic; - int interval; - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - sc->sc_stats.ast_rate_calls++; - - if (ic->ic_opmode == IEEE80211_M_STA) - ath_rate_ctl(sc, ic->ic_bss); /* NB: no reference */ - else - ieee80211_iterate_nodes(&ic->ic_sta, ath_rate_ctl, sc); - } - interval = ath_rateinterval; - if (ic->ic_opmode == IEEE80211_M_STA) - interval /= 2; - callout_reset(&osc->timer, (interval * hz) / 1000, - ath_ratectl, sc->sc_ifp); -} - -static void ath_rate_sysctlattach(struct ath_softc *sc) { struct sysctl_ctx_list *ctx = device_get_sysctl_ctx(sc->sc_dev); @@ -478,7 +435,6 @@ ath_rate_attach(struct ath_softc *sc) if (osc == NULL) return NULL; osc->arc.arc_space = sizeof(struct onoe_node); - callout_init(&osc->timer, CALLOUT_MPSAFE); ath_rate_sysctlattach(sc); return &osc->arc; @@ -489,7 +445,6 @@ ath_rate_detach(struct ath_ratectrl *arc) { struct onoe_softc *osc = (struct onoe_softc *) arc; - callout_drain(&osc->timer); free(osc, M_DEVBUF); } diff --git a/sys/dev/ath/ath_rate/onoe/onoe.h b/sys/dev/ath/ath_rate/onoe/onoe.h index 4eef862..27bbe94 100644 --- a/sys/dev/ath/ath_rate/onoe/onoe.h +++ b/sys/dev/ath/ath_rate/onoe/onoe.h @@ -38,11 +38,14 @@ /* per-device state */ struct onoe_softc { struct ath_ratectrl arc; /* base state */ - struct callout timer; /* periodic timer */ }; /* per-node state */ struct onoe_node { + int on_rix; /* current rate index */ + int on_ticks; /* time of last update */ + int on_interval; /* update interval (ticks) */ + u_int on_tx_ok; /* tx ok pkt */ u_int on_tx_err; /* tx !ok pkt */ u_int on_tx_retr; /* tx retry count */ diff --git a/sys/dev/ath/ath_rate/sample/sample.c b/sys/dev/ath/ath_rate/sample/sample.c index 180ef82..60a81ed 100644 --- a/sys/dev/ath/ath_rate/sample/sample.c +++ b/sys/dev/ath/ath_rate/sample/sample.c @@ -42,6 +42,7 @@ __FBSDID("$FreeBSD$"); * John Bicket's SampleRate control algorithm. */ #include "opt_inet.h" +#include "opt_wlan.h" #include #include @@ -61,7 +62,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#include /* XXX for ether_sprintf */ #include @@ -76,23 +76,6 @@ __FBSDID("$FreeBSD$"); #include #include -#define SAMPLE_DEBUG -#ifdef SAMPLE_DEBUG -enum { - ATH_DEBUG_NODE = 0x00080000, /* node management */ - ATH_DEBUG_RATE = 0x00000010, /* rate control */ - ATH_DEBUG_ANY = 0xffffffff -}; -#define DPRINTF(sc, m, fmt, ...) do { \ - if (sc->sc_debug & (m)) \ - printf(fmt, __VA_ARGS__); \ -} while (0) -#else -#define DPRINTF(sc, m, fmt, ...) do { \ - (void) sc; \ -} while (0) -#endif - /* * This file is an implementation of the SampleRate algorithm * in "Bit-rate Selection in Wireless Networks" @@ -152,14 +135,12 @@ rate_to_ndx(struct sample_node *sn, int rate) { void ath_rate_node_init(struct ath_softc *sc, struct ath_node *an) { - DPRINTF(sc, ATH_DEBUG_NODE, "%s:\n", __func__); /* NB: assumed to be zero'd by caller */ } void ath_rate_node_cleanup(struct ath_softc *sc, struct ath_node *an) { - DPRINTF(sc, ATH_DEBUG_NODE, "%s:\n", __func__); } @@ -258,7 +239,8 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, { struct sample_node *sn = ATH_NODE_SAMPLE(an); struct sample_softc *ssc = ATH_SOFTC_SAMPLE(sc); - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int ndx, size_bin, mrr, best_ndx, change_rates; unsigned average_tx_time; @@ -323,10 +305,11 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, if (change_rates) { if (best_ndx != sn->current_rate[size_bin]) { - DPRINTF(sc, ATH_DEBUG_RATE, -"%s: %s size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d\n", + IEEE80211_NOTE(an->an_node.ni_vap, + IEEE80211_MSG_RATECTL, + &an->an_node, +"%s: size %d switch rate %d (%d/%d) -> %d (%d/%d) after %d packets mrr %d", __func__, - ether_sprintf(an->an_node.ni_macaddr), packet_size_bins[size_bin], sn->rates[sn->current_rate[size_bin]].rate, sn->stats[size_bin][sn->current_rate[size_bin]].average_tx_time, @@ -340,16 +323,13 @@ ath_rate_findrate(struct ath_softc *sc, struct ath_node *an, sn->packets_since_switch[size_bin] = 0; sn->current_rate[size_bin] = best_ndx; sn->ticks_since_switch[size_bin] = ticks; - } - ndx = sn->current_rate[size_bin]; - sn->packets_since_switch[size_bin]++; - if (size_bin == 0) { /* - * set the visible txrate for this node - * to the rate of small packets + * Set the visible txrate for this node. */ - an->an_node.ni_txrate = ndx; + an->an_node.ni_txrate = sn->rates[best_ndx].rate; } + ndx = sn->current_rate[size_bin]; + sn->packets_since_switch[size_bin]++; } } @@ -494,9 +474,10 @@ update_stats(struct ath_softc *sc, struct ath_node *an, if (ndx0 == sn->current_sample_ndx[size_bin]) { - DPRINTF(sc, ATH_DEBUG_RATE, -"%s: %s size %d %s sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d)\n", - __func__, ether_sprintf(an->an_node.ni_macaddr), + IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, + &an->an_node, +"%s: size %d %s sample rate %d tries (%d/%d) tt %d avg_tt (%d/%d)", + __func__, size, status ? "FAIL" : "OK", rate, short_tries, tries, tt, @@ -511,7 +492,8 @@ void ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, const struct ath_buf *bf) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct sample_node *sn = ATH_NODE_SAMPLE(an); const struct ath_tx_status *ts = &bf->bf_status.ds_txstat; const struct ath_desc *ds0 = &bf->bf_desc[0]; @@ -526,9 +508,10 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, frame_size = 1500; if (sn->num_rates <= 0) { - DPRINTF(sc, ATH_DEBUG_RATE, - "%s: %s size %d %s rate/try %d/%d no rates yet\n", - __func__, ether_sprintf(an->an_node.ni_macaddr), + IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, + &an->an_node, + "%s: size %d %s rate/try %d/%d no rates yet", + __func__, bin_to_size(size_to_bin(frame_size)), ts->ts_status ? "FAIL" : "OK", short_tries, long_tries); @@ -541,9 +524,9 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, /* * Only one rate was used; optimize work. */ - DPRINTF(sc, ATH_DEBUG_RATE, - "%s: %s size %d %s rate/try %d/%d/%d\n", - __func__, ether_sprintf(an->an_node.ni_macaddr), + IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, + &an->an_node, "%s: size %d %s rate/try %d/%d/%d", + __func__, bin_to_size(size_to_bin(frame_size)), ts->ts_status ? "FAIL" : "OK", final_rate, short_tries, long_tries); @@ -591,9 +574,10 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, tries3 = MS(ds0->ds_ctl2, AR_XmitDataTries3); ndx3 = rate_to_ndx(sn, rate3); - DPRINTF(sc, ATH_DEBUG_RATE, -"%s: %s size %d finaltsidx %d tries %d %s rate/try [%d/%d %d/%d %d/%d %d/%d]\n", - __func__, ether_sprintf(an->an_node.ni_macaddr), + IEEE80211_NOTE(an->an_node.ni_vap, IEEE80211_MSG_RATECTL, + &an->an_node, +"%s: size %d finaltsidx %d tries %d %s rate/try [%d/%d %d/%d %d/%d %d/%d]", + __func__, bin_to_size(size_to_bin(frame_size)), finalTSIdx, long_tries, @@ -658,8 +642,6 @@ ath_rate_tx_complete(struct ath_softc *sc, struct ath_node *an, void ath_rate_newassoc(struct ath_softc *sc, struct ath_node *an, int isnew) { - DPRINTF(sc, ATH_DEBUG_NODE, "%s: %s isnew %d\n", __func__, - ether_sprintf(an->an_node.ni_macaddr), isnew); if (isnew) ath_rate_ctl_reset(sc, &an->an_node); } @@ -671,15 +653,15 @@ static void ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) { #define RATE(_ix) (ni->ni_rates.rs_rates[(_ix)] & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; struct ath_node *an = ATH_NODE(ni); + const struct ieee80211_txparam *tp = an->an_tp; struct sample_node *sn = ATH_NODE_SAMPLE(an); const HAL_RATE_TABLE *rt = sc->sc_currates; int x, y, srate; KASSERT(rt != NULL, ("no rate table, mode %u", sc->sc_curmode)); sn->static_rate_ndx = -1; - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { + if (tp != NULL && tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { /* * A fixed rate is to be used; ic_fixed_rate is the * IEEE code for this rate (sans basic bit). Convert this @@ -688,7 +670,7 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) */ /* NB: the rate set is assumed sorted */ srate = ni->ni_rates.rs_nrates - 1; - for (; srate >= 0 && RATE(srate) != ic->ic_fixed_rate; srate--) + for (; srate >= 0 && RATE(srate) != tp->ucastrate; srate--) ; /* * The fixed rate may not be available due to races @@ -700,32 +682,34 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) sn->static_rate_ndx = srate; } - DPRINTF(sc, ATH_DEBUG_RATE, "%s: %s size 1600 rate/tt", - __func__, ether_sprintf(ni->ni_macaddr)); - sn->num_rates = ni->ni_rates.rs_nrates; for (x = 0; x < ni->ni_rates.rs_nrates; x++) { sn->rates[x].rate = ni->ni_rates.rs_rates[x] & IEEE80211_RATE_VAL; sn->rates[x].rix = sc->sc_rixmap[sn->rates[x].rate]; if (sn->rates[x].rix == 0xff) { - DPRINTF(sc, ATH_DEBUG_RATE, - "%s: ignore bogus rix at %d\n", __func__, x); + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "%s: ignore bogus rix at %d", __func__, x); continue; } sn->rates[x].rateCode = rt->info[sn->rates[x].rix].rateCode; sn->rates[x].shortPreambleRateCode = rt->info[sn->rates[x].rix].rateCode | rt->info[sn->rates[x].rix].shortPreamble; - - DPRINTF(sc, ATH_DEBUG_RATE, " %d/%d", sn->rates[x].rate, - calc_usecs_unicast_packet(sc, 1600, sn->rates[x].rix, 0,0)); } - DPRINTF(sc, ATH_DEBUG_RATE, "%s\n", ""); - - /* set the visible bit-rate to the lowest one available */ - ni->ni_txrate = 0; - sn->num_rates = ni->ni_rates.rs_nrates; - +#ifdef IEEE80211_DEBUG + if (ieee80211_msg(ni->ni_vap, IEEE80211_MSG_RATECTL)) { + ieee80211_note(ni->ni_vap, "[%6D] %s: size 1600 rate/tt", + __func__, ni->ni_macaddr, ":"); + for (x = 0; x < sn->num_rates; x++) { + if (sn->rates[x].rix == 0xff) + continue; + printf(" %d/%d", sn->rates[x].rate, + calc_usecs_unicast_packet(sc, 1600, + sn->rates[x].rix, 0,0)); + } + printf("\n"); + } +#endif for (y = 0; y < NUM_PACKET_SIZE_BINS; y++) { int size = bin_to_size(y); int ndx = 0; @@ -756,9 +740,8 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) sn->current_rate[y] = ndx; } - DPRINTF(sc, ATH_DEBUG_RATE, - "%s: %s %d rates %d%sMbps (%dus)- %d%sMbps (%dus)\n", - __func__, ether_sprintf(ni->ni_macaddr), + IEEE80211_NOTE(ni->ni_vap, IEEE80211_MSG_RATECTL, ni, + "%s: %d rates %d%sMbps (%dus)- %d%sMbps (%dus)", __func__, sn->num_rates, sn->rates[0].rate/2, sn->rates[0].rate % 0x1 ? ".5" : "", sn->stats[1][0].perfect_tx_time, @@ -767,10 +750,11 @@ ath_rate_ctl_reset(struct ath_softc *sc, struct ieee80211_node *ni) sn->stats[1][sn->num_rates-1].perfect_tx_time ); - if (sn->static_rate_ndx != -1) - ni->ni_txrate = sn->static_rate_ndx; + /* set the visible bit-rate */ + if (sn->static_rate_ndx != -1) + ni->ni_txrate = sn->rates[sn->static_rate_ndx].rate; else - ni->ni_txrate = sn->current_rate[0]; + ni->ni_txrate = sn->rates[0].rate; #undef RATE } @@ -786,18 +770,19 @@ rate_cb(void *arg, struct ieee80211_node *ni) * Reset the rate control state for each 802.11 state transition. */ void -ath_rate_newstate(struct ath_softc *sc, enum ieee80211_state state) +ath_rate_newstate(struct ieee80211vap *vap, enum ieee80211_state state) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = vap->iv_ic; + struct ath_softc *sc = ic->ic_ifp->if_softc; if (state == IEEE80211_S_RUN) { - if (ic->ic_opmode != IEEE80211_M_STA) { + if (vap->iv_opmode != IEEE80211_M_STA) { /* * Sync rates for associated stations and neighbors. */ ieee80211_iterate_nodes(&ic->ic_sta, rate_cb, sc); } - ath_rate_newassoc(sc, ATH_NODE(ic->ic_bss), 1); + ath_rate_newassoc(sc, ATH_NODE(vap->iv_bss), 1); } } @@ -822,7 +807,6 @@ ath_rate_attach(struct ath_softc *sc) { struct sample_softc *osc; - DPRINTF(sc, ATH_DEBUG_ANY, "%s:\n", __func__); osc = malloc(sizeof(struct sample_softc), M_DEVBUF, M_NOWAIT|M_ZERO); if (osc == NULL) return NULL; diff --git a/sys/dev/ath/ath_rate/sample/sample.h b/sys/dev/ath/ath_rate/sample/sample.h index 1e9377e..1ea96c4 100644 --- a/sys/dev/ath/ath_rate/sample/sample.h +++ b/sys/dev/ath/ath_rate/sample/sample.h @@ -155,12 +155,13 @@ static unsigned calc_usecs_unicast_packet(struct ath_softc *sc, int length, int rix, int short_retries, int long_retries) { const HAL_RATE_TABLE *rt = sc->sc_currates; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int rts, cts; unsigned t_slot = 20; unsigned t_difs = 50; unsigned t_sifs = 10; - struct ieee80211com *ic = &sc->sc_ic; int tt = 0; int x = 0; int cw = WIFI_CW_MIN; diff --git a/sys/dev/ath/if_ath.c b/sys/dev/ath/if_ath.c index fd02770..0d5ef91 100644 --- a/sys/dev/ath/if_ath.c +++ b/sys/dev/ath/if_ath.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -84,6 +84,22 @@ __FBSDID("$FreeBSD$"); #include #endif +/* + * ATH_BCBUF determines the number of vap's that can transmit + * beacons and also (currently) the number of vap's that can + * have unique mac addresses/bssid. When staggering beacons + * 4 is probably a good max as otherwise the beacons become + * very closely spaced and there is limited time for cab q traffic + * to go out. You can burst beacons instead but that is not good + * for stations in power save and at some point you really want + * another radio (and channel). + * + * The limit on the number of mac addresses is tied to our use of + * the U/L bit and tracking addresses in a byte; it would be + * worthwhile to allow more for applications like proxy sta. + */ +CTASSERT(ATH_BCBUF <= 8); + /* unaligned little endian access */ #define LE_READ_2(p) \ ((u_int16_t) \ @@ -99,49 +115,59 @@ enum { ATH_LED_POLL, }; +static struct ieee80211vap *ath_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void ath_vap_delete(struct ieee80211vap *); static void ath_init(void *); static void ath_stop_locked(struct ifnet *); static void ath_stop(struct ifnet *); static void ath_start(struct ifnet *); static int ath_reset(struct ifnet *); +static int ath_reset_vap(struct ieee80211vap *, u_long); static int ath_media_change(struct ifnet *); static void ath_watchdog(struct ifnet *); static int ath_ioctl(struct ifnet *, u_long, caddr_t); static void ath_fatal_proc(void *, int); static void ath_rxorn_proc(void *, int); +static void ath_bmiss_vap(struct ieee80211vap *); static void ath_bmiss_proc(void *, int); -static int ath_key_alloc(struct ieee80211com *, +static int ath_key_alloc(struct ieee80211vap *, const struct ieee80211_key *, ieee80211_keyix *, ieee80211_keyix *); -static int ath_key_delete(struct ieee80211com *, +static int ath_key_delete(struct ieee80211vap *, const struct ieee80211_key *); -static int ath_key_set(struct ieee80211com *, const struct ieee80211_key *, +static int ath_key_set(struct ieee80211vap *, const struct ieee80211_key *, const u_int8_t mac[IEEE80211_ADDR_LEN]); -static void ath_key_update_begin(struct ieee80211com *); -static void ath_key_update_end(struct ieee80211com *); +static void ath_key_update_begin(struct ieee80211vap *); +static void ath_key_update_end(struct ieee80211vap *); +static void ath_update_mcast(struct ifnet *); +static void ath_update_promisc(struct ifnet *); static void ath_mode_init(struct ath_softc *); static void ath_setslottime(struct ath_softc *); static void ath_updateslot(struct ifnet *); static int ath_beaconq_setup(struct ath_hal *); static int ath_beacon_alloc(struct ath_softc *, struct ieee80211_node *); -static void ath_beacon_update(struct ieee80211com *, int item); +static void ath_beacon_update(struct ieee80211vap *, int item); static void ath_beacon_setup(struct ath_softc *, struct ath_buf *); static void ath_beacon_proc(void *, int); +static struct ath_buf *ath_beacon_generate(struct ath_softc *, + struct ieee80211vap *); static void ath_bstuck_proc(void *, int); +static void ath_beacon_return(struct ath_softc *, struct ath_buf *); static void ath_beacon_free(struct ath_softc *); -static void ath_beacon_config(struct ath_softc *); +static void ath_beacon_config(struct ath_softc *, struct ieee80211vap *); static void ath_descdma_cleanup(struct ath_softc *sc, struct ath_descdma *, ath_bufhead *); static int ath_desc_alloc(struct ath_softc *); static void ath_desc_free(struct ath_softc *); static struct ieee80211_node *ath_node_alloc(struct ieee80211_node_table *); static void ath_node_free(struct ieee80211_node *); -static int8_t ath_node_getrssi(const struct ieee80211_node *); static void ath_node_getsignal(const struct ieee80211_node *, int8_t *, int8_t *); static int ath_rxbuf_init(struct ath_softc *, struct ath_buf *); -static void ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, - struct ieee80211_node *ni, +static void ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi, int noise, u_int32_t rstamp); static void ath_setdefantenna(struct ath_softc *, u_int); static void ath_rx_proc(void *, int); @@ -157,6 +183,7 @@ static int ath_tx_start(struct ath_softc *, struct ieee80211_node *, static void ath_tx_proc_q0(void *, int); static void ath_tx_proc_q0123(void *, int); static void ath_tx_proc(void *, int); +static void ath_tx_draintxq(struct ath_softc *, struct ath_txq *); static int ath_chan_set(struct ath_softc *, struct ieee80211_channel *); static void ath_draintxq(struct ath_softc *); static void ath_stoprecv(struct ath_softc *); @@ -166,13 +193,16 @@ static void ath_scan_start(struct ieee80211com *); static void ath_scan_end(struct ieee80211com *); static void ath_set_channel(struct ieee80211com *); static void ath_calibrate(void *); -static int ath_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int ath_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void ath_setup_stationkey(struct ieee80211_node *); static void ath_newassoc(struct ieee80211_node *, int); -static int ath_getchannels(struct ath_softc *, - HAL_REG_DOMAIN, HAL_CTRY_CODE, HAL_BOOL, HAL_BOOL); +static int ath_setregdomain(struct ieee80211com *, + struct ieee80211_regdomain *, int, + struct ieee80211_channel []); +static void ath_getradiocaps(struct ieee80211com *, int *, + struct ieee80211_channel []); +static int ath_getchannels(struct ath_softc *); static void ath_led_event(struct ath_softc *, int); -static void ath_update_txpow(struct ath_softc *); static int ath_rate_setup(struct ath_softc *, u_int mode); static void ath_setcurmode(struct ath_softc *, enum ieee80211_phymode); @@ -189,21 +219,6 @@ SYSCTL_DECL(_hw_ath); static int ath_calinterval = 30; /* calibrate every 30 secs */ SYSCTL_INT(_hw_ath, OID_AUTO, calibrate, CTLFLAG_RW, &ath_calinterval, 0, "chip calibration interval (secs)"); -static int ath_outdoor = AH_TRUE; /* outdoor operation */ -SYSCTL_INT(_hw_ath, OID_AUTO, outdoor, CTLFLAG_RW, &ath_outdoor, - 0, "outdoor operation"); -TUNABLE_INT("hw.ath.outdoor", &ath_outdoor); -static int ath_xchanmode = AH_TRUE; /* extended channel use */ -SYSCTL_INT(_hw_ath, OID_AUTO, xchanmode, CTLFLAG_RW, &ath_xchanmode, - 0, "extended channel mode"); -TUNABLE_INT("hw.ath.xchanmode", &ath_xchanmode); -static int ath_countrycode = CTRY_DEFAULT; /* country code */ -SYSCTL_INT(_hw_ath, OID_AUTO, countrycode, CTLFLAG_RW, &ath_countrycode, - 0, "country code"); -TUNABLE_INT("hw.ath.countrycode", &ath_countrycode); -static int ath_regdomain = 0; /* regulatory domain */ -SYSCTL_INT(_hw_ath, OID_AUTO, regdomain, CTLFLAG_RD, &ath_regdomain, - 0, "regulatory domain"); static int ath_rxbuf = ATH_RXBUF; /* # rx buffers to allocate */ SYSCTL_INT(_hw_ath, OID_AUTO, rxbuf, CTLFLAG_RW, &ath_rxbuf, @@ -273,19 +288,20 @@ int ath_attach(u_int16_t devid, struct ath_softc *sc) { struct ifnet *ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; struct ath_hal *ah = NULL; HAL_STATUS status; int error = 0, i; DPRINTF(sc, ATH_DEBUG_ANY, "%s: devid 0x%x\n", __func__, devid); - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(sc->sc_dev, "can not if_alloc()\n"); error = ENOSPC; goto bad; } + ic = ifp->if_l2com; /* set these up early for if_printf use */ if_initname(ifp, device_get_name(sc->sc_dev), @@ -342,13 +358,9 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) ath_hal_keyreset(ah, i); /* - * Collect the channel list using the default country - * code and including outdoor channels. The 802.11 layer - * is resposible for filtering this list based on settings - * like the phy mode. + * Collect the default channel list. */ - error = ath_getchannels(sc, ath_regdomain, ath_countrycode, - ath_outdoor != 0, ath_xchanmode != 0); + error = ath_getchannels(sc); if (error != 0) goto bad; @@ -378,7 +390,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) goto bad; } callout_init(&sc->sc_cal_ch, CALLOUT_MPSAFE); - callout_init(&sc->sc_dfs_ch, CALLOUT_MPSAFE); ATH_TXBUF_LOCK_INIT(sc); @@ -412,8 +423,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) error = EIO; goto bad2; } - /* NB: s/w q, qnum used only by WITNESS */ - ath_txq_init(sc, &sc->sc_mcastq, HAL_NUM_TX_QUEUES+1); /* NB: insure BK queue is the lowest priority h/w queue */ if (!ath_tx_setup(sc, WME_AC_BK, HAL_WME_AC_BK)) { if_printf(ifp, "unable to setup xmit queue for %s traffic!\n", @@ -497,10 +506,6 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; - ic->ic_reset = ath_reset; - ic->ic_newassoc = ath_newassoc; - ic->ic_updateslot = ath_updateslot; - ic->ic_wme.wme_update = ath_wme_update; /* XXX not right but it's not used anywhere important */ ic->ic_phytype = IEEE80211_T_OFDM; ic->ic_opmode = IEEE80211_M_STA; @@ -509,6 +514,7 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) | IEEE80211_C_HOSTAP /* hostap mode */ | IEEE80211_C_MONITOR /* monitor mode */ | IEEE80211_C_AHDEMO /* adhoc demo mode */ + | IEEE80211_C_WDS /* 4-address traffic works */ | IEEE80211_C_SHPREAMBLE /* short preamble supported */ | IEEE80211_C_SHSLOT /* short slot time supported */ | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ @@ -519,22 +525,22 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) * Query the hal to figure out h/w crypto support. */ if (ath_hal_ciphersupported(ah, HAL_CIPHER_WEP)) - ic->ic_caps |= IEEE80211_C_WEP; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP; if (ath_hal_ciphersupported(ah, HAL_CIPHER_AES_OCB)) - ic->ic_caps |= IEEE80211_C_AES; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_OCB; if (ath_hal_ciphersupported(ah, HAL_CIPHER_AES_CCM)) - ic->ic_caps |= IEEE80211_C_AES_CCM; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_AES_CCM; if (ath_hal_ciphersupported(ah, HAL_CIPHER_CKIP)) - ic->ic_caps |= IEEE80211_C_CKIP; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_CKIP; if (ath_hal_ciphersupported(ah, HAL_CIPHER_TKIP)) { - ic->ic_caps |= IEEE80211_C_TKIP; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_TKIP; /* * Check if h/w does the MIC and/or whether the * separate key cache entries are required to * handle both tx+rx MIC keys. */ if (ath_hal_ciphersupported(ah, HAL_CIPHER_MIC)) - ic->ic_caps |= IEEE80211_C_TKIPMIC; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_TKIPMIC; /* * If the h/w supports storing tx+rx MIC keys * in one cache slot automatically enable use. @@ -542,6 +548,13 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) if (ath_hal_hastkipsplit(ah) || !ath_hal_settkipsplit(ah, AH_FALSE)) sc->sc_splitmic = 1; + /* + * If the h/w can do TKIP MIC together with WME then + * we use it; otherwise we force the MIC to be done + * in software by the net80211 layer. + */ + if (ath_hal_haswmetkipmic(ah)) + sc->sc_wmetkipmic = 1; } sc->sc_hasclrkey = ath_hal_ciphersupported(ah, HAL_CIPHER_CLR); sc->sc_mcastkey = ath_hal_getmcastkeysearch(ah); @@ -578,9 +591,11 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) */ if (ath_hal_hasbursting(ah)) ic->ic_caps |= IEEE80211_C_BURST; + sc->sc_hasbmask = ath_hal_hasbssidmask(ah); + sc->sc_hastsfadd = ath_hal_hastsfadjust(ah); if (ath_hal_hasfastframes(ah)) ic->ic_caps |= IEEE80211_C_FF; - if (ath_hal_getwirelessmodes(ah, ath_countrycode) & (HAL_MODE_108G|HAL_MODE_TURBO)) + if (ath_hal_getwirelessmodes(ah, ic->ic_regdomain.country) & (HAL_MODE_108G|HAL_MODE_TURBO)) ic->ic_caps |= IEEE80211_C_TURBOP; /* @@ -602,33 +617,33 @@ ath_attach(u_int16_t devid, struct ath_softc *sc) /* get mac address from hardware */ ath_hal_getmac(ah, ic->ic_myaddr); + if (sc->sc_hasbmask) + ath_hal_getbssidmask(ah, sc->sc_hwbssidmask); + /* NB: used to size node table key mapping array */ + ic->ic_max_keyix = sc->sc_keymax; /* call MI attach routine. */ ieee80211_ifattach(ic); - sc->sc_opmode = ic->ic_opmode; + ic->ic_setregdomain = ath_setregdomain; + ic->ic_getradiocaps = ath_getradiocaps; + sc->sc_opmode = HAL_M_STA; + /* override default methods */ + ic->ic_newassoc = ath_newassoc; + ic->ic_updateslot = ath_updateslot; + ic->ic_wme.wme_update = ath_wme_update; + ic->ic_vap_create = ath_vap_create; + ic->ic_vap_delete = ath_vap_delete; + ic->ic_raw_xmit = ath_raw_xmit; + ic->ic_update_mcast = ath_update_mcast; + ic->ic_update_promisc = ath_update_promisc; ic->ic_node_alloc = ath_node_alloc; sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = ath_node_free; - ic->ic_node_getrssi = ath_node_getrssi; ic->ic_node_getsignal = ath_node_getsignal; - sc->sc_recv_mgmt = ic->ic_recv_mgmt; - ic->ic_recv_mgmt = ath_recv_mgmt; - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = ath_newstate; ic->ic_scan_start = ath_scan_start; ic->ic_scan_end = ath_scan_end; ic->ic_set_channel = ath_set_channel; - ic->ic_crypto.cs_max_keyix = sc->sc_keymax; - ic->ic_crypto.cs_key_alloc = ath_key_alloc; - ic->ic_crypto.cs_key_delete = ath_key_delete; - ic->ic_crypto.cs_key_set = ath_key_set; - ic->ic_crypto.cs_key_update_begin = ath_key_update_begin; - ic->ic_crypto.cs_key_update_end = ath_key_update_end; - ic->ic_raw_xmit = ath_raw_xmit; - ic->ic_update_beacon = ath_beacon_update; - /* complete initialization */ - ieee80211_media_init(ic, ath_media_change, ieee80211_media_status); ath_bpfattach(sc); /* @@ -675,7 +690,7 @@ ath_detach(struct ath_softc *sc) * it last * Other than that, it's straightforward... */ - ieee80211_ifdetach(&sc->sc_ic); + ieee80211_ifdetach(ifp->if_l2com); #ifdef ATH_TX99_DIAG if (sc->sc_tx99 != NULL) sc->sc_tx99->detach(sc->sc_tx99); @@ -690,6 +705,343 @@ ath_detach(struct ath_softc *sc) return 0; } +/* + * MAC address handling for multiple BSS on the same radio. + * The first vap uses the MAC address from the EEPROM. For + * subsequent vap's we set the U/L bit (bit 1) in the MAC + * address and use the next six bits as an index. + */ +static void +assign_address(struct ath_softc *sc, uint8_t mac[IEEE80211_ADDR_LEN], int clone) +{ + int i; + + if (clone && sc->sc_hasbmask) { + /* NB: we only do this if h/w supports multiple bssid */ + for (i = 0; i < 8; i++) + if ((sc->sc_bssidmask & (1<sc_bssidmask |= 1<sc_hwbssidmask[0] &= ~mac[0]; + if (i == 0) + sc->sc_nbssid0++; +} + +static void +reclaim_address(struct ath_softc *sc, const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + int i = mac[0] >> 2; + uint8_t mask; + + if (i != 0 || --sc->sc_nbssid0 == 0) { + sc->sc_bssidmask &= ~(1<sc_bssidmask & (1<sc_hwbssidmask[0] |= mask; + } +} + +/* + * Assign a beacon xmit slot. We try to space out + * assignments so when beacons are staggered the + * traffic coming out of the cab q has maximal time + * to go out before the next beacon is scheduled. + */ +static int +assign_bslot(struct ath_softc *sc) +{ + u_int slot, free; + + free = 0; + for (slot = 0; slot < ATH_BCBUF; slot++) + if (sc->sc_bslot[slot] == NULL) { + if (sc->sc_bslot[(slot+1)%ATH_BCBUF] == NULL && + sc->sc_bslot[(slot-1)%ATH_BCBUF] == NULL) + return slot; + free = slot; + /* NB: keep looking for a double slot */ + } + return free; +} + +static struct ieee80211vap * +ath_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac0[IEEE80211_ADDR_LEN]) +{ + struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_vap *avp; + struct ieee80211vap *vap; + uint8_t mac[IEEE80211_ADDR_LEN]; + int ic_opmode, needbeacon, error; + + avp = (struct ath_vap *) malloc(sizeof(struct ath_vap), + M_80211_VAP, M_WAITOK | M_ZERO); + needbeacon = 0; + IEEE80211_ADDR_COPY(mac, mac0); + + ATH_LOCK(sc); + switch (opmode) { + case IEEE80211_M_STA: + if (sc->sc_nstavaps != 0) { /* XXX only 1 sta for now */ + device_printf(sc->sc_dev, "only 1 sta vap supported\n"); + goto bad; + } + if (sc->sc_nvaps) { + /* + * When there are multiple vaps we must fall + * back to s/w beacon miss handling. + */ + flags |= IEEE80211_CLONE_NOBEACONS; + } + if (flags & IEEE80211_CLONE_NOBEACONS) { + sc->sc_swbmiss = 1; + ic_opmode = IEEE80211_M_HOSTAP; + } else + ic_opmode = opmode; + break; + case IEEE80211_M_IBSS: + if (sc->sc_nvaps != 0) { /* XXX only 1 for now */ + device_printf(sc->sc_dev, + "only 1 ibss vap supported\n"); + goto bad; + } + ic_opmode = opmode; + needbeacon = 1; + break; + case IEEE80211_M_AHDEMO: + /* fall thru... */ + case IEEE80211_M_MONITOR: + if (sc->sc_nvaps != 0 && ic->ic_opmode != opmode) { + /* XXX not right for monitor mode */ + ic_opmode = ic->ic_opmode; + } else + ic_opmode = opmode; + break; + case IEEE80211_M_HOSTAP: + needbeacon = 1; + /* fall thru... */ + case IEEE80211_M_WDS: + if (sc->sc_nvaps && ic->ic_opmode == IEEE80211_M_STA) { + device_printf(sc->sc_dev, + "wds not supported in sta mode\n"); + goto bad; + } + if (opmode == IEEE80211_M_WDS) { + /* + * Silently remove any request for a unique + * bssid; WDS vap's always share the local + * mac address. + */ + flags &= ~IEEE80211_CLONE_BSSID; + } + ic_opmode = IEEE80211_M_HOSTAP; + break; + default: + device_printf(sc->sc_dev, "unknown opmode %d\n", opmode); + goto bad; + } + /* + * Check that a beacon buffer is available; the code below assumes it. + */ + if (needbeacon & STAILQ_EMPTY(&sc->sc_bbuf)) { + device_printf(sc->sc_dev, "no beacon buffer available\n"); + goto bad; + } + + /* STA, AHDEMO? */ + if (opmode == IEEE80211_M_HOSTAP) { + assign_address(sc, mac, flags & IEEE80211_CLONE_BSSID); + ath_hal_setbssidmask(sc->sc_ah, sc->sc_hwbssidmask); + } + + vap = &avp->av_vap; + /* XXX can't hold mutex across if_alloc */ + ATH_UNLOCK(sc); + error = ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, + bssid, mac); + ATH_LOCK(sc); + if (error != 0) { + device_printf(sc->sc_dev, "%s: error %d creating vap\n", + __func__, error); + goto bad2; + } + + /* h/w crypto support */ + vap->iv_key_alloc = ath_key_alloc; + vap->iv_key_delete = ath_key_delete; + vap->iv_key_set = ath_key_set; + vap->iv_key_update_begin = ath_key_update_begin; + vap->iv_key_update_end = ath_key_update_end; + + /* override various methods */ + avp->av_recv_mgmt = vap->iv_recv_mgmt; + vap->iv_recv_mgmt = ath_recv_mgmt; + vap->iv_reset = ath_reset_vap; + vap->iv_update_beacon = ath_beacon_update; + avp->av_newstate = vap->iv_newstate; + vap->iv_newstate = ath_newstate; + avp->av_bmiss = vap->iv_bmiss; + vap->iv_bmiss = ath_bmiss_vap; + + avp->av_bslot = -1; + if (needbeacon) { + /* + * Allocate beacon state and setup the q for buffered + * multicast frames. We know a beacon buffer is + * available because we checked above. + */ + avp->av_bcbuf = STAILQ_FIRST(&sc->sc_bbuf); + STAILQ_REMOVE_HEAD(&sc->sc_bbuf, bf_list); + if (opmode != IEEE80211_M_IBSS || !sc->sc_hasveol) { + /* + * Assign the vap to a beacon xmit slot. As above + * this cannot fail to find a free one. + */ + avp->av_bslot = assign_bslot(sc); + KASSERT(sc->sc_bslot[avp->av_bslot] == NULL, + ("beacon slot %u not empty", avp->av_bslot)); + sc->sc_bslot[avp->av_bslot] = vap; + sc->sc_nbcnvaps++; + } + if (sc->sc_hastsfadd && sc->sc_nbcnvaps > 0) { + /* + * Multple vaps are to transmit beacons and we + * have h/w support for TSF adjusting; enable + * use of staggered beacons. + */ + sc->sc_stagbeacons = 1; + } + ath_txq_init(sc, &avp->av_mcastq, ATH_TXQ_SWQ); + } + + ic->ic_opmode = ic_opmode; + if (opmode != IEEE80211_M_WDS) { + sc->sc_nvaps++; + if (opmode == IEEE80211_M_STA) + sc->sc_nstavaps++; + } + switch (ic_opmode) { + case IEEE80211_M_IBSS: + sc->sc_opmode = HAL_M_IBSS; + break; + case IEEE80211_M_STA: + sc->sc_opmode = HAL_M_STA; + break; + case IEEE80211_M_AHDEMO: + case IEEE80211_M_HOSTAP: + sc->sc_opmode = HAL_M_HOSTAP; + break; + case IEEE80211_M_MONITOR: + sc->sc_opmode = HAL_M_MONITOR; + break; + default: + /* XXX should not happen */ + break; + } + if (sc->sc_hastsfadd) { + /* + * Configure whether or not TSF adjust should be done. + */ + ath_hal_settsfadjust(sc->sc_ah, sc->sc_stagbeacons); + } + ATH_UNLOCK(sc); + + /* complete setup */ + ieee80211_vap_attach(vap, ath_media_change, ieee80211_media_status); + return vap; +bad2: + reclaim_address(sc, mac); + ath_hal_setbssidmask(sc->sc_ah, sc->sc_hwbssidmask); +bad: + free(avp, M_80211_VAP); + ATH_UNLOCK(sc); + return NULL; +} + +static void +ath_vap_delete(struct ieee80211vap *vap) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; + struct ath_softc *sc = ifp->if_softc; + struct ath_hal *ah = sc->sc_ah; + struct ath_vap *avp = ATH_VAP(vap); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + /* + * Quiesce the hardware while we remove the vap. In + * particular we need to reclaim all references to + * the vap state by any frames pending on the tx queues. + */ + ath_hal_intrset(ah, 0); /* disable interrupts */ + ath_draintxq(sc); /* stop xmit side */ + ath_stoprecv(sc); /* stop recv side */ + } + + ieee80211_vap_detach(vap); + ATH_LOCK(sc); + /* + * Reclaim beacon state. Note this must be done before + * the vap instance is reclaimed as we may have a reference + * to it in the buffer for the beacon frame. + */ + if (avp->av_bcbuf != NULL) { + if (avp->av_bslot != -1) { + sc->sc_bslot[avp->av_bslot] = NULL; + sc->sc_nbcnvaps--; + } + ath_beacon_return(sc, avp->av_bcbuf); + avp->av_bcbuf = NULL; + if (sc->sc_nbcnvaps == 0) { + sc->sc_stagbeacons = 0; + if (sc->sc_hastsfadd) + ath_hal_settsfadjust(sc->sc_ah, 0); + } + /* + * Reclaim any pending mcast frames for the vap. + */ + ath_tx_draintxq(sc, &avp->av_mcastq); + ATH_TXQ_LOCK_DESTROY(&avp->av_mcastq); + } + /* + * Update bookkeeping. + */ + if (vap->iv_opmode == IEEE80211_M_STA) { + sc->sc_nstavaps--; + if (sc->sc_nstavaps == 0 && sc->sc_swbmiss) + sc->sc_swbmiss = 0; + } else if (vap->iv_opmode == IEEE80211_M_HOSTAP) { + reclaim_address(sc, vap->iv_myaddr); + ath_hal_setbssidmask(ah, sc->sc_hwbssidmask); + } + if (vap->iv_opmode != IEEE80211_M_WDS) + sc->sc_nvaps--; + ATH_UNLOCK(sc); + free(avp, M_80211_VAP); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) { + /* + * Restart rx+tx machines if still running (RUNNING will + * be reset if we just destroyed the last vap). + */ + if (ath_startrecv(sc) != 0) + if_printf(ifp, "%s: unable to restart recv logic\n", + __func__); + if (sc->sc_beacons) + ath_beacon_config(sc, NULL); + ath_hal_intrset(ah, sc->sc_imask); + } +} + void ath_suspend(struct ath_softc *sc) { @@ -864,37 +1216,40 @@ ath_rxorn_proc(void *arg, int pending) } static void +ath_bmiss_vap(struct ieee80211vap *vap) +{ + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + u_int64_t lastrx = sc->sc_lastrx; + u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah); + u_int bmisstimeout = + vap->iv_bmissthreshold * vap->iv_bss->ni_intval * 1024; + + DPRINTF(sc, ATH_DEBUG_BEACON, + "%s: tsf %llu lastrx %lld (%llu) bmiss %u\n", + __func__, (unsigned long long) tsf, + (unsigned long long)(tsf - lastrx), + (unsigned long long) lastrx, bmisstimeout); + /* + * Workaround phantom bmiss interrupts by sanity-checking + * the time of our last rx'd frame. If it is within the + * beacon miss interval then ignore the interrupt. If it's + * truly a bmiss we'll get another interrupt soon and that'll + * be dispatched up for processing. + */ + if (tsf - lastrx > bmisstimeout) + ATH_VAP(vap)->av_bmiss(vap); + else + sc->sc_stats.ast_bmiss_phantom++; +} + +static void ath_bmiss_proc(void *arg, int pending) { struct ath_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; DPRINTF(sc, ATH_DEBUG_ANY, "%s: pending %u\n", __func__, pending); - KASSERT(ic->ic_opmode == IEEE80211_M_STA, - ("unexpect operating mode %u", ic->ic_opmode)); - if (ic->ic_state == IEEE80211_S_RUN) { - u_int64_t lastrx = sc->sc_lastrx; - u_int64_t tsf = ath_hal_gettsf64(sc->sc_ah); - u_int bmisstimeout = - ic->ic_bmissthreshold * ic->ic_bss->ni_intval * 1024; - - DPRINTF(sc, ATH_DEBUG_BEACON, - "%s: tsf %llu lastrx %lld (%llu) bmiss %u\n", - __func__, (unsigned long long) tsf, - (unsigned long long)(tsf - lastrx), - (unsigned long long) lastrx, bmisstimeout); - /* - * Workaround phantom bmiss interrupts by sanity-checking - * the time of our last rx'd frame. If it is within the - * beacon miss interval then ignore the interrupt. If it's - * truly a bmiss we'll get another interrupt soon and that'll - * be dispatched up for processing. - */ - if (tsf - lastrx > bmisstimeout) - ieee80211_beacon_miss(ic); - else - sc->sc_stats.ast_bmiss_phantom++; - } + ieee80211_beacon_miss(ifp->if_l2com); } /* @@ -939,12 +1294,35 @@ ath_mapchan(HAL_CHANNEL *hc, const struct ieee80211_channel *chan) #undef N } +/* + * Handle TKIP MIC setup to deal hardware that doesn't do MIC + * calcs together with WME. If necessary disable the crypto + * hardware and mark the 802.11 state so keys will be setup + * with the MIC work done in software. + */ +static void +ath_settkipmic(struct ath_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + if ((ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP) && !sc->sc_wmetkipmic) { + if (ic->ic_flags & IEEE80211_F_WME) { + ath_hal_settkipmic(sc->sc_ah, AH_FALSE); + ic->ic_cryptocaps &= ~IEEE80211_CRYPTO_TKIPMIC; + } else { + ath_hal_settkipmic(sc->sc_ah, AH_TRUE); + ic->ic_cryptocaps |= IEEE80211_CRYPTO_TKIPMIC; + } + } +} + static void ath_init(void *arg) { struct ath_softc *sc = (struct ath_softc *) arg; - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -966,18 +1344,16 @@ ath_init(void *arg) * and then setup of the interrupt mask. */ ath_mapchan(&sc->sc_curchan, ic->ic_curchan); + ath_settkipmic(sc); if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_FALSE, &status)) { if_printf(ifp, "unable to reset hardware; hal status %u\n", status); - goto done; + ATH_UNLOCK(sc); + return; } + ath_chan_change(sc, ic->ic_curchan); /* - * This is needed only to setup initial state - * but it's best done after a reset. - */ - ath_update_txpow(sc); - /* * Likewise this is set during reset so update * state cached in the driver. */ @@ -994,7 +1370,8 @@ ath_init(void *arg) */ if (ath_startrecv(sc) != 0) { if_printf(ifp, "unable to start recv logic\n"); - goto done; + ATH_UNLOCK(sc); + return; } /* @@ -1009,36 +1386,24 @@ ath_init(void *arg) */ if (sc->sc_needmib && ic->ic_opmode == IEEE80211_M_STA) sc->sc_imask |= HAL_INT_MIB; - ath_hal_intrset(ah, sc->sc_imask); ifp->if_drv_flags |= IFF_DRV_RUNNING; - ic->ic_state = IEEE80211_S_INIT; + ath_hal_intrset(ah, sc->sc_imask); + + ATH_UNLOCK(sc); - /* - * The hardware should be ready to go now so it's safe - * to kick the 802.11 state machine as it's likely to - * immediately call back to us to send mgmt frames. - */ - ath_chan_change(sc, ic->ic_curchan); #ifdef ATH_TX99_DIAG if (sc->sc_tx99 != NULL) sc->sc_tx99->start(sc->sc_tx99); else #endif - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); -done: - ATH_UNLOCK(sc); + ieee80211_start_all(ic); /* start all vap's */ } static void ath_stop_locked(struct ifnet *ifp) { struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; struct ath_hal *ah = sc->sc_ah; DPRINTF(sc, ATH_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", @@ -1065,7 +1430,6 @@ ath_stop_locked(struct ifnet *ifp) if (sc->sc_tx99 != NULL) sc->sc_tx99->stop(sc->sc_tx99); #endif - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; ifp->if_timer = 0; if (!sc->sc_invalid) { @@ -1083,8 +1447,7 @@ ath_stop_locked(struct ifnet *ifp) ath_hal_phydisable(ah); } else sc->sc_rxlink = NULL; - IFQ_DRV_PURGE(&ifp->if_snd); - ath_beacon_free(sc); + ath_beacon_free(sc); /* XXX not needed */ } } @@ -1121,7 +1484,7 @@ static int ath_reset(struct ifnet *ifp) { struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; HAL_STATUS status; @@ -1134,11 +1497,11 @@ ath_reset(struct ifnet *ifp) ath_hal_intrset(ah, 0); /* disable interrupts */ ath_draintxq(sc); /* stop xmit side */ ath_stoprecv(sc); /* stop recv side */ + ath_settkipmic(sc); /* configure TKIP MIC handling */ /* NB: indicate channel change so we do a full reset */ if (!ath_hal_reset(ah, sc->sc_opmode, &sc->sc_curchan, AH_TRUE, &status)) if_printf(ifp, "%s: unable to reset hardware; hal status %u\n", __func__, status); - ath_update_txpow(sc); /* update tx power state */ sc->sc_diversity = ath_hal_getdiversity(ah); sc->sc_calinterval = 1; sc->sc_caltries = 0; @@ -1150,14 +1513,20 @@ ath_reset(struct ifnet *ifp) * might change as a result. */ ath_chan_change(sc, ic->ic_curchan); - if (ic->ic_state == IEEE80211_S_RUN) - ath_beacon_config(sc); /* restart beacons */ + if (sc->sc_beacons) + ath_beacon_config(sc, NULL); /* restart beacons */ ath_hal_intrset(ah, sc->sc_imask); ath_start(ifp); /* restart xmit */ return 0; } +static int +ath_reset_vap(struct ieee80211vap *vap, u_long cmd) +{ + return ath_reset(vap->iv_ic->ic_ifp); +} + static int ath_ff_always(struct ath_txq *txq, struct ath_buf *bf) { @@ -1210,7 +1579,7 @@ ath_ff_stageq_flush(struct ath_softc *sc, struct ath_txq *txq, sc->sc_stats.ast_ff_flush++; /* encap and xmit */ - bf->bf_m = ieee80211_encap(&sc->sc_ic, bf->bf_m, ni); + bf->bf_m = ieee80211_encap(ni, bf->bf_m); if (bf->bf_m == NULL) { DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF, "%s: discard, encapsulation failure\n", @@ -1243,6 +1612,7 @@ ath_ff_stageq_flush(struct ath_softc *sc, struct ath_txq *txq, static __inline u_int32_t ath_ff_approx_txtime(struct ath_softc *sc, struct ath_node *an, struct mbuf *m) { + struct ieee80211com *ic = sc->sc_ifp->if_l2com; u_int32_t framelen; struct ath_buf *bf; @@ -1256,7 +1626,7 @@ ath_ff_approx_txtime(struct ath_softc *sc, struct ath_node *an, struct mbuf *m) * - 14: 1 802.3 FF tunnel header (skb already accounts for 2nd) */ framelen = m->m_pkthdr.len + 32 + 4 + 6 + 16 + 14; - if (sc->sc_ic.ic_flags & IEEE80211_F_PRIVACY) + if (ic->ic_flags & IEEE80211_F_PRIVACY) framelen += 24; bf = an->an_ff_buf[M_WME_GETAC(m)]; if (bf != NULL) @@ -1280,7 +1650,7 @@ static __inline int ath_ff_can_aggregate(struct ath_softc *sc, struct ath_node *an, struct mbuf *m, int *flushq) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ath_txq *txq; u_int32_t txoplimit; u_int pri; @@ -1330,7 +1700,6 @@ static struct mbuf * ath_ff_check(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf, struct mbuf *m, struct ieee80211_node *ni) { - struct ieee80211com *ic = ni->ni_ic; struct ath_node *an = ATH_NODE(ni); struct ath_buf *bfstaged; int ff_flush, pri; @@ -1423,7 +1792,7 @@ ath_ff_check(struct ath_softc *sc, struct ath_txq *txq, ether_sprintf(an->an_node.ni_macaddr)); /* encap and xmit */ - bfstaged->bf_m = ieee80211_encap(ic, bfstaged->bf_m, ni); + bfstaged->bf_m = ieee80211_encap(ni, bfstaged->bf_m); if (bfstaged->bf_m == NULL) { DPRINTF(sc, ATH_DEBUG_XMIT | ATH_DEBUG_FF, "%s: discard, encap failure\n", __func__); @@ -1525,13 +1894,10 @@ static void ath_start(struct ifnet *ifp) { struct ath_softc *sc = ifp->if_softc; - struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_node *ni; struct ath_buf *bf; struct mbuf *m, *next; - struct ieee80211_frame *wh; - struct ether_header *eh; struct ath_txq *txq; ath_bufhead frags; int pri; @@ -1554,154 +1920,63 @@ ath_start(struct ifnet *ifp) ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } - /* - * Poll the management queue for frames; they - * have priority over normal data frames. - */ - IF_DEQUEUE(&ic->ic_mgtq, m); - if (m == NULL) { - /* - * No data frames go out unless we're associated. - */ - if (ic->ic_state != IEEE80211_S_RUN) { - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: discard data packet, state %s\n", - __func__, - ieee80211_state_name[ic->ic_state]); - sc->sc_stats.ast_tx_discard++; - ATH_TXBUF_LOCK(sc); - STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); - ATH_TXBUF_UNLOCK(sc); - break; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); /* XXX: LOCK */ - if (m == NULL) { - ATH_TXBUF_LOCK(sc); - STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); - ATH_TXBUF_UNLOCK(sc); - break; - } - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - STAILQ_INIT(&frags); + IFQ_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) { + ATH_TXBUF_LOCK(sc); + STAILQ_INSERT_TAIL(&sc->sc_txbuf, bf, bf_list); + ATH_TXBUF_UNLOCK(sc); + break; + } + STAILQ_INIT(&frags); + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + pri = M_WME_GETAC(m); + txq = sc->sc_ac2q[pri]; + if (ni->ni_ath_flags & IEEE80211_NODE_FF) { /* - * Find the node for the destination so we can do - * things like power save and fast frames aggregation. + * Check queue length; if too deep drop this + * frame (tail drop considered good). */ - if (m->m_len < sizeof(struct ether_header) && - (m = m_pullup(m, sizeof(struct ether_header))) == NULL) { - ic->ic_stats.is_tx_nobuf++; /* XXX */ - ni = NULL; - goto bad; - } - eh = mtod(m, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - /* NB: ieee80211_find_txnode does stat+msg */ + if (txq->axq_depth >= sc->sc_fftxqmax) { + DPRINTF(sc, ATH_DEBUG_FF, + "[%s] tail drop on q %u depth %u\n", + ether_sprintf(ni->ni_macaddr), + txq->axq_qnum, txq->axq_depth); + sc->sc_stats.ast_tx_qfull++; m_freem(m); - goto bad; - } - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && - (m->m_flags & M_PWR_SAV) == 0) { - /* - * Station in power save mode; pass the frame - * to the 802.11 layer and continue. We'll get - * the frame back when the time is right. - */ - ieee80211_pwrsave(ni, m); goto reclaim; } - /* calculate priority so we can find the tx queue */ - if (ieee80211_classify(ic, m, ni)) { - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: discard, classification failure\n", - __func__); - m_freem(m); - goto bad; - } - pri = M_WME_GETAC(m); - txq = sc->sc_ac2q[pri]; - if (ni->ni_ath_flags & IEEE80211_NODE_FF) { - /* - * Check queue length; if too deep drop this - * frame (tail drop considered good). - */ - if (txq->axq_depth >= sc->sc_fftxqmax) { - DPRINTF(sc, ATH_DEBUG_FF, - "[%s] tail drop on q %u depth %u\n", - ether_sprintf(ni->ni_macaddr), - txq->axq_qnum, txq->axq_depth); - sc->sc_stats.ast_tx_qfull++; - m_freem(m); - goto reclaim; - } - m = ath_ff_check(sc, txq, bf, m, ni); - if (m == NULL) { - /* NB: ni ref & bf held on stageq */ - continue; - } - } - ifp->if_opackets++; - BPF_MTAP(ifp, m); - /* - * Encapsulate the packet in prep for transmission. - */ - m = ieee80211_encap(ic, m, ni); + m = ath_ff_check(sc, txq, bf, m, ni); if (m == NULL) { - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: encapsulation failure\n", - __func__); - sc->sc_stats.ast_tx_encap++; - goto bad; - } - /* - * Check for fragmentation. If this frame - * has been broken up verify we have enough - * buffers to send all the fragments so all - * go out or none... - */ - if ((m->m_flags & M_FRAG) && - !ath_txfrag_setup(sc, &frags, m, ni)) { - DPRINTF(sc, ATH_DEBUG_XMIT, - "%s: out of txfrag buffers\n", __func__); - ic->ic_stats.is_tx_nobuf++; /* XXX */ - ath_freetx(m); - goto bad; + /* NB: ni ref & bf held on stageq */ + continue; } - } else { - /* - * Hack! The referenced node pointer is in the - * rcvif field of the packet header. This is - * placed there by ieee80211_mgmt_output because - * we need to hold the reference with the frame - * and there's no other way (other than packet - * tags which we consider too expensive to use) - * to pass it along. - */ - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - m->m_pkthdr.rcvif = NULL; - - wh = mtod(m, struct ieee80211_frame *); - if ((wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) == - IEEE80211_FC0_SUBTYPE_PROBE_RESP) { - /* fill time stamp */ - u_int64_t tsf; - u_int32_t *tstamp; - - tsf = ath_hal_gettsf64(ah); - /* XXX: adjust 100us delay to xmit */ - tsf += 100; - tstamp = (u_int32_t *)&wh[1]; - tstamp[0] = htole32(tsf & 0xffffffff); - tstamp[1] = htole32(tsf >> 32); - } - sc->sc_stats.ast_tx_mgmt++; } - + ifp->if_opackets++; + /* + * Encapsulate the packet in prep for transmission. + */ + m = ieee80211_encap(ni, m); + if (m == NULL) { + DPRINTF(sc, ATH_DEBUG_XMIT, + "%s: encapsulation failure\n", __func__); + sc->sc_stats.ast_tx_encap++; + goto bad; + } + /* + * Check for fragmentation. If this frame + * has been broken up verify we have enough + * buffers to send all the fragments so all + * go out or none... + */ + if ((m->m_flags & M_FRAG) && + !ath_txfrag_setup(sc, &frags, m, ni)) { + DPRINTF(sc, ATH_DEBUG_XMIT, + "%s: out of txfrag buffers\n", __func__); + ic->ic_stats.is_tx_nobuf++; /* XXX */ + ath_freetx(m); + goto bad; + } nextfrag: /* * Pass the frame to the h/w for transmission. @@ -1735,11 +2010,11 @@ ath_start(struct ifnet *ifp) * Beware of state changing between frags. * XXX check sta power-save state? */ - if (ic->ic_state != IEEE80211_S_RUN) { + if (ni->ni_vap->iv_state != IEEE80211_S_RUN) { DPRINTF(sc, ATH_DEBUG_XMIT, "%s: flush fragmented packet, state %s\n", __func__, - ieee80211_state_name[ic->ic_state]); + ieee80211_state_name[ni->ni_vap->iv_state]); ath_freetx(next); goto reclaim; } @@ -1751,7 +2026,6 @@ ath_start(struct ifnet *ifp) } ifp->if_timer = 5; - ic->ic_lastdata = ticks; #if 0 /* * Flush stale frames from the fast-frame staging queue. @@ -1765,30 +2039,9 @@ ath_start(struct ifnet *ifp) static int ath_media_change(struct ifnet *ifp) { -#define IS_UP(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - int error; - - error = ieee80211_media_change(ifp); - if (error == ENETRESET) { - struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - - if (ic->ic_opmode == IEEE80211_M_AHDEMO) { - /* - * Adhoc demo mode is just ibss mode w/o beacons - * (mostly). The hal knows nothing about it; - * tell it we're operating in ibss mode. - */ - sc->sc_opmode = HAL_M_IBSS; - } else - sc->sc_opmode = ic->ic_opmode; - if (IS_UP(ifp)) - ath_init(sc); /* XXX lose error */ - error = 0; - } - return error; -#undef IS_UP + int error = ieee80211_media_change(ifp); + /* NB: only the fixed rate can change and that doesn't need a reset */ + return (error == ENETRESET ? 0 : error); } #ifdef ATH_DEBUG @@ -1860,7 +2113,7 @@ ath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k, /* * Room for both TX+RX MIC keys in one key cache * slot, just set key at the first index; the hal - * will handle the reset. + * will handle the rest. */ memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); #if HAL_ABI_VERSION > 0x06052200 @@ -1869,13 +2122,16 @@ ath_keyset_tkip(struct ath_softc *sc, const struct ieee80211_key *k, KEYPRINTF(sc, k->wk_keyix, hk, mac); return ath_hal_keyset(ah, k->wk_keyix, hk, mac); } - } else if (k->wk_flags & IEEE80211_KEY_XR) { - /* - * TX/RX key goes at first index. - * The hal handles the MIC keys are index+64. - */ - memcpy(hk->kv_mic, k->wk_flags & IEEE80211_KEY_XMIT ? - k->wk_txmic : k->wk_rxmic, sizeof(hk->kv_mic)); + } else if (k->wk_flags & IEEE80211_KEY_XMIT) { +#if HAL_ABI_VERSION > 0x06052200 + memcpy(hk->kv_txmic, k->wk_txmic, sizeof(hk->kv_txmic)); +#else + memcpy(hk->kv_mic, k->wk_mic, sizeof(hk->kv_mic)); +#endif + KEYPRINTF(sc, k->wk_keyix, hk, mac); + return ath_hal_keyset(ah, k->wk_keyix, hk, mac); + } else if (k->wk_flags & IEEE80211_KEY_RECV) { + memcpy(hk->kv_mic, k->wk_rxmic, sizeof(hk->kv_mic)); KEYPRINTF(sc, k->wk_keyix, hk, mac); return ath_hal_keyset(ah, k->wk_keyix, hk, mac); } @@ -2091,10 +2347,10 @@ key_alloc_single(struct ath_softc *sc, * 64 entries. */ static int -ath_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, +ath_key_alloc(struct ieee80211vap *vap, const struct ieee80211_key *k, ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; /* * Group key allocation must be handled specially for @@ -2108,8 +2364,8 @@ ath_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, * multi-station operation. */ if ((k->wk_flags & IEEE80211_KEY_GROUP) && !sc->sc_mcastkey) { - if (!(&ic->ic_nw_keys[0] <= k && - k < &ic->ic_nw_keys[IEEE80211_WEP_NKID])) { + if (!(&vap->iv_nw_keys[0] <= k && + k < &vap->iv_nw_keys[IEEE80211_WEP_NKID])) { /* should not happen */ DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s: bogus group key\n", __func__); @@ -2119,7 +2375,7 @@ ath_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, * XXX we pre-allocate the global keys so * have no way to check if they've already been allocated. */ - *keyix = *rxkeyix = k - ic->ic_nw_keys; + *keyix = *rxkeyix = k - vap->iv_nw_keys; return 1; } @@ -2148,9 +2404,9 @@ ath_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, * Delete an entry in the key cache allocated by ath_key_alloc. */ static int -ath_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) +ath_key_delete(struct ieee80211vap *vap, const struct ieee80211_key *k) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; struct ath_hal *ah = sc->sc_ah; const struct ieee80211_cipher *cip = k->wk_cipher; u_int keyix = k->wk_keyix; @@ -2188,12 +2444,12 @@ ath_key_delete(struct ieee80211com *ic, const struct ieee80211_key *k) * slot(s) must already have been allocated by ath_key_alloc. */ static int -ath_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, +ath_key_set(struct ieee80211vap *vap, const struct ieee80211_key *k, const u_int8_t mac[IEEE80211_ADDR_LEN]) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; - return ath_keyset(sc, k, mac, ic->ic_bss); + return ath_keyset(sc, k, mac, vap->iv_bss); } /* @@ -2203,29 +2459,25 @@ ath_key_set(struct ieee80211com *ic, const struct ieee80211_key *k, * uses that originate in the driver. */ static void -ath_key_update_begin(struct ieee80211com *ic) +ath_key_update_begin(struct ieee80211vap *vap) { - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ath_softc *sc = ifp->if_softc; DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__); -#if 0 - tasklet_disable(&sc->sc_rxtq); -#endif + taskqueue_block(sc->sc_tq); IF_LOCK(&ifp->if_snd); /* NB: doesn't block mgmt frames */ } static void -ath_key_update_end(struct ieee80211com *ic) +ath_key_update_end(struct ieee80211vap *vap) { - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = vap->iv_ic->ic_ifp; struct ath_softc *sc = ifp->if_softc; DPRINTF(sc, ATH_DEBUG_KEYCACHE, "%s:\n", __func__); IF_UNLOCK(&ifp->if_snd); -#if 0 - tasklet_enable(&sc->sc_rxtq); -#endif + taskqueue_unblock(sc->sc_tq); } /* @@ -2233,80 +2485,101 @@ ath_key_update_end(struct ieee80211com *ic) * operating mode and state: * * o always accept unicast, broadcast, and multicast traffic - * o maintain current state of phy error reception (the hal - * may enable phy error frames for noise immunity work) + * o accept PHY error frames when hardware doesn't have MIB support + * to count and we need them for ANI (sta mode only at the moment) + * and we are not scanning (ANI is disabled) + * NB: only with recent hal's; older hal's add rx filter bits out + * of sight and we need to blindly preserve them * o probe request frames are accepted only when operating in * hostap, adhoc, or monitor modes - * o enable promiscuous mode according to the interface state + * o enable promiscuous mode + * - when in monitor mode + * - if interface marked PROMISC (assumes bridge setting is filtered) * o accept beacons: - * - when operating in adhoc mode so the 802.11 layer creates - * node table entries for peers, * - when operating in station mode for collecting rssi data when * the station is otherwise quiet, or + * - when operating in adhoc mode so the 802.11 layer creates + * node table entries for peers, * - when scanning + * - when doing s/w beacon miss (e.g. for ap+sta) + * - when operating in ap mode in 11g to detect overlapping bss that + * require protection * o accept control frames: * - when in monitor mode + * XXX BAR frames for 11n + * XXX HT protection for 11n */ static u_int32_t ath_calcrxfilter(struct ath_softc *sc) { -#define RX_FILTER_PRESERVE (HAL_RX_FILTER_PHYERR | HAL_RX_FILTER_PHYRADAR) - struct ieee80211com *ic = &sc->sc_ic; - struct ath_hal *ah = sc->sc_ah; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; u_int32_t rfilt; - rfilt = (ath_hal_getrxfilter(ah) & RX_FILTER_PRESERVE) +#if HAL_ABI_VERSION < 0x08011600 + rfilt = (ath_hal_getrxfilter(sc->sc_ah) & + (HAL_RX_FILTER_PHYRADAR | HAL_RX_FILTER_PHYERR)) | HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST; +#else + rfilt = HAL_RX_FILTER_UCAST | HAL_RX_FILTER_BCAST | HAL_RX_FILTER_MCAST; + if (ic->ic_opmode == IEEE80211_M_STA && + !sc->sc_needmib && !sc->sc_scanning) + rfilt |= HAL_RX_FILTER_PHYERR; +#endif if (ic->ic_opmode != IEEE80211_M_STA) rfilt |= HAL_RX_FILTER_PROBEREQ; - if (ic->ic_opmode != IEEE80211_M_HOSTAP && - (ifp->if_flags & IFF_PROMISC)) + if (ic->ic_opmode == IEEE80211_M_MONITOR || (ifp->if_flags & IFF_PROMISC)) rfilt |= HAL_RX_FILTER_PROM; if (ic->ic_opmode == IEEE80211_M_STA || - ic->ic_opmode == IEEE80211_M_IBSS || - sc->sc_scanning) + sc->sc_opmode == HAL_M_IBSS || + sc->sc_swbmiss || sc->sc_scanning) + rfilt |= HAL_RX_FILTER_BEACON; + /* + * NB: We don't recalculate the rx filter when + * ic_protmode changes; otherwise we could do + * this only when ic_protmode != NONE. + */ + if (ic->ic_opmode == IEEE80211_M_HOSTAP && + IEEE80211_IS_CHAN_ANYG(ic->ic_curchan)) rfilt |= HAL_RX_FILTER_BEACON; if (ic->ic_opmode == IEEE80211_M_MONITOR) rfilt |= HAL_RX_FILTER_CONTROL; + DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x, %s if_flags 0x%x\n", + __func__, rfilt, ieee80211_opmode_name[ic->ic_opmode], ifp->if_flags); return rfilt; -#undef RX_FILTER_PRESERVE } static void -ath_mode_init(struct ath_softc *sc) +ath_update_promisc(struct ifnet *ifp) { - struct ieee80211com *ic = &sc->sc_ic; - struct ath_hal *ah = sc->sc_ah; - struct ifnet *ifp = sc->sc_ifp; - u_int32_t rfilt, mfilt[2], val; - u_int8_t pos; - struct ifmultiaddr *ifma; + struct ath_softc *sc = ifp->if_softc; + u_int32_t rfilt; /* configure rx filter */ rfilt = ath_calcrxfilter(sc); - ath_hal_setrxfilter(ah, rfilt); + ath_hal_setrxfilter(sc->sc_ah, rfilt); - /* configure operational mode */ - ath_hal_setopmode(ah); + DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x\n", __func__, rfilt); +} - /* - * Handle any link-level address change. Note that we only - * need to force ic_myaddr; any other addresses are handled - * as a byproduct of the ifnet code marking the interface - * down then up. - * - * XXX should get from lladdr instead of arpcom but that's more work - */ - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - ath_hal_setmac(ah, ic->ic_myaddr); +static void +ath_update_mcast(struct ifnet *ifp) +{ + struct ath_softc *sc = ifp->if_softc; + u_int32_t mfilt[2]; /* calculate and install multicast filter */ if ((ifp->if_flags & IFF_ALLMULTI) == 0) { + struct ifmultiaddr *ifma; + /* + * Merge multicast addresses to form the hardware filter. + */ mfilt[0] = mfilt[1] = 0; - IF_ADDR_LOCK(ifp); + IF_ADDR_LOCK(ifp); /* XXX need some fiddling to remove? */ TAILQ_FOREACH(ifma, &ifp->if_multiaddrs, ifma_link) { caddr_t dl; + u_int32_t val; + u_int8_t pos; /* calculate XOR of eight 6bit values */ dl = LLADDR((struct sockaddr_dl *) ifma->ifma_addr); @@ -2318,12 +2591,41 @@ ath_mode_init(struct ath_softc *sc) mfilt[pos / 32] |= (1 << (pos % 32)); } IF_ADDR_UNLOCK(ifp); - } else { + } else mfilt[0] = mfilt[1] = ~0; - } - ath_hal_setmcastfilter(ah, mfilt[0], mfilt[1]); - DPRINTF(sc, ATH_DEBUG_MODE, "%s: RX filter 0x%x, MC filter %08x:%08x\n", - __func__, rfilt, mfilt[0], mfilt[1]); + ath_hal_setmcastfilter(sc->sc_ah, mfilt[0], mfilt[1]); + DPRINTF(sc, ATH_DEBUG_MODE, "%s: MC filter %08x:%08x\n", + __func__, mfilt[0], mfilt[1]); +} + +static void +ath_mode_init(struct ath_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ath_hal *ah = sc->sc_ah; + u_int32_t rfilt; + + /* configure rx filter */ + rfilt = ath_calcrxfilter(sc); + ath_hal_setrxfilter(ah, rfilt); + + /* configure operational mode */ + ath_hal_setopmode(ah); + + /* + * Handle any link-level address change. Note that we only + * need to force ic_myaddr; any other addresses are handled + * as a byproduct of the ifnet code marking the interface + * down then up. + * + * XXX should get from lladdr instead of arpcom but that's more work + */ + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); + ath_hal_setmac(ah, ic->ic_myaddr); + + /* calculate and install multicast filter */ + ath_update_mcast(ifp); } /* @@ -2332,7 +2634,7 @@ ath_mode_init(struct ath_softc *sc) static void ath_setslottime(struct ath_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; u_int usec; @@ -2367,7 +2669,7 @@ static void ath_updateslot(struct ifnet *ifp) { struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; /* * When not coordinating the BSS, change the hardware @@ -2404,7 +2706,7 @@ static int ath_beaconq_config(struct ath_softc *sc) { #define ATH_EXPONENT_TO_VALUE(v) ((1<<(v))-1) - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; HAL_TXQ_INFO qi; @@ -2444,38 +2746,81 @@ ath_beaconq_config(struct ath_softc *sc) static int ath_beacon_alloc(struct ath_softc *sc, struct ieee80211_node *ni) { + struct ieee80211vap *vap = ni->ni_vap; + struct ath_vap *avp = ATH_VAP(vap); struct ath_buf *bf; struct mbuf *m; int error; - bf = STAILQ_FIRST(&sc->sc_bbuf); - if (bf == NULL) { - DPRINTF(sc, ATH_DEBUG_BEACON, "%s: no dma buffers\n", __func__); - sc->sc_stats.ast_be_nombuf++; /* XXX */ - return ENOMEM; /* XXX */ + bf = avp->av_bcbuf; + if (bf->bf_m != NULL) { + bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); + m_freem(bf->bf_m); + bf->bf_m = NULL; + } + if (bf->bf_node != NULL) { + ieee80211_free_node(bf->bf_node); + bf->bf_node = NULL; } + /* * NB: the beacon data buffer must be 32-bit aligned; * we assume the mbuf routines will return us something * with this alignment (perhaps should assert). */ - m = ieee80211_beacon_alloc(ni, &sc->sc_boff); + m = ieee80211_beacon_alloc(ni, &avp->av_boff); if (m == NULL) { - DPRINTF(sc, ATH_DEBUG_BEACON, "%s: cannot get mbuf\n", - __func__); + device_printf(sc->sc_dev, "%s: cannot get mbuf\n", __func__); sc->sc_stats.ast_be_nombuf++; return ENOMEM; } error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, bf->bf_segs, &bf->bf_nseg, BUS_DMA_NOWAIT); - if (error == 0) { - bf->bf_m = m; - bf->bf_node = ieee80211_ref_node(ni); - } else { + if (error != 0) { + device_printf(sc->sc_dev, + "%s: cannot map mbuf, bus_dmamap_load_mbuf_sg returns %d\n", + __func__, error); m_freem(m); + return error; } - return error; + + /* + * Calculate a TSF adjustment factor required for staggered + * beacons. Note that we assume the format of the beacon + * frame leaves the tstamp field immediately following the + * header. + */ + if (sc->sc_stagbeacons && avp->av_bslot > 0) { + uint64_t tsfadjust; + struct ieee80211_frame *wh; + + /* + * The beacon interval is in TU's; the TSF is in usecs. + * We figure out how many TU's to add to align the timestamp + * then convert to TSF units and handle byte swapping before + * inserting it in the frame. The hardware will then add this + * each time a beacon frame is sent. Note that we align vap's + * 1..N and leave vap 0 untouched. This means vap 0 has a + * timestamp in one beacon interval while the others get a + * timstamp aligned to the next interval. + */ + tsfadjust = ni->ni_intval * + (ATH_BCBUF - avp->av_bslot) / ATH_BCBUF; + tsfadjust = htole64(tsfadjust << 10); /* TU -> TSF */ + + DPRINTF(sc, ATH_DEBUG_BEACON, + "%s: %s beacons bslot %d intval %u tsfadjust %llu\n", + __func__, sc->sc_stagbeacons ? "stagger" : "burst", + avp->av_bslot, ni->ni_intval, le64toh(tsfadjust)); + + wh = mtod(m, struct ieee80211_frame *); + memcpy(&wh[1], &tsfadjust, sizeof(tsfadjust)); + } + bf->bf_m = m; + bf->bf_node = ieee80211_ref_node(ni); + + return 0; } /* @@ -2516,8 +2861,12 @@ ath_beacon_setup(struct ath_softc *sc, struct ath_buf *bf) * Switch antenna every 4 beacons. * XXX assumes two antenna */ - antenna = sc->sc_txantenna != 0 ? sc->sc_txantenna - : (sc->sc_stats.ast_be_xmit & 4 ? 2 : 1); + if (sc->sc_txantenna != 0) + antenna = sc->sc_txantenna; + else if (sc->sc_stagbeacons && sc->sc_nbcnvaps != 0) + antenna = ((sc->sc_stats.ast_be_xmit / sc->sc_nbcnvaps) & 4 ? 2 : 1); + else + antenna = (sc->sc_stats.ast_be_xmit & 4 ? 2 : 1); } KASSERT(bf->bf_nseg == 1, @@ -2527,7 +2876,7 @@ ath_beacon_setup(struct ath_softc *sc, struct ath_buf *bf) * Calculate rate code. * XXX everything at min xmit rate */ - rix = sc->sc_minrateix; + rix = 0; rt = sc->sc_currates; rate = rt->info[rix].rateCode; if (USE_SHPREAMBLE(ic)) @@ -2551,14 +2900,16 @@ ath_beacon_setup(struct ath_softc *sc, struct ath_buf *bf) , AH_TRUE /* last segment */ , ds /* first descriptor */ ); +#if 0 + ath_desc_swap(ds); +#endif #undef USE_SHPREAMBLE } static void -ath_beacon_update(struct ieee80211com *ic, int item) +ath_beacon_update(struct ieee80211vap *vap, int item) { - struct ath_softc *sc = ic->ic_ifp->if_softc; - struct ieee80211_beacon_offsets *bo = &sc->sc_boff; + struct ieee80211_beacon_offsets *bo = &ATH_VAP(vap)->av_boff; setbit(bo->bo_flags, item); } @@ -2586,24 +2937,14 @@ static void ath_beacon_proc(void *arg, int pending) { struct ath_softc *sc = arg; - struct ath_buf *bf = STAILQ_FIRST(&sc->sc_bbuf); - struct ieee80211_node *ni = bf->bf_node; - struct ieee80211com *ic = ni->ni_ic; struct ath_hal *ah = sc->sc_ah; - struct ath_txq *cabq = sc->sc_cabq; - struct mbuf *m; - int ncabq, nmcastq, error, otherant; + struct ieee80211vap *vap; + struct ath_buf *bf; + int slot, otherant; + uint32_t bfaddr; DPRINTF(sc, ATH_DEBUG_BEACON_PROC, "%s: pending %u\n", __func__, pending); - - if (ic->ic_opmode == IEEE80211_M_STA || - ic->ic_opmode == IEEE80211_M_MONITOR || - bf == NULL || bf->bf_m == NULL) { - DPRINTF(sc, ATH_DEBUG_ANY, "%s: ic_flags=%x bf=%p bf_m=%p\n", - __func__, ic->ic_flags, bf, bf ? bf->bf_m : NULL); - return; - } /* * Check if the previous beacon has gone out. If * not don't try to post another, skip this period @@ -2627,39 +2968,34 @@ ath_beacon_proc(void *arg, int pending) sc->sc_bmisscount = 0; } - /* - * Update dynamic beacon contents. If this returns - * non-zero then we need to remap the memory because - * the beacon frame changed size (probably because - * of the TIM bitmap). - */ - m = bf->bf_m; - nmcastq = sc->sc_mcastq.axq_depth; - ncabq = ath_hal_numtxpending(ah, cabq->axq_qnum); - if (ieee80211_beacon_update(bf->bf_node, &sc->sc_boff, m, ncabq+nmcastq)) { - /* XXX too conservative? */ - bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); - error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, - bf->bf_segs, &bf->bf_nseg, - BUS_DMA_NOWAIT); - if (error != 0) { - if_printf(ic->ic_ifp, - "%s: bus_dmamap_load_mbuf_sg failed, error %u\n", - __func__, error); - return; + if (sc->sc_stagbeacons) { /* staggered beacons */ + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + uint32_t tsftu; + + tsftu = ath_hal_gettsf32(ah) >> 10; + /* XXX lintval */ + slot = ((tsftu % ic->ic_lintval) * ATH_BCBUF) / ic->ic_lintval; + vap = sc->sc_bslot[(slot+1) % ATH_BCBUF]; + bfaddr = 0; + if (vap != NULL && vap->iv_state == IEEE80211_S_RUN) { + bf = ath_beacon_generate(sc, vap); + if (bf != NULL) + bfaddr = bf->bf_daddr; } - } - if (ncabq && (sc->sc_boff.bo_tim[4] & 1)) { - /* - * CABQ traffic from the previous DTIM is still pending. - * This is ok for now but when there are multiple vap's - * and we are using staggered beacons we'll want to drain - * the cabq before loading frames for the different vap. - */ - DPRINTF(sc, ATH_DEBUG_BEACON, - "%s: cabq did not drain, mcastq %u cabq %u/%u\n", - __func__, nmcastq, ncabq, cabq->axq_depth); - sc->sc_stats.ast_cabq_busy++; + } else { /* burst'd beacons */ + uint32_t *bflink = &bfaddr; + + for (slot = 0; slot < ATH_BCBUF; slot++) { + vap = sc->sc_bslot[slot]; + if (vap != NULL && vap->iv_state == IEEE80211_S_RUN) { + bf = ath_beacon_generate(sc, vap); + if (bf != NULL) { + *bflink = bf->bf_daddr; + bflink = &bf->bf_desc->ds_link; + } + } + } + *bflink = 0; /* terminate list */ } /* @@ -2670,9 +3006,10 @@ ath_beacon_proc(void *arg, int pending) * beacon interval to note the state change. */ /* XXX locking */ - if (sc->sc_updateslot == UPDATE) + if (sc->sc_updateslot == UPDATE) { sc->sc_updateslot = COMMIT; /* commit next beacon */ - else if (sc->sc_updateslot == COMMIT) + sc->sc_slotupdate = slot; + } else if (sc->sc_updateslot == COMMIT && sc->sc_slotupdate == slot) ath_setslottime(sc); /* commit change to h/w */ /* @@ -2681,64 +3018,159 @@ ath_beacon_proc(void *arg, int pending) * on the non-default antenna. * XXX assumes 2 anntenae */ - otherant = sc->sc_defant & 1 ? 2 : 1; - if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 2) - ath_setdefantenna(sc, otherant); - sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0; + if (!sc->sc_diversity && (!sc->sc_stagbeacons || slot == 0)) { + otherant = sc->sc_defant & 1 ? 2 : 1; + if (sc->sc_ant_tx[otherant] > sc->sc_ant_tx[sc->sc_defant] + 2) + ath_setdefantenna(sc, otherant); + sc->sc_ant_tx[1] = sc->sc_ant_tx[2] = 0; + } - /* - * Construct tx descriptor. - */ - ath_beacon_setup(sc, bf); + if (bfaddr != 0) { + /* + * Stop any current dma and put the new frame on the queue. + * This should never fail since we check above that no frames + * are still pending on the queue. + */ + if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) { + DPRINTF(sc, ATH_DEBUG_ANY, + "%s: beacon queue %u did not stop?\n", + __func__, sc->sc_bhalq); + } + /* NB: cabq traffic should already be queued and primed */ + ath_hal_puttxbuf(ah, sc->sc_bhalq, bfaddr); + ath_hal_txstart(ah, sc->sc_bhalq); + + sc->sc_stats.ast_be_xmit++; + } +} + +static struct ath_buf * +ath_beacon_generate(struct ath_softc *sc, struct ieee80211vap *vap) +{ + struct ath_vap *avp = ATH_VAP(vap); + struct ath_txq *cabq = sc->sc_cabq; + struct ath_buf *bf; + struct mbuf *m; + int nmcastq, error; + + KASSERT(vap->iv_state == IEEE80211_S_RUN, + ("not running, state %d", vap->iv_state)); + KASSERT(avp->av_bcbuf != NULL, ("no beacon buffer")); /* - * Stop any current dma and put the new frame on the queue. - * This should never fail since we check above that no frames - * are still pending on the queue. + * Update dynamic beacon contents. If this returns + * non-zero then we need to remap the memory because + * the beacon frame changed size (probably because + * of the TIM bitmap). */ - if (!ath_hal_stoptxdma(ah, sc->sc_bhalq)) { - DPRINTF(sc, ATH_DEBUG_ANY, - "%s: beacon queue %u did not stop?\n", - __func__, sc->sc_bhalq); + bf = avp->av_bcbuf; + m = bf->bf_m; + nmcastq = avp->av_mcastq.axq_depth; + if (ieee80211_beacon_update(bf->bf_node, &avp->av_boff, m, nmcastq)) { + /* XXX too conservative? */ + bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); + error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, + bf->bf_segs, &bf->bf_nseg, + BUS_DMA_NOWAIT); + if (error != 0) { + if_printf(vap->iv_ifp, + "%s: bus_dmamap_load_mbuf_sg failed, error %u\n", + __func__, error); + return NULL; + } } + if ((avp->av_boff.bo_tim[4] & 1) && cabq->axq_depth) { + DPRINTF(sc, ATH_DEBUG_BEACON, + "%s: cabq did not drain, mcastq %u cabq %u\n", + __func__, nmcastq, cabq->axq_depth); + sc->sc_stats.ast_cabq_busy++; + if (sc->sc_nvaps > 1 && sc->sc_stagbeacons) { + /* + * CABQ traffic from a previous vap is still pending. + * We must drain the q before this beacon frame goes + * out as otherwise this vap's stations will get cab + * frames from a different vap. + * XXX could be slow causing us to miss DBA + */ + ath_tx_draintxq(sc, cabq); + } + } + ath_beacon_setup(sc, bf); bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); /* * Enable the CAB queue before the beacon queue to * insure cab frames are triggered by this beacon. */ - if (sc->sc_boff.bo_tim_len && (sc->sc_boff.bo_tim[4] & 1)) { + if (avp->av_boff.bo_tim[4] & 1) { + struct ath_hal *ah = sc->sc_ah; + /* NB: only at DTIM */ ATH_TXQ_LOCK(cabq); - ATH_TXQ_LOCK(&sc->sc_mcastq); + ATH_TXQ_LOCK(&avp->av_mcastq); if (nmcastq) { struct ath_buf *bfm; /* * Move frames from the s/w mcast q to the h/w cab q. + * XXX MORE_DATA bit */ - bfm = STAILQ_FIRST(&sc->sc_mcastq.axq_q); + bfm = STAILQ_FIRST(&avp->av_mcastq.axq_q); if (cabq->axq_link != NULL) { *cabq->axq_link = bfm->bf_daddr; } else ath_hal_puttxbuf(ah, cabq->axq_qnum, bfm->bf_daddr); - ath_txqmove(cabq, &sc->sc_mcastq); + ath_txqmove(cabq, &avp->av_mcastq); sc->sc_stats.ast_cabq_xmit += nmcastq; } /* NB: gated by beacon so safe to start here */ ath_hal_txstart(ah, cabq->axq_qnum); ATH_TXQ_UNLOCK(cabq); - ATH_TXQ_UNLOCK(&sc->sc_mcastq); + ATH_TXQ_UNLOCK(&avp->av_mcastq); } + return bf; +} + +static void +ath_beacon_start_adhoc(struct ath_softc *sc, struct ieee80211vap *vap) +{ + struct ath_vap *avp = ATH_VAP(vap); + struct ath_hal *ah = sc->sc_ah; + struct ath_buf *bf; + struct mbuf *m; + int error; + + KASSERT(avp->av_bcbuf != NULL, ("no beacon buffer")); + + /* + * Update dynamic beacon contents. If this returns + * non-zero then we need to remap the memory because + * the beacon frame changed size (probably because + * of the TIM bitmap). + */ + bf = avp->av_bcbuf; + m = bf->bf_m; + if (ieee80211_beacon_update(bf->bf_node, &avp->av_boff, m, 0)) { + /* XXX too conservative? */ + bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); + error = bus_dmamap_load_mbuf_sg(sc->sc_dmat, bf->bf_dmamap, m, + bf->bf_segs, &bf->bf_nseg, + BUS_DMA_NOWAIT); + if (error != 0) { + if_printf(vap->iv_ifp, + "%s: bus_dmamap_load_mbuf_sg failed, error %u\n", + __func__, error); + return; + } + } + ath_beacon_setup(sc, bf); + bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_PREWRITE); + + /* NB: caller is known to have already stopped tx dma */ ath_hal_puttxbuf(ah, sc->sc_bhalq, bf->bf_daddr); ath_hal_txstart(ah, sc->sc_bhalq); - DPRINTF(sc, ATH_DEBUG_BEACON_PROC, - "%s: TXDP[%u] = %p (%p)\n", __func__, - sc->sc_bhalq, (caddr_t)bf->bf_daddr, bf->bf_desc); - - sc->sc_stats.ast_be_xmit++; } /* @@ -2750,9 +3182,28 @@ ath_bstuck_proc(void *arg, int pending) struct ath_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; - if_printf(ifp, "stuck beacon; resetting (bmiss count %u)\n", - sc->sc_bmisscount); - ath_reset(ifp); + if_printf(ifp, "stuck beacon; resetting (bmiss count %u)\n", + sc->sc_bmisscount); + ath_reset(ifp); +} + +/* + * Reclaim beacon resources and return buffer to the pool. + */ +static void +ath_beacon_return(struct ath_softc *sc, struct ath_buf *bf) +{ + + if (bf->bf_m != NULL) { + bus_dmamap_unload(sc->sc_dmat, bf->bf_dmamap); + m_freem(bf->bf_m); + bf->bf_m = NULL; + } + if (bf->bf_node != NULL) { + ieee80211_free_node(bf->bf_node); + bf->bf_node = NULL; + } + STAILQ_INSERT_TAIL(&sc->sc_bbuf, bf, bf_list); } /* @@ -2792,29 +3243,46 @@ ath_beacon_free(struct ath_softc *sc) * we've associated with. */ static void -ath_beacon_config(struct ath_softc *sc) +ath_beacon_config(struct ath_softc *sc, struct ieee80211vap *vap) { #define TSF_TO_TU(_h,_l) \ ((((u_int32_t)(_h)) << 22) | (((u_int32_t)(_l)) >> 10)) #define FUDGE 2 struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + struct ieee80211_node *ni; u_int32_t nexttbtt, intval, tsftu; u_int64_t tsf; + if (vap == NULL) + vap = TAILQ_FIRST(&ic->ic_vaps); /* XXX */ + ni = vap->iv_bss; + /* extract tstamp from last beacon and convert to TU */ nexttbtt = TSF_TO_TU(LE_READ_4(ni->ni_tstamp.data + 4), LE_READ_4(ni->ni_tstamp.data)); - /* NB: the beacon interval is kept internally in TU's */ - intval = ni->ni_intval & HAL_BEACON_PERIOD; + if (ic->ic_opmode == IEEE80211_M_HOSTAP) { + /* + * For multi-bss ap support beacons are either staggered + * evenly over N slots or burst together. For the former + * arrange for the SWBA to be delivered for each slot. + * Slots that are not occupied will generate nothing. + */ + /* NB: the beacon interval is kept internally in TU's */ + intval = ni->ni_intval & HAL_BEACON_PERIOD; + if (sc->sc_stagbeacons) + intval /= ATH_BCBUF; + } else { + /* NB: the beacon interval is kept internally in TU's */ + intval = ni->ni_intval & HAL_BEACON_PERIOD; + } if (nexttbtt == 0) /* e.g. for ap mode */ nexttbtt = intval; else if (intval) /* NB: can be 0 for monitor mode */ nexttbtt = roundup(nexttbtt, intval); DPRINTF(sc, ATH_DEBUG_BEACON, "%s: nexttbtt %u intval %u (%u)\n", __func__, nexttbtt, intval, ni->ni_intval); - if (ic->ic_opmode == IEEE80211_M_STA) { + if (ic->ic_opmode == IEEE80211_M_STA && !sc->sc_swbmiss) { HAL_BEACON_STATE bs; int dtimperiod, dtimcount; int cfpperiod, cfpcount; @@ -2870,7 +3338,7 @@ ath_beacon_config(struct ath_softc *sc) * before taking a BMISS interrupt. * Note that we clamp the result to at most 10 beacons. */ - bs.bs_bmissthreshold = ic->ic_bmissthreshold; + bs.bs_bmissthreshold = vap->iv_bmissthreshold; if (bs.bs_bmissthreshold > 10) bs.bs_bmissthreshold = 10; else if (bs.bs_bmissthreshold <= 0) @@ -2953,7 +3421,7 @@ ath_beacon_config(struct ath_softc *sc) * ibss mode load it once here. */ if (ic->ic_opmode == IEEE80211_M_IBSS && sc->sc_hasveol) - ath_beacon_proc(sc, 0); + ath_beacon_start_adhoc(sc, vap); } sc->sc_syncbeacon = 0; #undef FUDGE @@ -3130,7 +3598,7 @@ ath_desc_alloc(struct ath_softc *sc) } error = ath_descdma_setup(sc, &sc->sc_bdma, &sc->sc_bbuf, - "beacon", 1, 1); + "beacon", ATH_BCBUF, 1); if (error != 0) { ath_descdma_cleanup(sc, &sc->sc_txdma, &sc->sc_txbuf); ath_descdma_cleanup(sc, &sc->sc_rxdma, &sc->sc_rxbuf); @@ -3164,7 +3632,6 @@ ath_node_alloc(struct ieee80211_node_table *nt) /* XXX stat+msg */ return NULL; } - an->an_avgrssi = ATH_RSSI_DUMMY_MARKER; ath_rate_node_init(sc, an); DPRINTF(sc, ATH_DEBUG_NODE, "%s: an %p\n", __func__, an); @@ -3183,26 +3650,6 @@ ath_node_free(struct ieee80211_node *ni) sc->sc_node_free(ni); } -static int8_t -ath_node_getrssi(const struct ieee80211_node *ni) -{ -#define HAL_EP_RND(x, mul) \ - ((((x)%(mul)) >= ((mul)/2)) ? ((x) + ((mul) - 1)) / (mul) : (x)/(mul)) - u_int32_t avgrssi = ATH_NODE_CONST(ni)->an_avgrssi; - int32_t rssi; - - /* - * When only one frame is received there will be no state in - * avgrssi so fallback on the value recorded by the 802.11 layer. - */ - if (avgrssi != ATH_RSSI_DUMMY_MARKER) - rssi = HAL_EP_RND(avgrssi, HAL_RSSI_EP_MULTIPLIER); - else - rssi = ni->ni_rssi; - return rssi < 0 ? 0 : rssi > 127 ? 127 : rssi; -#undef HAL_EP_RND -} - static void ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise) { @@ -3211,7 +3658,7 @@ ath_node_getsignal(const struct ieee80211_node *ni, int8_t *rssi, int8_t *noise) struct ath_hal *ah = sc->sc_ah; HAL_CHANNEL hchan; - *rssi = ath_node_getrssi(ni); + *rssi = ic->ic_node_getrssi(ni); if (ni->ni_chan != IEEE80211_CHAN_ANYC) { ath_mapchan(&hchan, ni->ni_chan); *noise = ath_hal_getchannoise(ah, &hchan); @@ -3309,33 +3756,33 @@ ath_extend_tsf(u_int32_t rstamp, u_int64_t tsf) * and to do ibss merges. */ static void -ath_recv_mgmt(struct ieee80211com *ic, struct mbuf *m, - struct ieee80211_node *ni, +ath_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, int subtype, int rssi, int noise, u_int32_t rstamp) { - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ieee80211vap *vap = ni->ni_vap; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; /* * Call up first so subsequent work can use information * potentially stored in the node (e.g. for ibss merge). */ - sc->sc_recv_mgmt(ic, m, ni, subtype, rssi, noise, rstamp); + ATH_VAP(vap)->av_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); switch (subtype) { case IEEE80211_FC0_SUBTYPE_BEACON: /* update rssi statistics for use by the hal */ ATH_RSSI_LPF(sc->sc_halstats.ns_avgbrssi, rssi); if (sc->sc_syncbeacon && - ni == ic->ic_bss && ic->ic_state == IEEE80211_S_RUN) { + ni == vap->iv_bss && vap->iv_state == IEEE80211_S_RUN) { /* * Resync beacon timers using the tsf of the beacon * frame we just received. */ - ath_beacon_config(sc); + ath_beacon_config(sc, vap); } /* fall thru... */ case IEEE80211_FC0_SUBTYPE_PROBE_RESP: - if (ic->ic_opmode == IEEE80211_M_IBSS && - ic->ic_state == IEEE80211_S_RUN) { + if (vap->iv_opmode == IEEE80211_M_IBSS && + vap->iv_state == IEEE80211_S_RUN) { u_int64_t tsf = ath_extend_tsf(rstamp, ath_hal_gettsf64(sc->sc_ah)); /* @@ -3377,14 +3824,13 @@ ath_setdefantenna(struct ath_softc *sc, u_int antenna) } static int -ath_rx_tap(struct ath_softc *sc, struct mbuf *m, +ath_rx_tap(struct ifnet *ifp, struct mbuf *m, const struct ath_rx_status *rs, u_int64_t tsf, int16_t nf) { #define CHANNEL_HT (CHANNEL_HT20|CHANNEL_HT40PLUS|CHANNEL_HT40MINUS) + struct ath_softc *sc = ifp->if_softc; u_int8_t rix; - KASSERT(sc->sc_drvbpf != NULL, ("no tap")); - /* * Discard anything shorter than an ack or cts. */ @@ -3425,13 +3871,28 @@ ath_rx_tap(struct ath_softc *sc, struct mbuf *m, sc->sc_rx_th.wr_antnoise = nf; sc->sc_rx_th.wr_antenna = rs->rs_antenna; - bpf_mtap2(sc->sc_drvbpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); + bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); return 1; #undef CHANNEL_HT } static void +ath_handle_micerror(struct ieee80211com *ic, + struct ieee80211_frame *wh, int keyix) +{ + struct ieee80211_node *ni; + + /* XXX recheck MIC to deal w/ chips that lie */ + /* XXX discard MIC errors on !data frames */ + ni = ieee80211_find_rxnode(ic, (const struct ieee80211_frame_min *) wh); + if (ni != NULL) { + ieee80211_notify_michael_failure(ni->ni_vap, wh, keyix); + ieee80211_free_node(ni); + } +} + +static void ath_rx_proc(void *arg, int npending) { #define PA2DESC(_sc, _pa) \ @@ -3439,21 +3900,19 @@ ath_rx_proc(void *arg, int npending) ((_pa) - (_sc)->sc_rxdma.dd_desc_paddr))) struct ath_softc *sc = arg; struct ath_buf *bf; - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; struct ath_desc *ds; struct ath_rx_status *rs; struct mbuf *m; struct ieee80211_node *ni; - struct ath_node *an; int len, type, ngood; u_int phyerr; HAL_STATUS status; int16_t nf; u_int64_t tsf; - DPRINTF(sc, ATH_DEBUG_RX_PROC, "%s: pending %u\n", __func__, npending); ngood = 0; nf = ath_hal_getchannoise(ah, &sc->sc_curchan); @@ -3540,11 +3999,10 @@ ath_rx_proc(void *arg, int npending) bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD); - ieee80211_notify_michael_failure(ic, + ath_handle_micerror(ic, mtod(m, struct ieee80211_frame *), sc->sc_splitmic ? - rs->rs_keyix-32 : rs->rs_keyix - ); + rs->rs_keyix-32 : rs->rs_keyix); } } ifp->if_ierrors++; @@ -3562,14 +4020,14 @@ rx_error: * pass decrypt+mic errors but others may be * interesting (e.g. crc). */ - if (bpf_peers_present(sc->sc_drvbpf) && + if (bpf_peers_present(ifp->if_bpf) && (rs->rs_status & sc->sc_monpass)) { bus_dmamap_sync(sc->sc_dmat, bf->bf_dmamap, BUS_DMASYNC_POSTREAD); /* NB: bpf needs the mbuf length setup */ len = rs->rs_datalen; m->m_pkthdr.len = m->m_len = len; - (void) ath_rx_tap(sc, m, rs, tsf, nf); + (void) ath_rx_tap(ifp, m, rs, tsf, nf); } /* XXX pass MIC errors up for s/w reclaculation */ goto rx_next; @@ -3624,10 +4082,11 @@ rx_accept: m->m_pkthdr.len = len; } + ifp->if_ipackets++; sc->sc_stats.ast_ant_rx[rs->rs_antenna]++; - if (bpf_peers_present(sc->sc_drvbpf) && - !ath_rx_tap(sc, m, rs, tsf, nf)) { + if (bpf_peers_present(ifp->if_bpf) && + !ath_rx_tap(ifp, m, rs, tsf, nf)) { m_freem(m); /* XXX reclaim */ goto rx_next; } @@ -3661,18 +4120,30 @@ rx_accept: mtod(m, const struct ieee80211_frame_min *), rs->rs_keyix == HAL_RXKEYIX_INVALID ? IEEE80211_KEYIX_NONE : rs->rs_keyix); + if (ni != NULL) { + /* + * Sending station is known, dispatch directly. + */ + type = ieee80211_input(ni, m, + rs->rs_rssi, nf, rs->rs_tstamp); + ieee80211_free_node(ni); + /* + * Arrange to update the last rx timestamp only for + * frames from our ap when operating in station mode. + * This assumes the rx key is always setup when + * associated. + */ + if (ic->ic_opmode == IEEE80211_M_STA && + rs->rs_keyix != HAL_RXKEYIX_INVALID) + ngood++; + } else { + type = ieee80211_input_all(ic, m, + rs->rs_rssi, nf, rs->rs_tstamp); + } /* * Track rx rssi and do any rx antenna management. */ - an = ATH_NODE(ni); - ATH_RSSI_LPF(an->an_avgrssi, rs->rs_rssi); ATH_RSSI_LPF(sc->sc_halstats.ns_avgrssi, rs->rs_rssi); - /* - * Send frame up for processing. - */ - type = ieee80211_input(ic, m, ni, - rs->rs_rssi, nf, rs->rs_tstamp); - ieee80211_free_node(ni); if (sc->sc_diversity) { /* * When using fast diversity, change the default rx @@ -3698,14 +4169,6 @@ rx_accept: } else if (ticks - sc->sc_ledevent >= sc->sc_ledidle) ath_led_event(sc, ATH_LED_POLL); } - /* - * Arrange to update the last rx timestamp only for - * frames from our ap when operating in station mode. - * This assumes the rx key is always setup when associated. - */ - if (ic->ic_opmode == IEEE80211_M_STA && - rs->rs_keyix != HAL_RXKEYIX_INVALID) - ngood++; rx_next: STAILQ_INSERT_TAIL(&sc->sc_rxbuf, bf, bf_list); } while (ath_rxbuf_init(sc, bf) == 0); @@ -3715,7 +4178,6 @@ rx_next: if (ngood) sc->sc_lastrx = tsf; - /* NB: may want to check mgtq too */ if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && !IFQ_IS_EMPTY(&ifp->if_snd)) ath_start(ifp); @@ -3825,7 +4287,8 @@ ath_txq_update(struct ath_softc *sc, int ac) { #define ATH_EXPONENT_TO_VALUE(v) ((1<sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_txq *txq = sc->sc_ac2q[ac]; struct wmeParams *wmep = &ic->ic_wme.wme_chanParams.cap_wmeParams[ac]; struct ath_hal *ah = sc->sc_ah; @@ -3838,7 +4301,7 @@ ath_txq_update(struct ath_softc *sc, int ac) qi.tqi_burstTime = ATH_TXOP_TO_US(wmep->wmep_txopLimit); if (!ath_hal_settxqueueprops(ah, txq->axq_qnum, &qi)) { - device_printf(sc->sc_dev, "unable to update hardware queue " + if_printf(ifp, "unable to update hardware queue " "parameters for %s traffic!\n", ieee80211_wme_acnames[ac]); return 0; @@ -3888,7 +4351,6 @@ ath_tx_cleanup(struct ath_softc *sc) for (i = 0; i < HAL_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_cleanupq(sc, &sc->sc_txq[i]); - ATH_TXQ_LOCK_DESTROY(&sc->sc_mcastq); } /* @@ -4016,8 +4478,8 @@ ath_tx_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf) * to avoid possible races. */ ATH_TXQ_LOCK(txq); - ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); - if (txq != &sc->sc_mcastq) { + if (txq->axq_qnum != ATH_TXQ_SWQ) { + ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); if (txq->axq_link == NULL) { ath_hal_puttxbuf(ah, txq->axq_qnum, bf->bf_daddr); DPRINTF(sc, ATH_DEBUG_XMIT, @@ -4034,8 +4496,20 @@ ath_tx_handoff(struct ath_softc *sc, struct ath_txq *txq, struct ath_buf *bf) txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link; ath_hal_txstart(ah, txq->axq_qnum); } else { - if (txq->axq_link != NULL) + if (txq->axq_link != NULL) { + struct ath_buf *last = ATH_TXQ_LAST(txq); + struct ieee80211_frame *wh; + + /* mark previous frame */ + wh = mtod(last->bf_m, struct ieee80211_frame *); + wh->i_fc[1] |= IEEE80211_FC1_MORE_DATA; + bus_dmamap_sync(sc->sc_dmat, last->bf_dmamap, + BUS_DMASYNC_PREWRITE); + + /* link descriptor */ *txq->axq_link = bf->bf_daddr; + } + ATH_TXQ_INSERT_TAIL(txq, bf, bf_list); txq->axq_link = &bf->bf_desc[bf->bf_nseg - 1].ds_link; } ATH_TXQ_UNLOCK(txq); @@ -4045,9 +4519,11 @@ static int ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ath_vap *avp = ATH_VAP(vap); struct ath_hal *ah = sc->sc_ah; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; int error, iswep, ismcast, isfrag, ismrr; int keyix, hdrlen, pktlen, try0; @@ -4083,7 +4559,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf * frame. The only reason this can fail is because of an * unknown or unsupported cipher/key type. */ - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { /* * This can happen when the key is yanked after the @@ -4156,6 +4632,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf an = ATH_NODE(ni); flags = HAL_TXDESC_CLRDMASK; /* XXX needed for crypto errs */ ismrr = 0; /* default no multi-rate retry*/ + pri = M_WME_GETAC(m0); /* honor classification */ /* * Calculate Atheros packet type from IEEE80211 packet header, * setup for rate calculations, and select h/w transmit queue. @@ -4171,32 +4648,20 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf atype = HAL_PKT_TYPE_ATIM; else atype = HAL_PKT_TYPE_NORMAL; /* XXX */ - rix = sc->sc_minrateix; + rix = an->an_mgmtrix; txrate = rt->info[rix].rateCode; if (shortPreamble) txrate |= rt->info[rix].shortPreamble; try0 = ATH_TXMGTTRY; - /* NB: force all management frames to highest queue */ - if (ni->ni_flags & IEEE80211_NODE_QOS) { - /* NB: force all management frames to highest queue */ - pri = WME_AC_VO; - } else - pri = WME_AC_BE; flags |= HAL_TXDESC_INTREQ; /* force interrupt */ break; case IEEE80211_FC0_TYPE_CTL: atype = HAL_PKT_TYPE_PSPOLL; /* stop setting of duration */ - rix = sc->sc_minrateix; + rix = an->an_mgmtrix; txrate = rt->info[rix].rateCode; if (shortPreamble) txrate |= rt->info[rix].shortPreamble; try0 = ATH_TXMGTTRY; - /* NB: force all ctl frames to highest queue */ - if (ni->ni_flags & IEEE80211_NODE_QOS) { - /* NB: force all ctl frames to highest queue */ - pri = WME_AC_VO; - } else - pri = WME_AC_BE; flags |= HAL_TXDESC_INTREQ; /* force interrupt */ break; case IEEE80211_FC0_TYPE_DATA: @@ -4207,16 +4672,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf * rate to use. */ if (ismcast) { - /* - * Check mcast rate setting in case it's changed. - * XXX move out of fastpath - */ - if (ic->ic_mcast_rate != sc->sc_mcastrate) { - sc->sc_mcastrix = - ath_tx_findrix(rt, ic->ic_mcast_rate); - sc->sc_mcastrate = ic->ic_mcast_rate; - } - rix = sc->sc_mcastrix; + rix = an->an_mcastrix; txrate = rt->info[rix].rateCode; if (shortPreamble) txrate |= rt->info[rix].shortPreamble; @@ -4229,7 +4685,6 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf if (try0 != ATH_TXMAXTRY) ismrr = 1; } - pri = M_WME_GETAC(m0); if (cap->cap_wmeParams[pri].wmep_noackPolicy) flags |= HAL_TXDESC_NOACK; break; @@ -4248,17 +4703,15 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf * queue (to prevent out of order delivery) multicast * frames must be buffered until after the beacon. */ - if (ismcast && (ic->ic_ps_sta || sc->sc_mcastq.axq_depth)) { - txq = &sc->sc_mcastq; - /* XXX? more bit in 802.11 frame header */ - } + if (ismcast && (vap->iv_ps_sta || avp->av_mcastq.axq_depth)) + txq = &avp->av_mcastq; /* * Calculate miscellaneous flags. */ if (ismcast) { flags |= HAL_TXDESC_NOACK; /* no ack on broad/multicast */ - } else if (pktlen > ic->ic_rtsthreshold && + } else if (pktlen > vap->iv_rtsthreshold && (ni->ni_ath_flags & IEEE80211_NODE_FF) == 0) { flags |= HAL_TXDESC_RTSENA; /* RTS based on frame length */ cix = rt->info[rix].controlRate; @@ -4386,9 +4839,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len, sc->sc_hwmap[txrate].ieeerate, -1); - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { u_int64_t tsf = ath_hal_gettsf64(ah); sc->sc_tx_th.wt_tsf = htole64(tsf); @@ -4401,8 +4852,7 @@ ath_tx_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf sc->sc_tx_th.wt_txpower = ni->ni_txpower; sc->sc_tx_th.wt_antenna = sc->sc_txantenna; - bpf_mtap2(sc->sc_drvbpf, - &sc->sc_tx_th, sc->sc_tx_th_len, m0); + bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0); } /* @@ -4465,7 +4915,8 @@ static int ath_tx_processq(struct ath_softc *sc, struct ath_txq *txq) { struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_buf *bf; struct ath_desc *ds, *ds0; struct ath_tx_status *ts; @@ -4706,10 +5157,12 @@ ath_tx_draintxq(struct ath_softc *sc, struct ath_txq *txq) ATH_TXQ_UNLOCK(txq); #ifdef ATH_DEBUG if (sc->sc_debug & ATH_DEBUG_RESET) { + struct ieee80211com *ic = sc->sc_ifp->if_l2com; + ath_printtxbuf(bf, txq->axq_qnum, ix, ath_hal_txprocdesc(ah, bf->bf_desc, &bf->bf_status.ds_txstat) == HAL_OK); - ieee80211_dump_pkt(&sc->sc_ic, mtod(bf->bf_m, caddr_t), + ieee80211_dump_pkt(ic, mtod(bf->bf_m, caddr_t), bf->bf_m->m_len, 0, -1); } #endif /* ATH_DEBUG */ @@ -4770,7 +5223,6 @@ ath_draintxq(struct ath_softc *sc) for (i = 0; i < HAL_NUM_TX_QUEUES; i++) if (ATH_TXQ_SETUP(sc, i)) ath_tx_draintxq(sc, &sc->sc_txq[i]); - ath_tx_draintxq(sc, &sc->sc_mcastq); #ifdef ATH_DEBUG if (sc->sc_debug & ATH_DEBUG_RESET) { struct ath_buf *bf = STAILQ_FIRST(&sc->sc_bbuf); @@ -4778,7 +5230,7 @@ ath_draintxq(struct ath_softc *sc) ath_printtxbuf(bf, sc->sc_bhalq, 0, ath_hal_txprocdesc(ah, bf->bf_desc, &bf->bf_status.ds_txstat) == HAL_OK); - ieee80211_dump_pkt(&sc->sc_ic, mtod(bf->bf_m, caddr_t), + ieee80211_dump_pkt(ifp->if_l2com, mtod(bf->bf_m, caddr_t), bf->bf_m->m_len, 0, -1); } } @@ -4890,42 +5342,6 @@ ath_chan_change(struct ath_softc *sc, struct ieee80211_channel *chan) } /* - * Poll for a channel clear indication; this is required - * for channels requiring DFS and not previously visited - * and/or with a recent radar detection. - */ -static void -ath_dfswait(void *arg) -{ - struct ath_softc *sc = arg; - struct ath_hal *ah = sc->sc_ah; - HAL_CHANNEL hchan; - - ath_hal_radar_wait(ah, &hchan); - DPRINTF(sc, ATH_DEBUG_DFS, "%s: radar_wait %u/%x/%x\n", - __func__, hchan.channel, hchan.channelFlags, hchan.privFlags); - - if (hchan.privFlags & CHANNEL_INTERFERENCE) { - if_printf(sc->sc_ifp, - "channel %u/0x%x/0x%x has interference\n", - hchan.channel, hchan.channelFlags, hchan.privFlags); - return; - } - if ((hchan.privFlags & CHANNEL_DFS) == 0) { - /* XXX should not happen */ - return; - } - if (hchan.privFlags & CHANNEL_DFS_CLEAR) { - sc->sc_curchan.privFlags |= CHANNEL_DFS_CLEAR; - sc->sc_ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if_printf(sc->sc_ifp, - "channel %u/0x%x/0x%x marked clear\n", - hchan.channel, hchan.channelFlags, hchan.privFlags); - } else - callout_reset(&sc->sc_dfs_ch, 2 * hz, ath_dfswait, sc); -} - -/* * Set/change channels. If the channel is really being changed, * it's done by reseting the chip. To accomplish this we must * first cleanup any pending DMA, then restart stuff after a la @@ -4934,8 +5350,9 @@ ath_dfswait(void *arg) static int ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; - struct ieee80211com *ic = &sc->sc_ic; HAL_CHANNEL hchan; /* @@ -4967,7 +5384,7 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) ath_draintxq(sc); /* clear pending tx frames */ ath_stoprecv(sc); /* turn off frame recv */ if (!ath_hal_reset(ah, sc->sc_opmode, &hchan, AH_TRUE, &status)) { - if_printf(ic->ic_ifp, "%s: unable to reset " + if_printf(ifp, "%s: unable to reset " "channel %u (%u Mhz, flags 0x%x hal flags 0x%x), " "hal status %u\n", __func__, ieee80211_chan2ieee(ic, chan), chan->ic_freq, @@ -4975,7 +5392,6 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) return EIO; } sc->sc_curchan = hchan; - ath_update_txpow(sc); /* update tx power state */ sc->sc_diversity = ath_hal_getdiversity(ah); sc->sc_calinterval = 1; sc->sc_caltries = 0; @@ -4984,8 +5400,8 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) * Re-enable rx framework. */ if (ath_startrecv(sc) != 0) { - if_printf(ic->ic_ifp, - "%s: unable to restart recv logic\n", __func__); + if_printf(ifp, "%s: unable to restart recv logic\n", + __func__); return EIO; } @@ -4996,25 +5412,6 @@ ath_chan_set(struct ath_softc *sc, struct ieee80211_channel *chan) ath_chan_change(sc, chan); /* - * Handle DFS required waiting period to determine - * if channel is clear of radar traffic. - */ - if (ic->ic_opmode == IEEE80211_M_HOSTAP) { -#define DFS_AND_NOT_CLEAR(_c) \ - (((_c)->privFlags & (CHANNEL_DFS | CHANNEL_DFS_CLEAR)) == CHANNEL_DFS) - if (DFS_AND_NOT_CLEAR(&sc->sc_curchan)) { - if_printf(sc->sc_ifp, - "wait for DFS clear channel signal\n"); - /* XXX stop sndq */ - sc->sc_ifp->if_drv_flags |= IFF_DRV_OACTIVE; - callout_reset(&sc->sc_dfs_ch, - 2 * hz, ath_dfswait, sc); - } else - callout_stop(&sc->sc_dfs_ch); -#undef DFS_NOT_CLEAR - } - - /* * Re-enable interrupts. */ ath_hal_intrset(ah, sc->sc_imask); @@ -5138,13 +5535,32 @@ ath_set_channel(struct ieee80211com *ic) sc->sc_syncbeacon = 1; } +/* + * Walk the vap list and check if there any vap's in RUN state. + */ static int -ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +ath_isanyrunningvaps(struct ieee80211vap *this) { - struct ifnet *ifp = ic->ic_ifp; - struct ath_softc *sc = ifp->if_softc; + struct ieee80211com *ic = this->iv_ic; + struct ieee80211vap *vap; + + IEEE80211_LOCK_ASSERT(ic); + + TAILQ_FOREACH(vap, &ic->ic_vaps, iv_next) { + if (vap != this && vap->iv_state == IEEE80211_S_RUN) + return 1; + } + return 0; +} + +static int +ath_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_vap *avp = ATH_VAP(vap); struct ath_hal *ah = sc->sc_ah; - struct ieee80211_node *ni; + struct ieee80211_node *ni = NULL; int i, error, stamode; u_int32_t rfilt; static const HAL_LED_STATE leds[] = { @@ -5159,75 +5575,70 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) }; DPRINTF(sc, ATH_DEBUG_STATE, "%s: %s -> %s\n", __func__, - ieee80211_state_name[ic->ic_state], + ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]); callout_stop(&sc->sc_cal_ch); - callout_stop(&sc->sc_dfs_ch); ath_hal_setledstate(ah, leds[nstate]); /* set LED */ - if (nstate == IEEE80211_S_INIT) { + if (nstate == IEEE80211_S_SCAN) { /* - * Shutdown host/driver operation: - * o disable interrupts so we don't rx frames - * o clean any pending items on the task q - * o notify the rate control algorithm + * Scanning: turn off beacon miss and don't beacon. + * Mark beacon state so when we reach RUN state we'll + * [re]setup beacons. Unblock the task q thread so + * deferred interrupt processing is done. */ + ath_hal_intrset(ah, + sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS)); sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS); - ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL); -#if 0 - /* XXX can't use taskqueue_drain 'cuz we're holding sc_mtx */ - taskqueue_drain(sc->sc_tq, &sc->sc_rxtask); - taskqueue_drain(sc->sc_tq, &sc->sc_rxorntask); - taskqueue_drain(sc->sc_tq, &sc->sc_bmisstask); - taskqueue_drain(sc->sc_tq, &sc->sc_bstucktask); -#endif - ath_rate_newstate(sc, nstate); - goto done; + sc->sc_beacons = 0; + taskqueue_unblock(sc->sc_tq); } - ni = ic->ic_bss; + ni = vap->iv_bss; rfilt = ath_calcrxfilter(sc); - stamode = (sc->sc_opmode == HAL_M_STA || sc->sc_opmode == HAL_M_IBSS); + stamode = (vap->iv_opmode == IEEE80211_M_STA || + vap->iv_opmode == IEEE80211_M_IBSS); if (stamode && nstate == IEEE80211_S_RUN) { sc->sc_curaid = ni->ni_associd; IEEE80211_ADDR_COPY(sc->sc_curbssid, ni->ni_bssid); - } else - sc->sc_curaid = 0; - + ath_hal_setassocid(ah, sc->sc_curbssid, sc->sc_curaid); + } DPRINTF(sc, ATH_DEBUG_STATE, "%s: RX filter 0x%x bssid %s aid 0x%x\n", - __func__, rfilt, ether_sprintf(sc->sc_curbssid), - sc->sc_curaid); - + __func__, rfilt, ether_sprintf(sc->sc_curbssid), sc->sc_curaid); ath_hal_setrxfilter(ah, rfilt); - if (stamode) - ath_hal_setassocid(ah, sc->sc_curbssid, ni->ni_associd); - if (ic->ic_opmode != IEEE80211_M_STA && - (ic->ic_flags & IEEE80211_F_PRIVACY)) { + /* XXX is this to restore keycache on resume? */ + if (vap->iv_opmode != IEEE80211_M_STA && + (vap->iv_flags & IEEE80211_F_PRIVACY)) { for (i = 0; i < IEEE80211_WEP_NKID; i++) if (ath_hal_keyisvalid(ah, i)) ath_hal_keysetmac(ah, i, ni->ni_bssid); } - /* * Notify the rate control algorithm so rates * are setup should ath_beacon_alloc be called. */ - ath_rate_newstate(sc, nstate); + ath_rate_newstate(vap, nstate); + + /* + * Invoke the parent method to do net80211 work. + */ + error = avp->av_newstate(vap, nstate, arg); + if (error != 0) + goto bad; if (nstate == IEEE80211_S_RUN) { + /* NB: collect bss node again, it may have changed */ + ni = vap->iv_bss; + DPRINTF(sc, ATH_DEBUG_STATE, - "%s(RUN): ic_flags=0x%08x iv=%d bssid=%s " - "capinfo=0x%04x chan=%d\n" - , __func__ - , ic->ic_flags - , ni->ni_intval - , ether_sprintf(ni->ni_bssid) - , ni->ni_capinfo - , ieee80211_chan2ieee(ic, ic->ic_curchan)); - - switch (ic->ic_opmode) { + "%s(RUN): iv_flags 0x%08x bintvl %d bssid %s " + "capinfo 0x%04x chan %d\n", __func__, + vap->iv_flags, ni->ni_intval, ether_sprintf(ni->ni_bssid), + ni->ni_capinfo, ieee80211_chan2ieee(ic, ic->ic_curchan)); + + switch (vap->iv_opmode) { case IEEE80211_M_HOSTAP: case IEEE80211_M_IBSS: /* @@ -5240,7 +5651,7 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) * be called with beacon transmission active. */ ath_hal_stoptxdma(ah, sc->sc_bhalq); - ath_beacon_free(sc); + error = ath_beacon_alloc(sc, ni); if (error != 0) goto bad; @@ -5248,22 +5659,23 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) * If joining an adhoc network defer beacon timer * configuration to the next beacon frame so we * have a current TSF to use. Otherwise we're - * starting an ibss/bss so there's no need to delay. + * starting an ibss/bss so there's no need to delay; + * if this is the first vap moving to RUN state, then + * beacon state needs to be [re]configured. */ - if (ic->ic_opmode == IEEE80211_M_IBSS && - ic->ic_bss->ni_tstamp.tsf != 0) + if (vap->iv_opmode == IEEE80211_M_IBSS && + ni->ni_tstamp.tsf != 0) { sc->sc_syncbeacon = 1; - else - ath_beacon_config(sc); + } else if (!sc->sc_beacons) { + ath_beacon_config(sc, vap); + sc->sc_beacons = 1; + } break; case IEEE80211_M_STA: /* - * Allocate a key cache slot to the station. + * Fakeup since we're not called by net80211. */ - if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0 && - sc->sc_hasclrkey && - ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE) - ath_setup_stationkey(ni); + ath_newassoc(ni, 1); /* * Defer beacon timer configuration to the next * beacon frame so we have a current TSF to use @@ -5271,6 +5683,16 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) */ sc->sc_syncbeacon = 1; break; + case IEEE80211_M_MONITOR: + /* + * Monitor mode vaps have only INIT->RUN and RUN->RUN + * transitions so we must re-enable interrupts here to + * handle the case of a single monitor mode vap. + */ + ath_hal_intrset(ah, sc->sc_imask); + break; + case IEEE80211_M_WDS: + break; default: break; } @@ -5285,23 +5707,31 @@ ath_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) sc->sc_halstats.ns_avgbrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_halstats.ns_avgrssi = ATH_RSSI_DUMMY_MARKER; sc->sc_halstats.ns_avgtxrssi = ATH_RSSI_DUMMY_MARKER; - } else { - ath_hal_intrset(ah, - sc->sc_imask &~ (HAL_INT_SWBA | HAL_INT_BMISS)); - sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS); - } -done: - /* - * Invoke the parent method to complete the work. - */ - error = sc->sc_newstate(ic, nstate, arg); - /* - * Finally, start any timers. - */ - if (nstate == IEEE80211_S_RUN) { - /* start periodic recalibration timer */ - callout_reset(&sc->sc_cal_ch, sc->sc_calinterval * hz, - ath_calibrate, sc); + /* + * Finally, start any timers and the task q thread + * (in case we didn't go through SCAN state). + */ + if (sc->sc_calinterval != 0) { + /* start periodic recalibration timer */ + callout_reset(&sc->sc_cal_ch, sc->sc_calinterval * hz, + ath_calibrate, sc); + } + taskqueue_unblock(sc->sc_tq); + } else if (nstate == IEEE80211_S_INIT) { + /* + * If there are no vaps left in RUN state then + * shutdown host/driver operation: + * o disable interrupts + * o disable the task queue thread + * o mark beacon processing as stopped + */ + if (!ath_isanyrunningvaps(vap)) { + sc->sc_imask &= ~(HAL_INT_SWBA | HAL_INT_BMISS); + /* disable interrupts */ + ath_hal_intrset(ah, sc->sc_imask &~ HAL_INT_GLOBAL); + taskqueue_block(sc->sc_tq); + sc->sc_beacons = 0; + } } bad: return error; @@ -5318,11 +5748,11 @@ bad: static void ath_setup_stationkey(struct ieee80211_node *ni) { - struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ieee80211vap *vap = ni->ni_vap; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; ieee80211_keyix keyix, rxkeyix; - if (!ath_key_alloc(ic, &ni->ni_ucastkey, &keyix, &rxkeyix)) { + if (!ath_key_alloc(vap, &ni->ni_ucastkey, &keyix, &rxkeyix)) { /* * Key cache is full; we'll fall back to doing * the more expensive lookup in software. Note @@ -5334,7 +5764,7 @@ ath_setup_stationkey(struct ieee80211_node *ni) ni->ni_ucastkey.wk_keyix = keyix; ni->ni_ucastkey.wk_rxkeyix = rxkeyix; /* NB: this will create a pass-thru key entry */ - ath_keyset(sc, &ni->ni_ucastkey, ni->ni_macaddr, ic->ic_bss); + ath_keyset(sc, &ni->ni_ucastkey, ni->ni_macaddr, vap->iv_bss); } } @@ -5346,58 +5776,78 @@ ath_setup_stationkey(struct ieee80211_node *ni) static void ath_newassoc(struct ieee80211_node *ni, int isnew) { - struct ieee80211com *ic = ni->ni_ic; - struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_node *an = ATH_NODE(ni); + struct ieee80211vap *vap = ni->ni_vap; + struct ath_softc *sc = vap->iv_ic->ic_ifp->if_softc; + const struct ieee80211_txparam *tp; + enum ieee80211_phymode mode; - ath_rate_newassoc(sc, ATH_NODE(ni), isnew); - if (isnew && - (ic->ic_flags & IEEE80211_F_PRIVACY) == 0 && sc->sc_hasclrkey) { - KASSERT(ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE, - ("new assoc with a unicast key already setup (keyix %u)", - ni->ni_ucastkey.wk_keyix)); + /* + * Deduce netband of station to simplify setting up xmit + * parameters. Note this allows us to assign different + * parameters to each station in a mixed bss (b/g, n/[abg]). + */ + if (ni->ni_flags & IEEE80211_NODE_HT) { + if (IEEE80211_IS_CHAN_5GHZ(ni->ni_chan)) + mode = IEEE80211_MODE_11NA; + else + mode = IEEE80211_MODE_11NG; + } else if (IEEE80211_IS_CHAN_A(ni->ni_chan)) + mode = IEEE80211_MODE_11A; + else if (ni->ni_flags & IEEE80211_NODE_ERP) + mode = IEEE80211_MODE_11G; + else + mode = IEEE80211_MODE_11B; + tp = &vap->iv_txparms[mode]; + an->an_tp = tp; + an->an_mcastrix = ath_tx_findrix(sc->sc_rates[mode], tp->mcastrate); + an->an_mgmtrix = ath_tx_findrix(sc->sc_rates[mode], tp->mgmtrate); + + ath_rate_newassoc(sc, an, isnew); + if (isnew && + (vap->iv_flags & IEEE80211_F_PRIVACY) == 0 && sc->sc_hasclrkey && + ni->ni_ucastkey.wk_keyix == IEEE80211_KEYIX_NONE) ath_setup_stationkey(ni); - } } static int -ath_getchannels(struct ath_softc *sc, - HAL_REG_DOMAIN rd, HAL_CTRY_CODE cc, HAL_BOOL outdoor, HAL_BOOL xchanmode) +getchannels(struct ath_softc *sc, int *nchans, struct ieee80211_channel chans[], + int cc, int ecm, int outdoor) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = sc->sc_ifp; struct ath_hal *ah = sc->sc_ah; - HAL_CHANNEL *chans; - int i, nchan; - u_int32_t regdomain; - - chans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL), - M_TEMP, M_NOWAIT); - if (chans == NULL) { - if_printf(ifp, "unable to allocate channel table\n"); + HAL_CHANNEL *halchans; + int i, nhalchans, error; + + halchans = malloc(IEEE80211_CHAN_MAX * sizeof(HAL_CHANNEL), + M_TEMP, M_NOWAIT | M_ZERO); + if (halchans == NULL) { + device_printf(sc->sc_dev, + "%s: unable to allocate channel table\n", __func__); return ENOMEM; } - if (!ath_hal_init_channels(ah, chans, IEEE80211_CHAN_MAX, &nchan, - NULL, 0, NULL, cc, HAL_MODE_ALL, outdoor, xchanmode)) { - (void) ath_hal_getregdomain(ah, ®domain); - if_printf(ifp, "unable to collect channel list from hal; " - "regdomain likely %u country code %u\n", regdomain, cc); - free(chans, M_TEMP); - return EINVAL; + error = 0; + if (!ath_hal_init_channels(ah, halchans, IEEE80211_CHAN_MAX, &nhalchans, + NULL, 0, NULL, CTRY_DEFAULT, HAL_MODE_ALL, AH_FALSE, AH_TRUE)) { + error = EINVAL; + goto done; } + if (nchans == NULL) /* no table requested */ + goto done; /* * Convert HAL channels to ieee80211 ones. */ - memset(ic->ic_channels, 0, sizeof(ic->ic_channels)); - for (i = 0; i < nchan; i++) { - HAL_CHANNEL *c = &chans[i]; - struct ieee80211_channel *ichan = &ic->ic_channels[i]; + for (i = 0; i < nhalchans; i++) { + HAL_CHANNEL *c = &halchans[i]; + struct ieee80211_channel *ichan = &chans[i]; ichan->ic_ieee = ath_hal_mhz2ieee(ah, c->channel, c->channelFlags); if (bootverbose) - if_printf(ifp, "hal channel %u/%x -> %u\n", - c->channel, c->channelFlags, ichan->ic_ieee); + device_printf(sc->sc_dev, "hal channel %u/%x -> %u " + "maxpow %d minpow %d maxreg %d\n", + c->channel, c->channelFlags, ichan->ic_ieee, + c->maxTxPower, c->minTxPower, c->maxRegTxPower); ichan->ic_freq = c->channel; if ((c->channelFlags & CHANNEL_PUREG) == CHANNEL_PUREG) { @@ -5419,15 +5869,98 @@ ath_getchannels(struct ath_softc *sc, ichan->ic_flags); } ichan->ic_maxregpower = c->maxRegTxPower; /* dBm */ - ichan->ic_maxpower = c->maxTxPower; /* 1/2 dBm */ + /* XXX: old hal's don't provide maxTxPower for some parts */ + ichan->ic_maxpower = (c->maxTxPower != 0) ? + c->maxTxPower : 2*c->maxRegTxPower; /* 1/2 dBm */ ichan->ic_minpower = c->minTxPower; /* 1/2 dBm */ } - ic->ic_nchans = nchan; - free(chans, M_TEMP); - (void) ath_hal_getregdomain(ah, &sc->sc_regdomain); - ath_hal_getcountrycode(ah, &sc->sc_countrycode); - sc->sc_xchanmode = xchanmode; - sc->sc_outdoor = outdoor; + *nchans = nhalchans; +done: + free(halchans, M_TEMP); + return error; +} + +static int +ath_setregdomain(struct ieee80211com *ic, struct ieee80211_regdomain *rd, + int nchans, struct ieee80211_channel chans[]) +{ + struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_hal *ah = sc->sc_ah; + u_int32_t ord; + int error; + + (void) ath_hal_getregdomain(ah, &ord); + /* XXX map sku->rd */ + ath_hal_setregdomain(ah, rd->regdomain); + error = getchannels(sc, &nchans, chans, rd->country, + rd->ecm ? AH_TRUE : AH_FALSE, + rd->location == 'O' ? AH_TRUE : AH_FALSE); + if (error != 0) { + /* + * Restore previous state. + */ + ath_hal_setregdomain(ah, ord); + (void) getchannels(sc, NULL, NULL, ic->ic_regdomain.country, + ic->ic_regdomain.ecm ? AH_TRUE : AH_FALSE, + ic->ic_regdomain.location == 'O' ? AH_TRUE : AH_FALSE); + return error; + } + return 0; +} + +static void +ath_getradiocaps(struct ieee80211com *ic, + int *nchans, struct ieee80211_channel chans[]) +{ + struct ath_softc *sc = ic->ic_ifp->if_softc; + struct ath_hal *ah = sc->sc_ah; + u_int32_t ord; + + (void) ath_hal_getregdomain(ah, &ord); + ath_hal_setregdomain(ah, 0); + /* XXX not quite right but close enough for now */ + getchannels(sc, nchans, chans, CTRY_DEBUG, AH_TRUE, AH_FALSE); + ath_hal_setregdomain(ah, ord); +} + +static int +ath_mapregdomain(struct ath_softc *sc, u_int32_t rd) +{ + /* map Atheros rd's to SKU's */ + return rd; +} + +static int +ath_getchannels(struct ath_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ath_hal *ah = sc->sc_ah; + u_int32_t rd, cc; + int error; + + /* + * Convert HAL channels to ieee80211 ones. + */ + error = getchannels(sc, &ic->ic_nchans, ic->ic_channels, + CTRY_DEFAULT, AH_TRUE, AH_FALSE); + (void) ath_hal_getregdomain(ah, &rd); + ath_hal_getcountrycode(ah, &cc); /* NB: cannot fail */ + if (error) { + if_printf(ifp, "%s: unable to collect channel list from hal, " + "error %d\n", __func__, error); + if (error == EINVAL) { + if_printf(ifp, "%s: regdomain likely %u country code %u\n", + __func__, rd, cc); + } + return error; + } + ic->ic_regdomain.regdomain = ath_mapregdomain(sc, rd); + ic->ic_regdomain.country = cc; + ic->ic_regdomain.ecm = 1; + ic->ic_regdomain.location = 'I'; + ic->ic_regdomain.isocc[0] = ' '; /* XXX don't know */ + ic->ic_regdomain.isocc[1] = ' '; return 0; } @@ -5488,26 +6021,6 @@ ath_led_event(struct ath_softc *sc, int event) } } -static void -ath_update_txpow(struct ath_softc *sc) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct ath_hal *ah = sc->sc_ah; - u_int32_t txpow; - - if (sc->sc_curtxpow != ic->ic_txpowlimit) { - ath_hal_settxpowlimit(ah, ic->ic_txpowlimit); - /* read back in case value is clamped */ - if (ath_hal_gettxpowlimit(ah, &txpow)) - ic->ic_txpowlimit = sc->sc_curtxpow = txpow; - } - /* - * Fetch max tx power level for status requests. - */ - if (ath_hal_getmaxtxpow(sc->sc_ah, &txpow)) - ic->ic_bss->ni_txpower = txpow; -} - static int ath_rate_setup(struct ath_softc *sc, u_int mode) { @@ -5630,14 +6143,6 @@ ath_setcurmode(struct ath_softc *sc, enum ieee80211_phymode mode) sc->sc_protrix = ath_tx_findrix(rt, 2*2); else sc->sc_protrix = ath_tx_findrix(rt, 2*1); - /* rate index used to send management frames */ - sc->sc_minrateix = 0; - /* - * Setup multicast rate state. - */ - /* XXX layering violation */ - sc->sc_mcastrix = ath_tx_findrix(rt, sc->sc_ic.ic_mcast_rate); - sc->sc_mcastrate = sc->sc_ic.ic_mcast_rate; /* NB: caller is responsible for reseting rate control state */ #undef N } @@ -5763,7 +6268,7 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) #define IS_RUNNING(ifp) \ ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) struct ath_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; struct ifreq *ifr = (struct ifreq *)data; int error = 0; @@ -5787,7 +6292,7 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * torn down much of our state. There's * probably a better way to deal with this. */ - if (!sc->sc_invalid && ic->ic_bss != NULL) + if (!sc->sc_invalid) ath_init(sc); /* XXX lose error */ } else ath_stop_locked(ifp); @@ -5802,12 +6307,18 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if (ifp->if_drv_flags & IFF_DRV_RUNNING) ath_mode_init(sc); break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; case SIOCGATHSTATS: /* NB: embed these numbers to get a consistent view */ sc->sc_stats.ast_tx_packets = ifp->if_opackets; sc->sc_stats.ast_rx_packets = ifp->if_ipackets; +#if 0 ieee80211_getsignal(ic, &sc->sc_stats.ast_rx_rssi, &sc->sc_stats.ast_rx_noise); +#endif sc->sc_stats.ast_tx_rate = sc->sc_hwmap[sc->sc_txrate].ieeerate; ATH_UNLOCK(sc); /* @@ -5826,15 +6337,7 @@ ath_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) break; #endif default: - error = ieee80211_ioctl(ic, cmd, data); - if (error == ENETRESET) { - if (IS_RUNNING(ifp) && - ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ath_init(sc); /* XXX lose error */ - error = 0; - } - if (error == ERESTART) - error = IS_RUNNING(ifp) ? ath_reset(ifp) : 0; + error = ether_ioctl(ifp, cmd, data); break; } ATH_UNLOCK(sc); @@ -6059,48 +6562,6 @@ ath_sysctl_rfsilent(SYSCTL_HANDLER_ARGS) } static int -ath_sysctl_countrycode(SYSCTL_HANDLER_ARGS) -{ - struct ath_softc *sc = arg1; - u_int32_t cc = sc->sc_countrycode; - struct ieee80211com *ic = &sc->sc_ic; - int error; - - error = sysctl_handle_int(oidp, &cc, 0, req); - if (error || !req->newptr) - return error; - error = ath_getchannels(sc, sc->sc_regdomain, cc, - sc->sc_outdoor != 0, sc->sc_xchanmode != 0); - if (error != 0) - return error; - ieee80211_media_init(ic, ath_media_change, ieee80211_media_status); - /* setcurmode? */ - return 0; -} - -static int -ath_sysctl_regdomain(SYSCTL_HANDLER_ARGS) -{ - struct ath_softc *sc = arg1; - u_int32_t rd = sc->sc_regdomain; - struct ieee80211com *ic = &sc->sc_ic; - int error; - - error = sysctl_handle_int(oidp, &rd, 0, req); - if (error || !req->newptr) - return error; - if (!ath_hal_setregdomain(sc->sc_ah, rd)) - return EINVAL; - error = ath_getchannels(sc, rd, sc->sc_countrycode, - sc->sc_outdoor != 0, sc->sc_xchanmode != 0); - if (error != 0) - return error; - ieee80211_media_init(ic, ath_media_change, ieee80211_media_status); - /* setcurmode? */ - return 0; -} - -static int ath_sysctl_tpack(SYSCTL_HANDLER_ARGS) { struct ath_softc *sc = arg1; @@ -6135,12 +6596,6 @@ ath_sysctlattach(struct ath_softc *sc) struct sysctl_oid *tree = device_get_sysctl_tree(sc->sc_dev); struct ath_hal *ah = sc->sc_ah; - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "countrycode", CTLTYPE_INT | CTLFLAG_RW, sc, 0, - ath_sysctl_countrycode, "I", "country code"); - SYSCTL_ADD_PROC(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, - "regdomain", CTLTYPE_INT | CTLFLAG_RW, sc, 0, - ath_sysctl_regdomain, "I", "EEPROM regdomain code"); #ifdef ATH_DEBUG sc->sc_debug = ath_debug; SYSCTL_ADD_INT(ctx, SYSCTL_CHILDREN(tree), OID_AUTO, @@ -6228,9 +6683,8 @@ ath_bpfattach(struct ath_softc *sc) { struct ifnet *ifp = sc->sc_ifp; - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th)); /* * Initialize constant fields. * XXX make header lengths a multiple of 32-bits so subsequent @@ -6254,12 +6708,12 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, struct ath_buf *bf, struct mbuf *m0, const struct ieee80211_bpf_params *params) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ath_hal *ah = sc->sc_ah; int error, ismcast, ismrr; int hdrlen, pktlen, try0, txantenna; u_int8_t rix, cix, txrate, ctsrate, rate1, rate2, rate3; - struct ath_txq *txq; struct ieee80211_frame *wh; u_int flags, ctsduration; HAL_PKT_TYPE atype; @@ -6340,9 +6794,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, ieee80211_dump_pkt(ic, mtod(m0, caddr_t), m0->m_len, sc->sc_hwmap[txrate].ieeerate, -1); - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { u_int64_t tsf = ath_hal_gettsf64(ah); sc->sc_tx_th.wt_tsf = htole64(tsf); @@ -6353,8 +6805,7 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, sc->sc_tx_th.wt_txpower = ni->ni_txpower; sc->sc_tx_th.wt_antenna = sc->sc_txantenna; - bpf_mtap2(sc->sc_drvbpf, - &sc->sc_tx_th, sc->sc_tx_th_len, m0); + bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0); } /* @@ -6402,16 +6853,8 @@ ath_tx_raw_start(struct ath_softc *sc, struct ieee80211_node *ni, ); } - /* - * When servicing one or more stations in power-save mode - * (or) if there is some mcast data waiting on the mcast - * queue (to prevent out of order delivery) multicast - * frames must be buffered until after the beacon. - */ - txq = sc->sc_ac2q[pri]; - if (ismcast && (ic->ic_ps_sta || sc->sc_mcastq.axq_depth)) - txq = &sc->sc_mcastq; - ath_tx_handoff(sc, txq, bf); + /* NB: no buffered multicast in power save support */ + ath_tx_handoff(sc, sc->sc_ac2q[pri], bf); return 0; } diff --git a/sys/dev/ath/if_ath_pci.c b/sys/dev/ath/if_ath_pci.c index d775966..ed35447 100644 --- a/sys/dev/ath/if_ath_pci.c +++ b/sys/dev/ath/if_ath_pci.c @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/ath/if_athioctl.h b/sys/dev/ath/if_athioctl.h index ccd7220..1c737a4 100644 --- a/sys/dev/ath/if_athioctl.h +++ b/sys/dev/ath/if_athioctl.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without diff --git a/sys/dev/ath/if_athrate.h b/sys/dev/ath/if_athrate.h index a6aaf6f..3ad287a 100644 --- a/sys/dev/ath/if_athrate.h +++ b/sys/dev/ath/if_athrate.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2004-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2004-2008 Sam Leffler, Errno Consulting * Copyright (c) 2004 Video54 Technologies, Inc. * All rights reserved. * @@ -102,7 +102,7 @@ void ath_rate_newassoc(struct ath_softc *, struct ath_node *, * Important mostly as the analog to ath_rate_newassoc when operating * in station mode. */ -void ath_rate_newstate(struct ath_softc *, enum ieee80211_state); +void ath_rate_newstate(struct ieee80211vap *, enum ieee80211_state); /* * Transmit handling. diff --git a/sys/dev/ath/if_athvar.h b/sys/dev/ath/if_athvar.h index af1045d..257c6ee 100644 --- a/sys/dev/ath/if_athvar.h +++ b/sys/dev/ath/if_athvar.h @@ -1,5 +1,5 @@ /*- - * Copyright (c) 2002-2007 Sam Leffler, Errno Consulting + * Copyright (c) 2002-2008 Sam Leffler, Errno Consulting * All rights reserved. * * Redistribution and use in source and binary forms, with or without @@ -49,6 +49,8 @@ #ifndef ATH_TXBUF #define ATH_TXBUF 200 /* number of TX buffers */ #endif +#define ATH_BCBUF 4 /* number of beacon buffers */ + #define ATH_TXDESC 10 /* number of descriptors per buffer */ #define ATH_TXMAXTRY 11 /* max number of transmit attempts */ #define ATH_TXMGTTRY 4 /* xmit attempts for mgt/ctl frames */ @@ -80,7 +82,9 @@ struct ath_buf; /* driver-specific node state */ struct ath_node { struct ieee80211_node an_node; /* base class */ - u_int32_t an_avgrssi; /* average rssi over all rx frames */ + const struct ieee80211_txparam *an_tp; + u_int8_t an_mgmtrix; /* min h/w rate index */ + u_int8_t an_mcastrix; /* mcast h/w rate index */ struct ath_buf *an_ff_buf[WME_NUM_AC]; /* ff staging area */ /* variable-length rate control state follows */ }; @@ -141,6 +145,7 @@ struct ath_descdma { */ struct ath_txq { u_int axq_qnum; /* hardware q number */ +#define ATH_TXQ_SWQ (HAL_NUM_TX_QUEUES+1) /* qnum for s/w only queue */ u_int axq_depth; /* queue depth (stat only) */ u_int axq_intrcnt; /* interrupt count */ u_int32_t *axq_link; /* link ptr in last TX desc */ @@ -175,6 +180,25 @@ struct ath_txq { STAILQ_REMOVE_HEAD(&(_tq)->axq_q, _field); \ (_tq)->axq_depth--; \ } while (0) +/* NB: this does not do the "head empty check" that STAILQ_LAST does */ +#define ATH_TXQ_LAST(_tq) \ + ((struct ath_buf *)(void *) \ + ((char *)((_tq)->axq_q.stqh_last) - __offsetof(struct ath_buf, bf_list))) + +struct ath_vap { + struct ieee80211vap av_vap; /* base class */ + int av_bslot; /* beacon slot index */ + struct ath_buf *av_bcbuf; /* beacon buffer */ + struct ieee80211_beacon_offsets av_boff;/* dynamic update state */ + struct ath_txq av_mcastq; /* buffered mcast s/w queue */ + + void (*av_recv_mgmt)(struct ieee80211_node *, + struct mbuf *, int, int, int, u_int32_t); + int (*av_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); + void (*av_bmiss)(struct ieee80211vap *); +}; +#define ATH_VAP(vap) ((struct ath_vap *)(vap)) struct taskqueue; struct ath_tx99; @@ -182,16 +206,13 @@ struct ath_tx99; struct ath_softc { struct ifnet *sc_ifp; /* interface common */ struct ath_stats sc_stats; /* interface statistics */ - struct ieee80211com sc_ic; /* IEEE 802.11 common */ int sc_debug; - u_int32_t sc_countrycode; - u_int32_t sc_regdomain; - void (*sc_recv_mgmt)(struct ieee80211com *, - struct mbuf *, - struct ieee80211_node *, - int, int, int, u_int32_t); - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); + int sc_nvaps; /* # vaps */ + int sc_nstavaps; /* # station vaps */ + u_int8_t sc_hwbssidmask[IEEE80211_ADDR_LEN]; + u_int8_t sc_nbssid0; /* # vap's using base mac */ + uint32_t sc_bssidmask; /* bssid mask */ + void (*sc_node_free)(struct ieee80211_node *); device_t sc_dev; HAL_BUS_TAG sc_st; /* bus space tag */ @@ -203,22 +224,28 @@ struct ath_softc { struct ath_ratectrl *sc_rc; /* tx rate control support */ struct ath_tx99 *sc_tx99; /* tx99 adjunct state */ void (*sc_setdefantenna)(struct ath_softc *, u_int); - unsigned int sc_invalid : 1, /* disable hardware accesses */ - sc_mrretry : 1, /* multi-rate retry support */ - sc_softled : 1, /* enable LED gpio status */ - sc_splitmic: 1, /* split TKIP MIC keys */ - sc_needmib : 1, /* enable MIB stats intr */ - sc_diversity : 1,/* enable rx diversity */ - sc_hasveol : 1, /* tx VEOL support */ - sc_ledstate: 1, /* LED on/off state */ - sc_blinking: 1, /* LED blink operation active */ - sc_mcastkey: 1, /* mcast key cache search */ - sc_scanning: 1, /* scanning active */ + unsigned int sc_invalid : 1,/* disable hardware accesses */ + sc_mrretry : 1,/* multi-rate retry support */ + sc_softled : 1,/* enable LED gpio status */ + sc_splitmic : 1,/* split TKIP MIC keys */ + sc_needmib : 1,/* enable MIB stats intr */ + sc_diversity: 1,/* enable rx diversity */ + sc_hasveol : 1,/* tx VEOL support */ + sc_ledstate : 1,/* LED on/off state */ + sc_blinking : 1,/* LED blink operation active */ + sc_mcastkey : 1,/* mcast key cache search */ + sc_scanning : 1,/* scanning active */ sc_syncbeacon:1,/* sync/resync beacon timers */ - sc_hasclrkey:1, /* CLR key supported */ + sc_hasclrkey: 1,/* CLR key supported */ sc_xchanmode: 1,/* extended channel mode */ sc_outdoor : 1,/* outdoor operation */ - sc_dturbo : 1; /* dynamic turbo in use */ + sc_dturbo : 1,/* dynamic turbo in use */ + sc_hasbmask : 1,/* bssid mask support */ + sc_hastsfadd: 1,/* tsf adjust support */ + sc_beacons : 1,/* beacons running */ + sc_swbmiss : 1,/* sta mode using sw bmiss */ + sc_stagbeacons:1,/* use staggered beacons */ + sc_wmetkipmic:1;/* can do WME+TKIP MIC */ /* rate tables */ #define IEEE80211_MODE_HALF (IEEE80211_MODE_MAX+0) #define IEEE80211_MODE_QUARTER (IEEE80211_MODE_MAX+1) @@ -238,8 +265,6 @@ struct ath_softc { u_int16_t ledon; /* softled on time */ u_int16_t ledoff; /* softled off time */ } sc_hwmap[32]; /* h/w rate ix mappings */ - u_int8_t sc_minrateix; /* min h/w rate index */ - u_int8_t sc_mcastrix; /* mcast h/w rate index */ u_int8_t sc_protrix; /* protection rate index */ u_int8_t sc_lastdatarix; /* last data frame rate index */ u_int sc_mcastrate; /* ieee rate for mcastrateix */ @@ -262,20 +287,13 @@ struct ath_softc { u_int sc_rfsilentpin; /* GPIO pin for rfkill int */ u_int sc_rfsilentpol; /* pin setting for rfkill on */ - struct bpf_if *sc_drvbpf; - union { - struct ath_tx_radiotap_header th; - u_int8_t pad[64]; - } u_tx_rt; + struct ath_tx_radiotap_header sc_tx_th; int sc_tx_th_len; - union { - struct ath_rx_radiotap_header th; - u_int8_t pad[64]; - } u_rx_rt; + struct ath_rx_radiotap_header sc_rx_th; int sc_rx_th_len; u_int sc_monpass; /* frames to pass in mon.mode */ - struct ath_descdma sc_rxdma; /* RX descriptos */ + struct ath_descdma sc_rxdma; /* RX descriptors */ ath_bufhead sc_rxbuf; /* receive buffer */ struct mbuf *sc_rxpending; /* pending receive data */ u_int32_t *sc_rxlink; /* link ptr in last RX desc */ @@ -301,7 +319,6 @@ struct ath_softc { u_int sc_bmisscount; /* missed beacon transmits */ u_int32_t sc_ant_tx[8]; /* recent tx frames/antenna */ struct ath_txq *sc_cabq; /* tx q for cab frames */ - struct ieee80211_beacon_offsets sc_boff;/* dynamic update state */ struct task sc_bmisstask; /* bmiss int processing */ struct task sc_bstucktask; /* stuck beacon processing */ enum { @@ -309,16 +326,15 @@ struct ath_softc { UPDATE, /* update pending */ COMMIT /* beacon sent, commit change */ } sc_updateslot; /* slot time update fsm */ - struct ath_txq sc_mcastq; /* mcast xmits w/ ps sta's */ + int sc_slotupdate; /* slot to advance fsm */ + struct ieee80211vap *sc_bslot[ATH_BCBUF]; + int sc_nbcnvaps; /* # vaps with beacons */ struct callout sc_cal_ch; /* callout handle for cals */ int sc_calinterval; /* current polling interval */ int sc_caltries; /* cals at current interval */ HAL_NODE_STATS sc_halstats; /* station-mode rssi stats */ - struct callout sc_dfs_ch; /* callout handle for dfs */ }; -#define sc_tx_th u_tx_rt.th -#define sc_rx_th u_rx_rt.th #define ATH_LOCK_INIT(_sc) \ mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ @@ -361,6 +377,10 @@ void ath_intr(void *); ((*(_ah)->ah_getMacAddress)((_ah), (_mac))) #define ath_hal_setmac(_ah, _mac) \ ((*(_ah)->ah_setMacAddress)((_ah), (_mac))) +#define ath_hal_getbssidmask(_ah, _mask) \ + ((*(_ah)->ah_getBssIdMask)((_ah), (_mask))) +#define ath_hal_setbssidmask(_ah, _mask) \ + ((*(_ah)->ah_setBssIdMask)((_ah), (_mask))) #define ath_hal_intrset(_ah, _mask) \ ((*(_ah)->ah_setInterrupts)((_ah), (_mask))) #define ath_hal_intrget(_ah) \ @@ -483,15 +503,21 @@ void ath_intr(void *); #define ath_hal_getregdomain(_ah, _prd) \ (ath_hal_getcapability(_ah, HAL_CAP_REG_DMN, 0, (_prd)) == HAL_OK) #define ath_hal_setregdomain(_ah, _rd) \ - ((*(_ah)->ah_setRegulatoryDomain)((_ah), (_rd), NULL)) + (*(uint16_t *)(((uint8_t *)(_ah)) + 520) = (_rd)) #define ath_hal_getcountrycode(_ah, _pcc) \ (*(_pcc) = (_ah)->ah_countryCode) +#define ath_hal_gettkipmic(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_TKIP_MIC, 1, NULL) == HAL_OK) +#define ath_hal_settkipmic(_ah, _v) \ + ath_hal_setcapability(_ah, HAL_CAP_TKIP_MIC, 1, _v, NULL) #define ath_hal_hastkipsplit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 0, NULL) == HAL_OK) #define ath_hal_gettkipsplit(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, NULL) == HAL_OK) #define ath_hal_settkipsplit(_ah, _v) \ ath_hal_setcapability(_ah, HAL_CAP_TKIP_SPLIT, 1, _v, NULL) +#define ath_hal_haswmetkipmic(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_WME_TKIPMIC, 0, NULL) == HAL_OK) #define ath_hal_hwphycounters(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_PHYCOUNTERS, 0, NULL) == HAL_OK) #define ath_hal_hasdiversity(_ah) \ @@ -542,6 +568,14 @@ void ath_intr(void *); #endif #define ath_hal_hasfastframes(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_FASTFRAME, 0, NULL) == HAL_OK) +#define ath_hal_hasbssidmask(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_BSSIDMASK, 0, NULL) == HAL_OK) +#define ath_hal_hastsfadjust(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_TSF_ADJUST, 0, NULL) == HAL_OK) +#define ath_hal_gettsfadjust(_ah) \ + (ath_hal_getcapability(_ah, HAL_CAP_TSF_ADJUST, 1, NULL) == HAL_OK) +#define ath_hal_settsfadjust(_ah, _onoff) \ + ath_hal_setcapability(_ah, HAL_CAP_TSF_ADJUST, 1, _onoff, NULL) #define ath_hal_hasrfsilent(_ah) \ (ath_hal_getcapability(_ah, HAL_CAP_RFSILENT, 0, NULL) == HAL_OK) #define ath_hal_getrfkill(_ah) \ diff --git a/sys/dev/if_ndis/if_ndis.c b/sys/dev/if_ndis/if_ndis.c index c44ed53..896ddb3 100644 --- a/sys/dev/if_ndis/if_ndis.c +++ b/sys/dev/if_ndis/if_ndis.c @@ -133,16 +133,21 @@ static funcptr ndis_starttask_wrap; static funcptr ndis_resettask_wrap; static funcptr ndis_inputtask_wrap; +static struct ieee80211vap *ndis_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void ndis_vap_delete (struct ieee80211vap *); static void ndis_tick (void *); static void ndis_ticktask (device_object *, void *); +static int ndis_raw_xmit (struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); static void ndis_start (struct ifnet *); static void ndis_starttask (device_object *, void *); static void ndis_resettask (device_object *, void *); static void ndis_inputtask (device_object *, void *); static int ndis_ioctl (struct ifnet *, u_long, caddr_t); -static int ndis_80211_ioctl_get (struct ifnet *, u_long, caddr_t); -static int ndis_80211_ioctl_set (struct ifnet *, u_long, caddr_t); -static int ndis_newstate (struct ieee80211com *, enum ieee80211_state, +static int ndis_newstate (struct ieee80211vap *, enum ieee80211_state, int); static int ndis_nettype_chan (uint32_t); static int ndis_nettype_mode (uint32_t); @@ -151,8 +156,8 @@ static void ndis_scan_results (struct ndis_softc *); static void ndis_scan_start (struct ieee80211com *); static void ndis_scan_end (struct ieee80211com *); static void ndis_set_channel (struct ieee80211com *); -static void ndis_scan_curchan (struct ieee80211com *, unsigned long); -static void ndis_scan_mindwell (struct ieee80211com *); +static void ndis_scan_curchan (struct ieee80211_scan_state *, unsigned long); +static void ndis_scan_mindwell (struct ieee80211_scan_state *); static void ndis_init (void *); static void ndis_stop (struct ndis_softc *); static void ndis_watchdog (struct ifnet *); @@ -164,12 +169,11 @@ static int ndis_set_offload (struct ndis_softc *); static void ndis_getstate_80211 (struct ndis_softc *); static void ndis_setstate_80211 (struct ndis_softc *); static int ndis_set_cipher (struct ndis_softc *, int); -static int ndis_set_wpa (struct ndis_softc *); -static int ndis_add_key (struct ieee80211com *, +static int ndis_set_wpa (struct ndis_softc *, void *, int); +static int ndis_add_key (struct ieee80211vap *, const struct ieee80211_key *, const u_int8_t []); -static int ndis_del_key (struct ieee80211com *, +static int ndis_del_key (struct ieee80211vap *, const struct ieee80211_key *); -static void ndis_media_status (struct ifnet *, struct ifmediareq *); static void ndis_setmulti (struct ndis_softc *); static void ndis_map_sclist (void *, bus_dma_segment_t *, @@ -520,16 +524,11 @@ ndis_attach(dev) driver_object *pdrv; device_object *pdo; struct ifnet *ifp = NULL; - int error = 0, len, mode, bands = 0; + int error = 0, len, mode; + uint8_t bands = 0; int i; sc = device_get_softc(dev); - ifp = sc->ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - error = ENOSPC; - goto fail; - } - ifp->if_softc = sc; KeInitializeSpinLock(&sc->ndis_spinlock); KeInitializeSpinLock(&sc->ndis_rxlock); @@ -598,10 +597,6 @@ ndis_attach(dev) sc->ndis_inputitem = IoAllocateWorkItem(sc->ndis_block->nmb_deviceobj); KeInitializeDpc(&sc->ndis_rxdpc, ndis_rxeof_xfr_wrap, sc->ndis_block); - /* make sure drv flags are all cleared before initing the NIC. */ - - ifp->if_drv_flags = 0; - /* Call driver's init routine. */ if (ndis_init_nic(sc)) { device_printf (dev, "init handler failed\n"); @@ -677,6 +672,17 @@ ndis_attach(dev) } } + if (sc->ndis_80211) + ifp = if_alloc(IFT_IEEE80211); + else + ifp = if_alloc(IFT_ETHER); + if (ifp == NULL) { + error = ENOSPC; + goto fail; + } + sc->ifp = ifp; + ifp->if_softc = sc; + /* Check for task offload support. */ ndis_probe_offload(sc); @@ -696,7 +702,7 @@ ndis_attach(dev) /* Do media setup */ if (sc->ndis_80211) { - struct ieee80211com *ic = (void *)&sc->ic; + struct ieee80211com *ic = ifp->if_l2com; ndis_80211_rates_ex rates; struct ndis_80211_nettype_list *ntl; uint32_t arg; @@ -709,8 +715,8 @@ ndis_attach(dev) TASK_INIT(&sc->ndis_scantask, 0, ndis_scan, sc); ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_DS; ic->ic_opmode = IEEE80211_M_STA; + ic->ic_phytype = IEEE80211_T_DS; ic->ic_caps = IEEE80211_C_IBSS; setbit(ic->ic_modecaps, IEEE80211_MODE_AUTO); len = 0; @@ -840,7 +846,7 @@ nonettypes: } #undef SETRATE #undef INCRATE - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); /* * To test for WPA support, we need to see if we can @@ -869,20 +875,22 @@ nonettypes: arg = NDIS_80211_WEPSTAT_ENC3ENABLED; r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); if (r == 0) { - ic->ic_caps |= IEEE80211_C_WEP|IEEE80211_C_TKIP| - IEEE80211_C_AES_CCM; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP + | IEEE80211_CRYPTO_TKIP + | IEEE80211_CRYPTO_AES_CCM; goto got_crypto; } arg = NDIS_80211_WEPSTAT_ENC2ENABLED; r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); if (r == 0) { - ic->ic_caps |= IEEE80211_C_WEP|IEEE80211_C_TKIP; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP + | IEEE80211_CRYPTO_TKIP; goto got_crypto; } arg = NDIS_80211_WEPSTAT_ENC1ENABLED; r = ndis_set_info(sc, OID_802_11_ENCRYPTION_STATUS, &arg, &i); if (r == 0) - ic->ic_caps |= IEEE80211_C_WEP; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP; got_crypto: i = sizeof(arg); r = ndis_get_info(sc, OID_802_11_POWER_MODE, &arg, &i); @@ -890,21 +898,17 @@ got_crypto: ic->ic_caps |= IEEE80211_C_PMGT; bcopy(eaddr, &ic->ic_myaddr, sizeof(eaddr)); ieee80211_ifattach(ic); - ieee80211_media_init(ic, ieee80211_media_change, - ndis_media_status); + ic->ic_raw_xmit = ndis_raw_xmit; ic->ic_scan_start = ndis_scan_start; ic->ic_scan_end = ndis_scan_end; ic->ic_set_channel = ndis_set_channel; ic->ic_scan_curchan = ndis_scan_curchan; ic->ic_scan_mindwell = ndis_scan_mindwell; ic->ic_bsschan = IEEE80211_CHAN_ANYC; - ic->ic_bss->ni_chan = ic->ic_bsschan; - /* override state transition machine */ - sc->ndis_newstate = ic->ic_newstate; - ic->ic_newstate = ndis_newstate; - /* install key handing routines */ - ic->ic_crypto.cs_key_set = ndis_add_key; - ic->ic_crypto.cs_key_delete = ndis_del_key; + //ic->ic_bss->ni_chan = ic->ic_bsschan; + ic->ic_vap_create = ndis_vap_create; + ic->ic_vap_delete = ndis_vap_delete; + } else { ifmedia_init(&sc->ifmedia, IFM_IMASK, ndis_ifmedia_upd, ndis_ifmedia_sts); @@ -928,6 +932,45 @@ fail: return(error); } +static struct ieee80211vap * +ndis_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ndis_vap *nvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + nvp = (struct ndis_vap *) malloc(sizeof(struct ndis_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (nvp == NULL) + return NULL; + vap = &nvp->vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + /* override with driver methods */ + nvp->newstate = vap->iv_newstate; + vap->iv_newstate = ndis_newstate; + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + /* install key handing routines */ + vap->iv_key_set = ndis_add_key; + vap->iv_key_delete = ndis_del_key; + return vap; +} + +static void +ndis_vap_delete(struct ieee80211vap *vap) +{ + struct ndis_vap *nvp = NDIS_VAP(vap); + + ieee80211_vap_detach(vap); + free(nvp, M_80211_VAP); +} + /* * Shutdown hardware and free up resources. This can be called any * time after the mutex has been initialized. It is called in both @@ -952,7 +995,7 @@ ndis_detach(dev) NDIS_UNLOCK(sc); ndis_stop(sc); if (sc->ndis_80211) - ieee80211_ifdetach(&sc->ic); + ieee80211_ifdetach(ifp->if_l2com); else ether_ifdetach(ifp); } else @@ -1422,10 +1465,14 @@ ndis_inputtask(dobj, arg) struct ifnet *ifp; struct ndis_softc *sc; struct mbuf *m; + struct ieee80211com *ic; + struct ieee80211vap *vap; uint8_t irql; ifp = arg; sc = ifp->if_softc; + ic = ifp->if_l2com; + vap = TAILQ_FIRST(&ic->ic_vaps); block = dobj->do_devext; KeAcquireSpinLock(&sc->ndis_rxlock, &irql); @@ -1434,8 +1481,10 @@ ndis_inputtask(dobj, arg) if (m == NULL) break; KeReleaseSpinLock(&sc->ndis_rxlock, irql); - ifp->if_ipackets++; - (*ifp->if_input)(ifp, m); + if (sc->ndis_80211) + vap->iv_deliver_data(vap, vap->iv_bss, m); + else + (*ifp->if_input)(ifp, m); KeAcquireSpinLock(&sc->ndis_rxlock, &irql); } KeReleaseSpinLock(&sc->ndis_rxlock, irql); @@ -1600,11 +1649,13 @@ ndis_ticktask(d, xsc) { struct ndis_softc *sc; struct ieee80211com *ic; + struct ieee80211vap *vap; ndis_checkforhang_handler hangfunc; uint8_t rval; sc = xsc; - ic = &sc->ic; + ic = sc->ifp->if_l2com; + vap = TAILQ_FIRST(&ic->ic_vaps); NDIS_LOCK(sc); if (!NDIS_INITIALIZED(sc)) { @@ -1631,7 +1682,7 @@ ndis_ticktask(d, xsc) NDIS_UNLOCK(sc); if (sc->ndis_80211) { ndis_getstate_80211(sc); - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + ieee80211_new_state(vap, IEEE80211_S_RUN, -1); } NDIS_LOCK(sc); if_link_state_change(sc->ifp, LINK_STATE_UP); @@ -1641,7 +1692,7 @@ ndis_ticktask(d, xsc) sc->ndis_sts == NDIS_STATUS_MEDIA_DISCONNECT) { sc->ndis_link = 0; if (sc->ndis_80211) - ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); + ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); if_link_state_change(sc->ifp, LINK_STATE_DOWN); } @@ -1677,6 +1728,16 @@ ndis_map_sclist(arg, segs, nseg, mapsize, error) return; } +static int +ndis_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + /* no support; just discard */ + m_freem(m); + ieee80211_free_node(ni); + return 0; +} + static void ndis_starttask(d, arg) device_object *d; @@ -1791,7 +1852,8 @@ ndis_start(ifp) * to him. */ - BPF_MTAP(ifp, m); + if (!sc->ndis_80211) /* XXX handle 80211 */ + BPF_MTAP(ifp, m); /* * The array that p0 points to must appear contiguous, @@ -1840,8 +1902,8 @@ ndis_init(xsc) void *xsc; { struct ndis_softc *sc = xsc; - struct ieee80211com *ic = (void *)&sc->ic; struct ifnet *ifp = sc->ifp; + struct ieee80211com *ic = ifp->if_l2com; int i, len, error; /* @@ -1850,7 +1912,7 @@ ndis_init(xsc) * fixing the upper layer modules so they don't * call ifp->if_init() quite as often. */ - if (sc->ndis_link && sc->ndis_skip) + if (sc->ndis_link) return; /* @@ -1908,23 +1970,14 @@ ndis_init(xsc) if_link_state_change(sc->ifp, LINK_STATE_UNKNOWN); - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - /* - * NB: When restarting the adapter clock the state - * machine regardless of the roaming mode; otherwise - * we need to notify user apps so they can manually - * get us going again. - */ - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; NDIS_UNLOCK(sc); + /* XXX force handling */ + ieee80211_start_all(ic); /* start all vap's */ + /* * Some drivers don't set this value. The NDIS spec says * the default checkforhang timeout is "approximately 2 @@ -2017,24 +2070,24 @@ ndis_set_cipher(sc, cipher) int rval = 0, len; uint32_t arg, save; - ic = &sc->ic; + ic = sc->ifp->if_l2com; len = sizeof(arg); if (cipher == WPA_CSE_WEP40 || WPA_CSE_WEP104) { - if (!(ic->ic_caps & IEEE80211_C_WEP)) + if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP)) return(ENOTSUP); arg = NDIS_80211_WEPSTAT_ENC1ENABLED; } if (cipher == WPA_CSE_TKIP) { - if (!(ic->ic_caps & IEEE80211_C_TKIP)) + if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_TKIP)) return(ENOTSUP); arg = NDIS_80211_WEPSTAT_ENC2ENABLED; } if (cipher == WPA_CSE_CCMP) { - if (!(ic->ic_caps & IEEE80211_C_AES_CCM)) + if (!(ic->ic_cryptocaps & IEEE80211_CRYPTO_AES_CCM)) return(ENOTSUP); arg = NDIS_80211_WEPSTAT_ENC3ENABLED; } @@ -2067,18 +2120,17 @@ ndis_set_cipher(sc, cipher) */ static int -ndis_set_wpa(sc) +ndis_set_wpa(sc, ie, ielen) struct ndis_softc *sc; + void *ie; + int ielen; { - struct ieee80211com *ic; struct ieee80211_ie_wpa *w; struct ndis_ie *n; char *pos; uint32_t arg; int i; - ic = &sc->ic; - /* * Apparently, the only way for us to know what ciphers * and key management/authentication mode to use is for @@ -2087,7 +2139,7 @@ ndis_set_wpa(sc) * supplied by the WPA supplicant. */ - w = (struct ieee80211_ie_wpa *)ic->ic_opt_ie; + w = (struct ieee80211_ie_wpa *)ie; /* Check for the right kind of IE. */ if (w->wpa_id != IEEE80211_ELEMID_VENDOR) { @@ -2150,18 +2202,20 @@ ndis_setstate_80211(sc) struct ndis_softc *sc; { struct ieee80211com *ic; + struct ieee80211vap *vap; struct ieee80211_node *ni; ndis_80211_ssid ssid; ndis_80211_macaddr bssid; ndis_80211_config config; ndis_80211_wep wep; - int i, rval = 0, len; + int i, rval = 0, len, error; uint32_t arg; struct ifnet *ifp; - ic = &sc->ic; ifp = sc->ifp; - ni = ic->ic_bss; + ic = ifp->if_l2com; + vap = TAILQ_FIRST(&ic->ic_vaps); + ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: NDIS not initialized\n", __func__)); @@ -2177,7 +2231,7 @@ ndis_setstate_80211(sc) /* Set network infrastructure mode. */ len = sizeof(arg); - if (ic->ic_opmode == IEEE80211_M_IBSS) + if (vap->iv_opmode == IEEE80211_M_IBSS) arg = NDIS_80211_NET_INFRA_IBSS; else arg = NDIS_80211_NET_INFRA_BSS; @@ -2190,13 +2244,13 @@ ndis_setstate_80211(sc) /* Set RTS threshold */ len = sizeof(arg); - arg = ic->ic_rtsthreshold; + arg = vap->iv_rtsthreshold; ndis_set_info(sc, OID_802_11_RTS_THRESHOLD, &arg, &len); /* Set fragmentation threshold */ len = sizeof(arg); - arg = ic->ic_fragthreshold; + arg = vap->iv_fragthreshold; ndis_set_info(sc, OID_802_11_FRAGMENTATION_THRESHOLD, &arg, &len); /* Set power management */ @@ -2231,11 +2285,11 @@ ndis_setstate_80211(sc) /* Set WEP */ - if (ic->ic_flags & IEEE80211_F_PRIVACY && - !(ic->ic_flags & IEEE80211_F_WPA)) { + if (vap->iv_flags & IEEE80211_F_PRIVACY && + !(vap->iv_flags & IEEE80211_F_WPA)) { int keys_set = 0; - if (ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED) { + if (ni->ni_authmode == IEEE80211_AUTH_SHARED) { len = sizeof(arg); arg = NDIS_80211_AUTHMODE_SHARED; DPRINTF(("Setting shared auth\n")); @@ -2243,12 +2297,12 @@ ndis_setstate_80211(sc) &arg, &len); } for (i = 0; i < IEEE80211_WEP_NKID; i++) { - if (ic->ic_nw_keys[i].wk_keylen) { - if (ic->ic_nw_keys[i].wk_cipher->ic_cipher != + if (vap->iv_nw_keys[i].wk_keylen) { + if (vap->iv_nw_keys[i].wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) continue; bzero((char *)&wep, sizeof(wep)); - wep.nw_keylen = ic->ic_nw_keys[i].wk_keylen; + wep.nw_keylen = vap->iv_nw_keys[i].wk_keylen; /* * 5, 13 and 16 are the only valid @@ -2256,21 +2310,21 @@ ndis_setstate_80211(sc) * in between will be zero padded out to * the next highest boundary. */ - if (ic->ic_nw_keys[i].wk_keylen < 5) + if (vap->iv_nw_keys[i].wk_keylen < 5) wep.nw_keylen = 5; - else if (ic->ic_nw_keys[i].wk_keylen > 5 && - ic->ic_nw_keys[i].wk_keylen < 13) + else if (vap->iv_nw_keys[i].wk_keylen > 5 && + vap->iv_nw_keys[i].wk_keylen < 13) wep.nw_keylen = 13; - else if (ic->ic_nw_keys[i].wk_keylen > 13 && - ic->ic_nw_keys[i].wk_keylen < 16) + else if (vap->iv_nw_keys[i].wk_keylen > 13 && + vap->iv_nw_keys[i].wk_keylen < 16) wep.nw_keylen = 16; wep.nw_keyidx = i; wep.nw_length = (sizeof(uint32_t) * 3) + wep.nw_keylen; - if (i == ic->ic_def_txkey) + if (i == vap->iv_def_txkey) wep.nw_keyidx |= NDIS_80211_WEPKEY_TX; - bcopy(ic->ic_nw_keys[i].wk_key, + bcopy(vap->iv_nw_keys[i].wk_key, wep.nw_keydata, wep.nw_length); len = sizeof(wep); DPRINTF(("Setting WEP key %d\n", i)); @@ -2291,7 +2345,7 @@ ndis_setstate_80211(sc) if (rval) device_printf(sc->ndis_dev, "enable WEP failed: %d\n", rval); - if (ic->ic_flags & IEEE80211_F_DROPUNENC) + if (vap->iv_flags & IEEE80211_F_DROPUNENC) arg = NDIS_80211_PRIVFILT_8021XWEP; else arg = NDIS_80211_PRIVFILT_ACCEPTALL; @@ -2300,20 +2354,23 @@ ndis_setstate_80211(sc) ndis_set_info(sc, OID_802_11_PRIVACY_FILTER, &arg, &len); } - } + } /* Set up WPA. */ - if (ic->ic_flags & IEEE80211_F_WPA1 && ic->ic_opt_ie_len && - ic->ic_caps & IEEE80211_C_WPA) - if (ndis_set_wpa(sc)) + if ((vap->iv_flags & IEEE80211_F_WPA) && + vap->iv_appie_assocreq != NULL) { + struct ieee80211_appie *ie = vap->iv_appie_assocreq; + error = ndis_set_wpa(sc, ie->ie_data, ie->ie_len); + if (error != 0) device_printf(sc->ndis_dev, "WPA setup failed\n"); + } #ifdef notyet /* Set network type. */ arg = 0; - switch (ic->ic_curmode) { + switch (vap->iv_curmode) { case IEEE80211_MODE_11A: arg = NDIS_80211_NETTYPE_11OFDM5; break; @@ -2325,7 +2382,7 @@ ndis_setstate_80211(sc) break; default: device_printf(sc->ndis_dev, "unknown mode: %d\n", - ic->ic_curmode); + vap->iv_curmode); } if (arg) { @@ -2365,7 +2422,7 @@ ndis_setstate_80211(sc) if (chan != ieee80211_mhz2ieee(config.nc_dsconfig / 1000, 0)) { config.nc_dsconfig = ic->ic_bsschan->ic_freq * 1000; - ic->ic_bss->ni_chan = ic->ic_bsschan; + ni->ni_chan = ic->ic_bsschan; len = sizeof(config); config.nc_length = len; config.nc_fhconfig.ncf_length = @@ -2397,8 +2454,8 @@ ndis_setstate_80211(sc) */ len = IEEE80211_ADDR_LEN; - if (ic->ic_flags & IEEE80211_F_DESBSSID && - ic->ic_opmode != IEEE80211_M_IBSS) + if (vap->iv_flags & IEEE80211_F_DESBSSID && + vap->iv_opmode != IEEE80211_M_IBSS) bcopy(ni->ni_bssid, bssid, len); else bcopy(ifp->if_broadcastaddr, bssid, len); @@ -2432,67 +2489,12 @@ ndis_setstate_80211(sc) if (rval) device_printf (sc->ndis_dev, "set ssid failed: %d\n", rval); - if (ic->ic_state == IEEE80211_S_AUTH) - ieee80211_new_state(ic, IEEE80211_S_ASSOC, 0); + if (vap->iv_state == IEEE80211_S_AUTH) + ieee80211_new_state(vap, IEEE80211_S_ASSOC, 0); return; } -static void -ndis_media_status(struct ifnet *ifp, struct ifmediareq *imr) -{ - struct ieee80211com *ic = &((struct ndis_softc *)ifp->if_softc)->ic; - struct ieee80211_node *ni = NULL; - - imr->ifm_status = IFM_AVALID; - imr->ifm_active = IFM_IEEE80211; - if (ic->ic_state == IEEE80211_S_RUN) - imr->ifm_status |= IFM_ACTIVE; - imr->ifm_active |= IFM_AUTO; - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - ni = ic->ic_bss; - /* calculate rate subtype */ - imr->ifm_active |= ieee80211_rate2media(ic, - ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode); - break; - case IEEE80211_M_IBSS: - ni = ic->ic_bss; - /* calculate rate subtype */ - imr->ifm_active |= ieee80211_rate2media(ic, - ni->ni_rates.rs_rates[ni->ni_txrate], ic->ic_curmode); - imr->ifm_active |= IFM_IEEE80211_ADHOC; - break; - case IEEE80211_M_AHDEMO: - /* should not come here */ - break; - case IEEE80211_M_HOSTAP: - imr->ifm_active |= IFM_IEEE80211_HOSTAP; - break; - case IEEE80211_M_MONITOR: - imr->ifm_active |= IFM_IEEE80211_MONITOR; - break; - case IEEE80211_M_WDS: - printf("WARNING: WDS operation mode not supported by NDIS\n"); - break; - } - switch (ic->ic_curmode) { - case IEEE80211_MODE_11A: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A); - break; - case IEEE80211_MODE_11B: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11B); - break; - case IEEE80211_MODE_11G: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11G); - break; - case IEEE80211_MODE_TURBO_A: - imr->ifm_active |= IFM_MAKEMODE(IFM_IEEE80211_11A) - | IFM_IEEE80211_TURBO; - break; - } -} - static int ndis_get_assoc(sc, assoc) struct ndis_softc *sc; @@ -2557,14 +2559,18 @@ ndis_getstate_80211(sc) struct ndis_softc *sc; { struct ieee80211com *ic; + struct ieee80211vap *vap; + struct ieee80211_node *ni; ndis_wlan_bssid_ex *bs; int rval, len, i = 0; int chanflag; uint32_t arg; struct ifnet *ifp; - ic = &sc->ic; ifp = sc->ifp; + ic = ifp->if_l2com; + vap = TAILQ_FIRST(&ic->ic_vaps); + ni = vap->iv_bss; if (!NDIS_INITIALIZED(sc)) return; @@ -2575,12 +2581,12 @@ ndis_getstate_80211(sc) /* We're associated, retrieve info on the current bssid. */ ic->ic_curmode = ndis_nettype_mode(bs->nwbx_nettype); chanflag = ndis_nettype_chan(bs->nwbx_nettype); - IEEE80211_ADDR_COPY(ic->ic_bss->ni_bssid, bs->nwbx_macaddr); + IEEE80211_ADDR_COPY(ni->ni_bssid, bs->nwbx_macaddr); /* Get SSID from current association info. */ - bcopy(bs->nwbx_ssid.ns_ssid, ic->ic_bss->ni_essid, + bcopy(bs->nwbx_ssid.ns_ssid, ni->ni_essid, bs->nwbx_ssid.ns_ssidlen); - ic->ic_bss->ni_esslen = bs->nwbx_ssid.ns_ssidlen; + ni->ni_esslen = bs->nwbx_ssid.ns_ssidlen; len = sizeof(arg); rval = ndis_get_info(sc, OID_GEN_LINK_SPEED, &arg, &len); @@ -2589,29 +2595,29 @@ ndis_getstate_80211(sc) rval); if (isset(ic->ic_modecaps, IEEE80211_MODE_11B)) { - ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B]; - for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) { - if ((ic->ic_bss->ni_rates.rs_rates[i] & + ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11B]; + for (i = 0; i < ni->ni_rates.rs_nrates; i++) { + if ((ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) == arg / 5000) break; } } - if (i == ic->ic_bss->ni_rates.rs_nrates && + if (i == ni->ni_rates.rs_nrates && isset(ic->ic_modecaps, IEEE80211_MODE_11G)) { - ic->ic_bss->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G]; - for (i = 0; i < ic->ic_bss->ni_rates.rs_nrates; i++) { - if ((ic->ic_bss->ni_rates.rs_rates[i] & + ni->ni_rates = ic->ic_sup_rates[IEEE80211_MODE_11G]; + for (i = 0; i < ni->ni_rates.rs_nrates; i++) { + if ((ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) == arg / 5000) break; } } - if (i == ic->ic_bss->ni_rates.rs_nrates) + if (i == ni->ni_rates.rs_nrates) device_printf(sc->ndis_dev, "no matching rate for: %d\n", arg / 5000); else - ic->ic_bss->ni_txrate = i; + ni->ni_txrate = i; if (ic->ic_caps & IEEE80211_C_PMGT) { len = sizeof(arg); @@ -2634,7 +2640,7 @@ ndis_getstate_80211(sc) bs->nwbx_config.nc_dsconfig / 1000, chanflag); if (ic->ic_curchan == NULL) ic->ic_curchan = &ic->ic_channels[0]; - ic->ic_bss->ni_chan = ic->ic_curchan; + ni->ni_chan = ic->ic_curchan; ic->ic_bsschan = ic->ic_curchan; free(bs, M_TEMP); @@ -2653,27 +2659,27 @@ ndis_getstate_80211(sc) ic->ic_flags &= ~IEEE80211_F_WPA; switch(arg) { case NDIS_80211_AUTHMODE_OPEN: - ic->ic_bss->ni_authmode = IEEE80211_AUTH_OPEN; + ni->ni_authmode = IEEE80211_AUTH_OPEN; break; case NDIS_80211_AUTHMODE_SHARED: - ic->ic_bss->ni_authmode = IEEE80211_AUTH_SHARED; + ni->ni_authmode = IEEE80211_AUTH_SHARED; break; case NDIS_80211_AUTHMODE_AUTO: - ic->ic_bss->ni_authmode = IEEE80211_AUTH_AUTO; + ni->ni_authmode = IEEE80211_AUTH_AUTO; break; case NDIS_80211_AUTHMODE_WPA: case NDIS_80211_AUTHMODE_WPAPSK: case NDIS_80211_AUTHMODE_WPANONE: - ic->ic_bss->ni_authmode = IEEE80211_AUTH_WPA; + ni->ni_authmode = IEEE80211_AUTH_WPA; ic->ic_flags |= IEEE80211_F_WPA1; break; case NDIS_80211_AUTHMODE_WPA2: case NDIS_80211_AUTHMODE_WPA2PSK: - ic->ic_bss->ni_authmode = IEEE80211_AUTH_WPA; + ni->ni_authmode = IEEE80211_AUTH_WPA; ic->ic_flags |= IEEE80211_F_WPA2; break; default: - ic->ic_bss->ni_authmode = IEEE80211_AUTH_NONE; + ni->ni_authmode = IEEE80211_AUTH_NONE; break; } } @@ -2699,6 +2705,7 @@ ndis_ioctl(ifp, command, data) caddr_t data; { struct ndis_softc *sc = ifp->if_softc; + struct ieee80211com *ic = ifp->if_l2com; struct ifreq *ifr = (struct ifreq *) data; struct ndis_oid_data oid; struct ndis_evt evt; @@ -2744,14 +2751,9 @@ ndis_ioctl(ifp, command, data) break; case SIOCGIFMEDIA: case SIOCSIFMEDIA: - if (sc->ndis_80211) { - error = ieee80211_ioctl(&sc->ic, command, data); - if (error == ENETRESET) { - ndis_setstate_80211(sc); - /*ndis_init(sc);*/ - error = 0; - } - } else + if (sc->ndis_80211) + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, command); + else error = ifmedia_ioctl(ifp, ifr, &sc->ifmedia, command); break; case SIOCSIFCAP: @@ -2762,22 +2764,6 @@ ndis_ioctl(ifp, command, data) ifp->if_hwassist = 0; ndis_set_offload(sc); break; - case SIOCG80211: - if (!NDIS_INITIALIZED(sc)) - goto do_80211; - if (sc->ndis_80211) - error = ndis_80211_ioctl_get(ifp, command, data); - else - error = ENOTTY; - break; - case SIOCS80211: - if (!NDIS_INITIALIZED(sc)) - goto do_80211; - if (sc->ndis_80211) - error = ndis_80211_ioctl_set(ifp, command, data); - else - error = ENOTTY; - break; case SIOCGDRVSPEC: if ((error = priv_check(curthread, PRIV_DRIVER))) break; @@ -2878,17 +2864,7 @@ ndis_ioctl(ifp, command, data) NDIS_UNLOCK(sc); break; default: -do_80211: - sc->ndis_skip = 1; - if (sc->ndis_80211) { - error = ieee80211_ioctl(&sc->ic, command, data); - if (error == ENETRESET) { - ndis_setstate_80211(sc); - error = 0; - } - } else - error = ether_ioctl(ifp, command, data); - sc->ndis_skip = 0; + error = ether_ioctl(ifp, command, data); break; } @@ -2897,55 +2873,16 @@ do_80211: return(error); } -static int -ndis_80211_ioctl_get(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct ndis_softc *sc; - struct ieee80211req *ireq; - int error, len; - uint16_t nodename_u[IEEE80211_NWID_LEN + 1]; - unicode_string us; - ansi_string as; - - sc = ifp->if_softc; - ireq = (struct ieee80211req *) data; - - switch (ireq->i_type) { - case IEEE80211_IOC_MLME: - error = 0; - break; - case IEEE80211_IOC_STATIONNAME: - error = ndis_get_info(sc, OID_GEN_MACHINE_NAME, - &nodename_u, &len); - if (error) - break; - us.us_len = us.us_maxlen = len; - us.us_buf = nodename_u; - if (RtlUnicodeStringToAnsiString(&as, &us, TRUE)) { - error = ENOMEM; - break; - } - ireq->i_len = as.as_len; - error = copyout(as.as_buf, ireq->i_data, ireq->i_len); - RtlFreeAnsiString(&as); - break; - default: - error = ieee80211_ioctl(&sc->ic, command, data); - break; - } - return(error); -} - int -ndis_del_key(ic, key) - struct ieee80211com *ic; +ndis_del_key(vap, key) + struct ieee80211vap *vap; const struct ieee80211_key *key; { struct ndis_softc *sc; ndis_80211_key rkey; int len, error = 0; - sc = ic->ic_ifp->if_softc; + sc = vap->iv_ic->ic_ifp->if_softc; bzero((char *)&rkey, sizeof(rkey)); len = sizeof(rkey); @@ -2953,7 +2890,7 @@ ndis_del_key(ic, key) rkey.nk_len = len; rkey.nk_keyidx = key->wk_keyix; - bcopy(ic->ic_ifp->if_broadcastaddr, + bcopy(vap->iv_ifp->if_broadcastaddr, rkey.nk_bssid, IEEE80211_ADDR_LEN); error = ndis_set_info(sc, OID_802_11_REMOVE_KEY, &rkey, &len); @@ -2971,16 +2908,18 @@ ndis_del_key(ic, key) */ static int -ndis_add_key(ic, key, mac) - struct ieee80211com *ic; +ndis_add_key(vap, key, mac) + struct ieee80211vap *vap; const struct ieee80211_key *key; const uint8_t mac[IEEE80211_ADDR_LEN]; { struct ndis_softc *sc; + struct ifnet *ifp; ndis_80211_key rkey; int len, error = 0; - sc = ic->ic_ifp->if_softc; + ifp = vap->iv_ic->ic_ifp; + sc = ifp->if_softc; switch (key->wk_cipher->ic_cipher) { case IEEE80211_CIPHER_TKIP: @@ -3005,17 +2944,17 @@ ndis_add_key(ic, key, mac) rkey.nk_keyidx |= 1 << 31; if (key->wk_flags & IEEE80211_KEY_GROUP) { - bcopy(ic->ic_ifp->if_broadcastaddr, + bcopy(ifp->if_broadcastaddr, rkey.nk_bssid, IEEE80211_ADDR_LEN); } else { - bcopy(ic->ic_bss->ni_bssid, + bcopy(vap->iv_bss->ni_bssid, rkey.nk_bssid, IEEE80211_ADDR_LEN); /* pairwise key */ rkey.nk_keyidx |= 1 << 30; } /* need to set bit 29 based on keyrsc */ - rkey.nk_keyrsc = key->wk_keyrsc; + rkey.nk_keyrsc = key->wk_keyrsc[0]; /* XXX need tid */ if (rkey.nk_keyrsc) rkey.nk_keyidx |= 1 << 29; @@ -3050,54 +2989,6 @@ ndis_add_key(ic, key, mac) return (1); } -static int -ndis_80211_ioctl_set(struct ifnet *ifp, u_long command, caddr_t data) -{ - struct ndis_softc *sc; - struct ieee80211req *ireq; - int error = EINVAL, len; - ansi_string as; - unicode_string us; - - sc = ifp->if_softc; - ireq = (struct ieee80211req *) data; - - switch (ireq->i_type) { - case IEEE80211_IOC_COUNTERMEASURES: - case IEEE80211_IOC_DROPUNENCRYPTED: - error = 0; - break; - case IEEE80211_IOC_STATIONNAME: - error = priv_check(curthread, PRIV_NET80211_MANAGE); - if (error) - break; - if (ireq->i_val != 0 || - ireq->i_len > IEEE80211_NWID_LEN) { - error = EINVAL; - break; - } - as.as_len = as.as_maxlen = ireq->i_len; - as.as_buf = ireq->i_data; - if (RtlAnsiStringToUnicodeString(&us, &as, TRUE)) { - error = ENOMEM; - break; - } - len = us.us_len; - error = ndis_set_info(sc, OID_GEN_MACHINE_NAME, - us.us_buf, &len); - RtlFreeUnicodeString(&us); - break; - default: - error = ieee80211_ioctl(&sc->ic, command, data); - if (error == ENETRESET) { - ndis_setstate_80211(sc); - error = 0; - } - } - - return(error); -} - static void ndis_resettask(d, arg) device_object *d; @@ -3142,13 +3033,8 @@ ndis_stop(sc) struct ndis_softc *sc; { struct ifnet *ifp; - struct ieee80211com *ic; int i; - ic = &sc->ic; - if (sc->ndis_80211) - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - ifp = sc->ifp; callout_drain(&sc->ndis_stat_callout); @@ -3191,24 +3077,26 @@ ndis_shutdown(dev) } static int -ndis_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +ndis_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct ndis_vap *nvp = NDIS_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct ndis_softc *sc = ifp->if_softc; - enum ieee80211_state ostate; + enum ieee80211_state ostate; DPRINTF(("%s: %s -> %s\n", __func__, - ieee80211_state_name[ic->ic_state], + ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate])); - ostate = ic->ic_state; - ic->ic_state = nstate; + ostate = vap->iv_state; + vap->iv_state = nstate; switch (nstate) { /* pass on to net80211 */ case IEEE80211_S_INIT: case IEEE80211_S_SCAN: - return (sc->ndis_newstate(ic, nstate, arg)); + return nvp->newstate(vap, nstate, arg); case IEEE80211_S_ASSOC: if (ostate != IEEE80211_S_AUTH) @@ -3229,14 +3117,19 @@ static void ndis_scan(void *arg, int npending) { struct ndis_softc *sc = arg; - struct ieee80211com *ic = (void *)&sc->ic; - struct ieee80211_scan_state *ss = ic->ic_scan; + struct ieee80211com *ic; + struct ieee80211vap *vap; + struct ieee80211_scan_state *ss; ndis_80211_ssid ssid; int error, len; + ic = sc->ifp->if_l2com; + ss = ic->ic_scan; + vap = TAILQ_FIRST(&ic->ic_vaps); + if (!NDIS_INITIALIZED(sc)) { DPRINTF(("%s: scan aborted\n", __func__)); - ieee80211_cancel_scan(ic); + ieee80211_cancel_scan(vap); return; } @@ -3257,7 +3150,7 @@ ndis_scan(void *arg, int npending) NULL, &len); if (error) { DPRINTF(("%s: scan command failed\n", __func__)); - ieee80211_cancel_scan(ic); + ieee80211_cancel_scan(vap); return; } @@ -3267,13 +3160,14 @@ ndis_scan(void *arg, int npending) return; ndis_scan_results(sc); - ieee80211_scan_done(ic); + ieee80211_scan_done(vap); } static void ndis_scan_results(struct ndis_softc *sc) { - struct ieee80211com *ic = (void *)&sc->ic; + struct ieee80211com *ic; + struct ieee80211vap *vap; ndis_80211_bssid_list_ex *bl; ndis_wlan_bssid_ex *wb; struct ieee80211_scanparams sp; @@ -3285,6 +3179,8 @@ ndis_scan_results(struct ndis_softc *sc) uint8_t rates[2+IEEE80211_RATE_MAXSIZE]; uint8_t *frm, *efrm; + ic = sc->ifp->if_l2com; + vap = TAILQ_FIRST(&ic->ic_vaps); noise = -96; len = sizeof(uint32_t) + (sizeof(ndis_wlan_bssid_ex) * 16); @@ -3344,10 +3240,7 @@ ndis_scan_results(struct ndis_softc *sc) chanflag = ndis_nettype_chan(wb->nwbx_nettype); freq = wb->nwbx_config.nc_dsconfig / 1000; - sp.bchan = ieee80211_mhz2ieee(freq, chanflag); - sp.curchan = ieee80211_find_channel(ic, freq, chanflag); - if (sp.curchan == NULL) - sp.curchan = &ic->ic_channels[0]; + sp.chan = sp.bchan = ieee80211_mhz2ieee(freq, chanflag); /* Process extended info from AP */ if (wb->nwbx_len > sizeof(ndis_wlan_bssid)) { @@ -3378,7 +3271,7 @@ done: DPRINTF(("scan: bssid %s chan %dMHz (%d/%d) rssi %d\n", ether_sprintf(wb->nwbx_macaddr), freq, sp.bchan, chanflag, rssi)); - ieee80211_add_scan(ic, &sp, &wh, 0, rssi, noise, rstamp); + ieee80211_add_scan(vap, &sp, &wh, 0, rssi, noise, rstamp); wb = (ndis_wlan_bssid_ex *)((char *)wb + wb->nwbx_len); } free(bl, M_DEVBUF); @@ -3400,13 +3293,13 @@ ndis_set_channel(struct ieee80211com *ic) } static void -ndis_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) +ndis_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { /* ignore */ } static void -ndis_scan_mindwell(struct ieee80211com *ic) +ndis_scan_mindwell(struct ieee80211_scan_state *ss) { /* NB: don't try to abort scan; wait for firmware to finish */ } diff --git a/sys/dev/if_ndis/if_ndisvar.h b/sys/dev/if_ndis/if_ndisvar.h index cdbf543..6814709 100644 --- a/sys/dev/if_ndis/if_ndisvar.h +++ b/sys/dev/if_ndis/if_ndisvar.h @@ -99,8 +99,15 @@ struct ndis_evt { char *ne_buf; }; +struct ndis_vap { + struct ieee80211vap vap; + + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define NDIS_VAP(vap) ((struct ndis_vap *)(vap)) + struct ndis_softc { - struct ieee80211com ic; /* interface info */ struct ifnet *ifp; struct ifmedia ifmedia; /* media info */ u_long ndis_hwassist; diff --git a/sys/dev/ipw/if_ipw.c b/sys/dev/ipw/if_ipw.c index 8a69a40..f21bc5b 100644 --- a/sys/dev/ipw/if_ipw.c +++ b/sys/dev/ipw/if_ipw.c @@ -107,13 +107,21 @@ static const struct ipw_ident ipw_ident_table[] = { { 0, 0, NULL } }; +static struct ieee80211vap *ipw_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void ipw_vap_delete(struct ieee80211vap *); static int ipw_dma_alloc(struct ipw_softc *); static void ipw_release(struct ipw_softc *); -static int ipw_media_change(struct ifnet *); static void ipw_media_status(struct ifnet *, struct ifmediareq *); -static int ipw_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int ipw_newstate(struct ieee80211vap *, enum ieee80211_state, int); static uint16_t ipw_read_prom_word(struct ipw_softc *, uint8_t); static void ipw_rx_cmd_intr(struct ipw_softc *, struct ipw_soft_buf *); +static void ipw_assocsuccess(void *, int); +static void ipw_assocfailed(void *, int); +static void ipw_scandone(void *, int); +static void ipw_bmiss(void *, int); static void ipw_rx_newstate_intr(struct ipw_softc *, struct ipw_soft_buf *); static void ipw_rx_data_intr(struct ipw_softc *, struct ipw_status *, struct ipw_soft_bd *, struct ipw_soft_buf *); @@ -126,6 +134,8 @@ static const char * ipw_cmdname(int); static int ipw_cmd(struct ipw_softc *, uint32_t, void *, uint32_t); static int ipw_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *); +static int ipw_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); static void ipw_start(struct ifnet *); static void ipw_start_locked(struct ifnet *); static void ipw_watchdog(void *); @@ -138,12 +148,10 @@ static int ipw_load_ucode(struct ipw_softc *, const char *, int); static int ipw_load_firmware(struct ipw_softc *, const char *, int); static int ipw_config(struct ipw_softc *); static void ipw_assoc_task(void *, int); -static int ipw_auth_and_assoc(struct ipw_softc *); static void ipw_disassoc_task(void *, int); -static int ipw_disassociate(struct ipw_softc *); static void ipw_init_task(void *, int); static void ipw_init(void *); -static void ipw_init_locked(struct ipw_softc *, int); +static void ipw_init_locked(struct ipw_softc *); static void ipw_stop(void *); static void ipw_stop_locked(struct ipw_softc *); static int ipw_sysctl_stats(SYSCTL_HANDLER_ARGS); @@ -163,8 +171,9 @@ static int ipw_scan(struct ipw_softc *); static void ipw_scan_start(struct ieee80211com *); static void ipw_scan_end(struct ieee80211com *); static void ipw_set_channel(struct ieee80211com *); -static void ipw_scan_curchan(struct ieee80211com *, unsigned long maxdwell); -static void ipw_scan_mindwell(struct ieee80211com *); +static void ipw_scan_curchan(struct ieee80211_scan_state *, + unsigned long maxdwell); +static void ipw_scan_mindwell(struct ieee80211_scan_state *); static int ipw_probe(device_t); static int ipw_attach(device_t); @@ -219,7 +228,7 @@ ipw_attach(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); struct ifnet *ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; struct ieee80211_channel *c; uint16_t val; int error, i; @@ -231,8 +240,7 @@ ipw_attach(device_t dev) TASK_INIT(&sc->sc_init_task, 0, ipw_init_task, sc); TASK_INIT(&sc->sc_scan_task, 0, ipw_scan_task, sc); - TASK_INIT(&sc->sc_assoc_task, 0, ipw_assoc_task, sc); - TASK_INIT(&sc->sc_disassoc_task, 0, ipw_disassoc_task, sc); + TASK_INIT(&sc->sc_bmiss_task, 0, ipw_bmiss, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { @@ -262,24 +270,25 @@ ipw_attach(device_t dev) RF_ACTIVE | RF_SHAREABLE); if (sc->irq == NULL) { device_printf(dev, "could not allocate interrupt resource\n"); - goto fail; + goto fail1; } if (ipw_reset(sc) != 0) { device_printf(dev, "could not reset adapter\n"); - goto fail; + goto fail2; } if (ipw_dma_alloc(sc) != 0) { device_printf(dev, "could not allocate DMA resources\n"); - goto fail; + goto fail2; } - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); - goto fail; + goto fail3; } + ic = ifp->if_l2com; ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); @@ -292,9 +301,8 @@ ipw_attach(device_t dev) IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_DS; ic->ic_opmode = IEEE80211_M_STA; - ic->ic_state = IEEE80211_S_INIT; + ic->ic_phytype = IEEE80211_T_DS; /* set device capabilities */ ic->ic_caps = IEEE80211_C_IBSS /* IBSS mode supported */ @@ -333,20 +341,18 @@ ipw_attach(device_t dev) sc->flags |= IPW_FLAG_HAS_RADIO_SWITCH; ieee80211_ifattach(ic); - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = ipw_newstate; - ieee80211_media_init(ic, ipw_media_change, ipw_media_status); - ic->ic_scan_start = ipw_scan_start; ic->ic_scan_end = ipw_scan_end; ic->ic_set_channel = ipw_set_channel; ic->ic_scan_curchan = ipw_scan_curchan; ic->ic_scan_mindwell = ipw_scan_mindwell; + ic->ic_raw_xmit = ipw_raw_xmit; - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), - &sc->sc_drvbpf); + ic->ic_vap_create = ipw_vap_create; + ic->ic_vap_delete = ipw_vap_delete; + + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); @@ -359,8 +365,6 @@ ipw_attach(device_t dev) /* * Add a few sysctl knobs. */ - sc->dwelltime = 100; - SYSCTL_ADD_PROC(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "radio", CTLTYPE_INT | CTLFLAG_RD, sc, 0, ipw_sysctl_radio, "I", @@ -371,11 +375,6 @@ ipw_attach(device_t dev) CTLTYPE_OPAQUE | CTLFLAG_RD, sc, 0, ipw_sysctl_stats, "S", "statistics"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell", - CTLFLAG_RW, &sc->dwelltime, 0, - "channel dwell time (ms) for AP/station scanning"); - /* * Hook our interrupt after all initialization is complete. */ @@ -383,15 +382,23 @@ ipw_attach(device_t dev) NULL, ipw_intr, sc, &sc->sc_ih); if (error != 0) { device_printf(dev, "could not set up interrupt\n"); - goto fail; + goto fail4; } if (bootverbose) ieee80211_announce(ic); return 0; - -fail: ipw_detach(dev); +fail4: + if_free(ifp); +fail3: + ipw_release(sc); +fail2: + bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); +fail1: + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); +fail: + mtx_destroy(&sc->sc_mtx); return ENXIO; } @@ -399,33 +406,27 @@ static int ipw_detach(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; ipw_stop(sc); + + bpfdetach(ifp); + ieee80211_ifdetach(ic); + callout_drain(&sc->sc_wdtimer); taskqueue_drain(taskqueue_fast, &sc->sc_init_task); taskqueue_drain(taskqueue_fast, &sc->sc_scan_task); - taskqueue_drain(taskqueue_fast, &sc->sc_assoc_task); - taskqueue_drain(taskqueue_fast, &sc->sc_disassoc_task); - - if (ifp != NULL) { - bpfdetach(ifp); - ieee80211_ifdetach(ic); - } + taskqueue_drain(taskqueue_fast, &sc->sc_bmiss_task); ipw_release(sc); - if (sc->irq != NULL) { - bus_teardown_intr(dev, sc->irq, sc->sc_ih); - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); - } + bus_teardown_intr(dev, sc->irq, sc->sc_ih); + bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); - if (sc->mem != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); - if (ifp != NULL) - if_free(ifp); + if_free(ifp); if (sc->sc_firmware != NULL) { firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); @@ -437,6 +438,103 @@ ipw_detach(device_t dev) return 0; } +static struct ieee80211vap * +ipw_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ifnet *ifp = ic->ic_ifp; + struct ipw_softc *sc = ifp->if_softc; + struct ipw_vap *ivp; + struct ieee80211vap *vap; + const struct firmware *fp; + const struct ipw_firmware_hdr *hdr; + const char *imagename; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + + switch (opmode) { + case IEEE80211_M_STA: + imagename = "ipw_bss"; + break; + case IEEE80211_M_IBSS: + imagename = "ipw_ibss"; + break; + case IEEE80211_M_MONITOR: + imagename = "ipw_monitor"; + break; + default: + return NULL; + } + + /* + * Load firmware image using the firmware(9) subsystem. Doing + * this unlocked is ok since we're single-threaded by the + * 802.11 layer. + */ + if (sc->sc_firmware == NULL || + strcmp(sc->sc_firmware->name, imagename) != 0) { + if (sc->sc_firmware != NULL) + firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); + sc->sc_firmware = firmware_get(imagename); + } + if (sc->sc_firmware == NULL) { + device_printf(sc->sc_dev, + "could not load firmware image '%s'\n", imagename); + return NULL; + } + fp = sc->sc_firmware; + if (fp->datasize < sizeof *hdr) { + device_printf(sc->sc_dev, + "firmware image too short %zu\n", fp->datasize); + firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); + sc->sc_firmware = NULL; + return NULL; + } + hdr = (const struct ipw_firmware_hdr *)fp->data; + if (fp->datasize < sizeof *hdr + le32toh(hdr->mainsz) + + le32toh(hdr->ucodesz)) { + device_printf(sc->sc_dev, + "firmware image too short %zu\n", fp->datasize); + firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); + sc->sc_firmware = NULL; + return NULL; + } + + ivp = (struct ipw_vap *) malloc(sizeof(struct ipw_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (ivp == NULL) + return NULL; + vap = &ivp->vap; + + TASK_INIT(&ivp->assoc_task, 0, ipw_assoc_task, vap); + TASK_INIT(&ivp->disassoc_task, 0, ipw_disassoc_task, vap); + TASK_INIT(&ivp->assoc_success_task, 0, ipw_assocsuccess, vap); + TASK_INIT(&ivp->assoc_failed_task, 0, ipw_assocfailed, vap); + TASK_INIT(&ivp->scandone_task, 0, ipw_scandone, vap); + + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + /* override with driver methods */ + ivp->newstate = vap->iv_newstate; + vap->iv_newstate = ipw_newstate; + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ipw_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +ipw_vap_delete(struct ieee80211vap *vap) +{ + struct ipw_vap *ivp = IPW_VAP(vap); + + ieee80211_vap_detach(vap); + free(ivp, M_80211_VAP); +} + static int ipw_dma_alloc(struct ipw_softc *sc) { @@ -748,45 +846,17 @@ static int ipw_resume(device_t dev) { struct ipw_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ic.ic_ifp; - IPW_LOCK_DECL; - - IPW_LOCK(sc); + struct ifnet *ifp = sc->sc_ifp; pci_write_config(dev, 0x41, 0, 1); - if (ifp->if_flags & IFF_UP) { - ipw_init_locked(sc, 0); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ipw_start_locked(ifp); - } - - IPW_UNLOCK(sc); + if (ifp->if_flags & IFF_UP) + ipw_init(sc); return 0; } static int -ipw_media_change(struct ifnet *ifp) -{ - struct ipw_softc *sc = ifp->if_softc; - int error; - IPW_LOCK_DECL; - - IPW_LOCK(sc); - error = ieee80211_media_change(ifp); - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) - ipw_init_locked(sc, 0); - error = 0; - } - IPW_UNLOCK(sc); - - return (error); -} - -static int ipw_cvtrate(int ipwrate) { switch (ipwrate) { @@ -805,47 +875,26 @@ ipw_cvtrate(int ipwrate) static void ipw_media_status(struct ifnet *ifp, struct ifmediareq *imr) { - struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int rate; - - imr->ifm_status = IFM_AVALID; - imr->ifm_active = IFM_IEEE80211; - if (ic->ic_state == IEEE80211_S_RUN) - imr->ifm_status |= IFM_ACTIVE; + struct ieee80211vap *vap = ifp->if_softc; + struct ieee80211com *ic = vap->iv_ic; + struct ipw_softc *sc = ic->ic_ifp->if_softc; /* read current transmission rate from adapter */ - rate = ipw_cvtrate(ipw_read_table1(sc, IPW_INFO_CURRENT_TX_RATE) & 0xf); - imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B); - - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - break; - - case IEEE80211_M_IBSS: - imr->ifm_active |= IFM_IEEE80211_IBSS; - break; - - case IEEE80211_M_MONITOR: - imr->ifm_active |= IFM_IEEE80211_MONITOR; - break; - - case IEEE80211_M_AHDEMO: - case IEEE80211_M_HOSTAP: - case IEEE80211_M_WDS: - /* should not get there */ - break; - } + vap->iv_bss->ni_txrate = ipw_cvtrate( + ipw_read_table1(sc, IPW_INFO_CURRENT_TX_RATE) & 0xf); + ieee80211_media_status(ifp, imr); } static int -ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +ipw_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct ipw_vap *ivp = IPW_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct ipw_softc *sc = ifp->if_softc; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, - ieee80211_state_name[ic->ic_state], + ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate], sc->flags)); switch (nstate) { @@ -859,36 +908,40 @@ ipw_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) * AUTH -> RUN transition and we want to do nothing. * This is all totally bogus and needs to be redone. */ - if (ic->ic_state == IEEE80211_S_SCAN) - taskqueue_enqueue_fast(taskqueue_fast, - &sc->sc_assoc_task); + if (vap->iv_state == IEEE80211_S_SCAN) { + taskqueue_enqueue(taskqueue_swi, + &IPW_VAP(vap)->assoc_task); + return EINPROGRESS; + } } break; case IEEE80211_S_INIT: if (sc->flags & IPW_FLAG_ASSOCIATED) - taskqueue_enqueue_fast(taskqueue_fast, - &sc->sc_disassoc_task); + taskqueue_enqueue(taskqueue_swi, + &IPW_VAP(vap)->disassoc_task); break; case IEEE80211_S_AUTH: - taskqueue_enqueue_fast(taskqueue_fast, &sc->sc_assoc_task); - break; + taskqueue_enqueue(taskqueue_swi, &IPW_VAP(vap)->assoc_task); + return EINPROGRESS; case IEEE80211_S_ASSOC: /* * If we are not transitioning from AUTH the resend the * association request. */ - if (ic->ic_state != IEEE80211_S_AUTH) - taskqueue_enqueue_fast(taskqueue_fast, - &sc->sc_assoc_task); + if (vap->iv_state != IEEE80211_S_AUTH) { + taskqueue_enqueue(taskqueue_swi, + &IPW_VAP(vap)->assoc_task); + return EINPROGRESS; + } break; default: break; } - return (*sc->sc_newstate)(ic, nstate, arg); + return ivp->newstate(vap, nstate, arg); } /* @@ -965,10 +1018,44 @@ ipw_rx_cmd_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) } static void +ipw_assocsuccess(void *arg, int npending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_new_state(vap, IEEE80211_S_RUN, -1); +} + +static void +ipw_assocfailed(void *arg, int npending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); +} + +static void +ipw_scandone(void *arg, int npending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_scan_done(vap); +} + +static void +ipw_bmiss(void *arg, int npending) +{ + struct ieee80211com *ic = arg; + + ieee80211_beacon_miss(ic); +} + +static void ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) { -#define IEEESTATE(ic) ieee80211_state_name[ic->ic_state] - struct ieee80211com *ic = &sc->sc_ic; +#define IEEESTATE(vap) ieee80211_state_name[vap->iv_state] + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t state; bus_dmamap_sync(sc->rxbuf_dmat, sbuf->map, BUS_DMASYNC_POSTREAD); @@ -978,27 +1065,32 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) switch (state) { case IPW_STATE_ASSOCIATED: DPRINTFN(2, ("Association succeeded (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); - sc->flags |= IPW_FLAG_ASSOCIATED; + IEEESTATE(vap), sc->flags)); /* XXX suppress state change in case the fw auto-associates */ - if (ic->ic_state != IEEE80211_S_ASSOC) { - DPRINTF(("Unexpected association (state %u)\n", - ic->ic_state)); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + if ((sc->flags & IPW_FLAG_ASSOCIATING) == 0) { + DPRINTF(("Unexpected association (%s, flags 0x%x)\n", + IEEESTATE(vap), sc->flags)); + break; + } + sc->flags &= ~IPW_FLAG_ASSOCIATING; + sc->flags |= IPW_FLAG_ASSOCIATED; + taskqueue_enqueue(taskqueue_swi, + &IPW_VAP(vap)->assoc_success_task); break; case IPW_STATE_SCANNING: DPRINTFN(3, ("Scanning (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); /* * NB: Check driver state for association on assoc * loss as the firmware will immediately start to * scan and we would treat it as a beacon miss if * we checked the 802.11 layer state. */ - if (sc->flags & IPW_FLAG_ASSOCIATED) - ieee80211_beacon_miss(ic); + if (sc->flags & IPW_FLAG_ASSOCIATED) { + /* XXX probably need to issue disassoc to fw */ + taskqueue_enqueue(taskqueue_swi, &sc->sc_bmiss_task); + } break; case IPW_STATE_SCAN_COMPLETE: @@ -1009,14 +1101,15 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) * around this by marking the HACK flag and skipping * the first scan complete event. */ + DPRINTFN(3, ("Scan complete (%s flags 0x%x)\n", + IEEESTATE(vap), sc->flags)); if (sc->flags & IPW_FLAG_HACK) { sc->flags &= ~IPW_FLAG_HACK; break; } - DPRINTFN(3, ("Scan complete (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); if (sc->flags & IPW_FLAG_SCANNING) { - ieee80211_scan_done(ic); + taskqueue_enqueue(taskqueue_swi, + &IPW_VAP(vap)->scandone_task); sc->flags &= ~IPW_FLAG_SCANNING; sc->sc_scan_timer = 0; } @@ -1024,27 +1117,31 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) case IPW_STATE_ASSOCIATION_LOST: DPRINTFN(2, ("Association lost (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); - sc->flags &= ~IPW_FLAG_ASSOCIATED; - if (ic->ic_state == IEEE80211_S_RUN) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); + IEEESTATE(vap), sc->flags)); + sc->flags &= ~(IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); + if (vap->iv_state == IEEE80211_S_RUN) + taskqueue_enqueue(taskqueue_swi, + &IPW_VAP(vap)->assoc_failed_task); break; case IPW_STATE_DISABLED: + /* XXX? is this right? */ + sc->flags &= ~(IPW_FLAG_HACK | IPW_FLAG_SCANNING | + IPW_FLAG_ASSOCIATING | IPW_FLAG_ASSOCIATED); DPRINTFN(2, ("Firmware disabled (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); + IEEESTATE(vap), sc->flags)); break; case IPW_STATE_RADIO_DISABLED: - DPRINTFN(2, ("Radio off (%s flags 0x%x)\n", - IEEESTATE(ic), sc->flags)); - ic->ic_ifp->if_flags &= ~IFF_UP; + device_printf(sc->sc_dev, "radio turned off\n"); + ieee80211_notify_radio(ic, 0); ipw_stop_locked(sc); + /* XXX start polling thread to detect radio on */ break; default: DPRINTFN(2, ("%s: unhandled state %u %s flags 0x%x\n", - __func__, state, IEEESTATE(ic), sc->flags)); + __func__, state, IEEESTATE(vap), sc->flags)); break; } #undef IEEESTATE @@ -1056,7 +1153,8 @@ ipw_rx_newstate_intr(struct ipw_softc *sc, struct ipw_soft_buf *sbuf) static void ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; ic->ic_curchan = chan; sc->sc_rxtap.wr_chan_freq = sc->sc_txtap.wt_chan_freq = @@ -1072,7 +1170,8 @@ ipw_setcurchan(struct ipw_softc *sc, struct ieee80211_channel *chan) static void ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_channel *c; struct ieee80211_frame *wh; uint8_t subtype; @@ -1089,6 +1188,7 @@ ipw_fix_channel(struct ipw_softc *sc, struct mbuf *m) subtype != IEEE80211_FC0_SUBTYPE_PROBE_RESP) return; + /* XXX use ieee80211_parse_beacon */ frm = (uint8_t *)(wh + 1); efrm = mtod(m, uint8_t *) + m->m_len; @@ -1116,10 +1216,9 @@ static void ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, struct ipw_soft_bd *sbd, struct ipw_soft_buf *sbuf) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct mbuf *mnew, *m; - struct ieee80211_frame *wh; struct ieee80211_node *ni; bus_addr_t physaddr; int error; @@ -1177,7 +1276,7 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = le32toh(status->len); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct ipw_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; @@ -1185,21 +1284,19 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } if (sc->flags & IPW_FLAG_SCANNING) ipw_fix_channel(sc, m); - wh = mtod(m, struct ieee80211_frame *); IPW_UNLOCK(sc); - ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); - - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, status->rssi, -95/*XXX*/, 0); - - /* node is no longer needed */ - ieee80211_free_node(ni); + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + (void) ieee80211_input(ni, m, status->rssi, -95, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, status->rssi, -95, 0); IPW_LOCK(sc); bus_dmamap_sync(sc->rbd_dmat, sc->rbd_map, BUS_DMASYNC_PREWRITE); @@ -1208,7 +1305,6 @@ ipw_rx_data_intr(struct ipw_softc *sc, struct ipw_status *status, static void ipw_rx_intr(struct ipw_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; struct ipw_status *status; struct ipw_soft_bd *sbd; struct ipw_soft_buf *sbuf; @@ -1243,11 +1339,7 @@ ipw_rx_intr(struct ipw_softc *sc) case IPW_STATUS_CODE_NOTIFICATION: DPRINTFN(2, ("notification status, len %u flags 0x%x\n", le32toh(status->len), status->flags)); - if (ic->ic_state == IEEE80211_S_AUTH) { - /* XXX assume auth notification */ - ieee80211_node_authorize(ic->ic_bss); - ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1); - } + /* XXX maybe drive state machine AUTH->ASSOC? */ break; default: @@ -1311,7 +1403,7 @@ ipw_release_sbd(struct ipw_softc *sc, struct ipw_soft_bd *sbd) static void ipw_tx_intr(struct ipw_softc *sc) { - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct ipw_soft_bd *sbd; uint32_t r, i; @@ -1359,7 +1451,7 @@ ipw_intr(void *arg) if (r & (IPW_INTR_FATAL_ERROR | IPW_INTR_PARITY_ERROR)) { device_printf(sc->sc_dev, "firmware error\n"); - taskqueue_enqueue_fast(taskqueue_fast, &sc->sc_init_task); + taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task); r = 0; /* don't process more interrupts */ } @@ -1447,6 +1539,8 @@ ipw_cmd(struct ipw_softc *sc, uint32_t type, void *data, uint32_t len) bus_addr_t physaddr; int error; + IPW_LOCK_ASSERT(sc); + if (sc->flags & IPW_FLAG_BUSY) { device_printf(sc->sc_dev, "%s: %s not sent, busy\n", __func__, ipw_cmdname(type)); @@ -1514,7 +1608,7 @@ static int ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) { struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_frame *wh; struct ipw_soft_bd *sbd; struct ipw_soft_hdr *shdr; @@ -1528,24 +1622,23 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; } - /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct ipw_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } shdr = SLIST_FIRST(&sc->free_shdr); @@ -1660,6 +1753,16 @@ ipw_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni) return 0; } +static int +ipw_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + /* no support; just discard */ + m_freem(m); + ieee80211_free_node(ni); + return 0; +} + static void ipw_start(struct ifnet *ifp) { @@ -1675,54 +1778,31 @@ static void ipw_start_locked(struct ifnet *ifp) { struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct mbuf *m0; - struct ether_header *eh; struct ieee80211_node *ni; + struct mbuf *m; IPW_LOCK_ASSERT(sc); - if (ic->ic_state != IEEE80211_S_RUN) - return; - for (;;) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) break; - if (sc->txfree < 1 + IPW_MAX_NSEG) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); + IFQ_DRV_PREPEND(&ifp->if_snd, m); ifp->if_drv_flags |= IFF_DRV_OACTIVE; break; } - - if (m0->m_len < sizeof (struct ether_header) && - (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) - continue; - - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - BPF_MTAP(ifp, m0); - - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { ieee80211_free_node(ni); continue; } - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (ipw_tx_start(ifp, m0, ni) != 0) { + if (ipw_tx_start(ifp, m, ni) != 0) { ieee80211_free_node(ni); ifp->if_oerrors++; break; } - /* start watchdog timer */ sc->sc_tx_timer = 5; } @@ -1732,8 +1812,8 @@ static void ipw_watchdog(void *arg) { struct ipw_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; IPW_LOCK_ASSERT(sc); @@ -1741,8 +1821,7 @@ ipw_watchdog(void *arg) if (--sc->sc_tx_timer == 0) { if_printf(ifp, "device timeout\n"); ifp->if_oerrors++; - taskqueue_enqueue_fast(taskqueue_fast, - &sc->sc_init_task); + taskqueue_enqueue(taskqueue_swi, &sc->sc_init_task); } } if (sc->sc_scan_timer > 0) { @@ -1750,7 +1829,7 @@ ipw_watchdog(void *arg) DPRINTFN(3, ("Scan timeout\n")); /* End the scan */ if (sc->flags & IPW_FLAG_SCANNING) { - ieee80211_scan_done(ic); + ieee80211_scan_done(TAILQ_FIRST(&ic->ic_vaps)); sc->flags &= ~IPW_FLAG_SCANNING; } } @@ -1763,37 +1842,35 @@ static int ipw_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ipw_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; IPW_LOCK_DECL; IPW_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - ipw_init_locked(sc, 0); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + ipw_init_locked(sc); + startall = 1; + } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) ipw_stop_locked(sc); } break; - + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - ipw_init_locked(sc, 0); - error = 0; + error = ether_ioctl(ifp, cmd, data); } - IPW_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } @@ -2010,13 +2087,15 @@ ipw_load_firmware(struct ipw_softc *sc, const char *fw, int size) static int ipw_setwepkeys(struct ipw_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ipw_wep_key wepkey; struct ieee80211_key *wk; int error, i; for (i = 0; i < IEEE80211_WEP_NKID; i++) { - wk = &ic->ic_crypto.cs_nw_keys[i]; + wk = &vap->iv_nw_keys[i]; if (wk->wk_cipher == NULL || wk->wk_cipher->ic_cipher != IEEE80211_CIPHER_WEP) @@ -2166,7 +2245,8 @@ done: static int ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t data; int error; @@ -2178,308 +2258,126 @@ ipw_setchannel(struct ipw_softc *sc, struct ieee80211_channel *chan) return error; } -static int -ipw_config(struct ipw_softc *sc) +static void +ipw_assoc_task(void *context, int pending) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ieee80211vap *vap = context; + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ipw_softc *sc = ifp->if_softc; + struct ieee80211_node *ni = vap->iv_bss; struct ipw_security security; - struct ipw_configuration config; uint32_t data; int error; + IPW_LOCK_DECL; + IPW_LOCK(sc); error = ipw_disable(sc); if (error != 0) - return error; + goto done; - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - case IEEE80211_M_HOSTAP: - case IEEE80211_M_WDS: /* XXX */ - data = htole32(IPW_MODE_BSS); - break; - case IEEE80211_M_IBSS: - case IEEE80211_M_AHDEMO: - data = htole32(IPW_MODE_IBSS); - break; - case IEEE80211_M_MONITOR: - data = htole32(IPW_MODE_MONITOR); - break; - } - DPRINTF(("Setting mode to %u\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_MODE, &data, sizeof data); + memset(&security, 0, sizeof security); + security.authmode = (ni->ni_authmode == IEEE80211_AUTH_SHARED) ? + IPW_AUTH_SHARED : IPW_AUTH_OPEN; + security.ciphers = htole32(IPW_CIPHER_NONE); + DPRINTF(("Setting authmode to %u\n", security.authmode)); + error = ipw_cmd(sc, IPW_CMD_SET_SECURITY_INFO, &security, + sizeof security); if (error != 0) - return error; - - if (ic->ic_opmode == IEEE80211_M_IBSS || - ic->ic_opmode == IEEE80211_M_MONITOR) { - error = ipw_setchannel(sc, ic->ic_curchan); - if (error != 0) - return error; - } - - if (ic->ic_opmode == IEEE80211_M_MONITOR) - return ipw_enable(sc); + goto done; - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - DPRINTF(("Setting MAC address to %6D\n", ic->ic_myaddr, ":")); - error = ipw_cmd(sc, IPW_CMD_SET_MAC_ADDRESS, ic->ic_myaddr, - IEEE80211_ADDR_LEN); + data = htole32(vap->iv_rtsthreshold); + DPRINTF(("Setting RTS threshold to %u\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_RTS_THRESHOLD, &data, sizeof data); if (error != 0) - return error; + goto done; - config.flags = htole32(IPW_CFG_BSS_MASK | IPW_CFG_IBSS_MASK | - IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE); - if (ic->ic_opmode == IEEE80211_M_IBSS) - config.flags |= htole32(IPW_CFG_IBSS_AUTO_START); - if (ifp->if_flags & IFF_PROMISC) - config.flags |= htole32(IPW_CFG_PROMISCUOUS); - config.bss_chan = htole32(0x3fff); /* channels 1-14 */ - config.ibss_chan = htole32(0x7ff); /* channels 1-11 */ - DPRINTF(("Setting configuration to 0x%x\n", le32toh(config.flags))); - error = ipw_cmd(sc, IPW_CMD_SET_CONFIGURATION, &config, sizeof config); + data = htole32(vap->iv_fragthreshold); + DPRINTF(("Setting frag threshold to %u\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_FRAG_THRESHOLD, &data, sizeof data); if (error != 0) - return error; + goto done; - data = htole32(0x3); /* 1, 2 */ - DPRINTF(("Setting basic tx rates to 0x%x\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_BASIC_TX_RATES, &data, sizeof data); - if (error != 0) - return error; - - /* NB: use the same rate set */ - DPRINTF(("Setting msdu tx rates to 0x%x\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_MSDU_TX_RATES, &data, sizeof data); - if (error != 0) - return error; - - data = htole32(0xf); /* 1, 2, 5.5, 11 */ - DPRINTF(("Setting tx rates to 0x%x\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_TX_RATES, &data, sizeof data); - if (error != 0) - return error; - - data = htole32(IPW_POWER_MODE_CAM); - DPRINTF(("Setting power mode to %u\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_POWER_MODE, &data, sizeof data); - if (error != 0) - return error; - - if (ic->ic_opmode == IEEE80211_M_IBSS) { - data = htole32(32); /* default value */ - DPRINTF(("Setting tx power index to %u\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_TX_POWER_INDEX, &data, - sizeof data); - if (error != 0) - return error; - } - - data = htole32(ic->ic_rtsthreshold); - DPRINTF(("Setting RTS threshold to %u\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_RTS_THRESHOLD, &data, sizeof data); - if (error != 0) - return error; - - data = htole32(ic->ic_fragthreshold); - DPRINTF(("Setting frag threshold to %u\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_FRAG_THRESHOLD, &data, sizeof data); - if (error != 0) - return error; - - error = ipw_setssid(sc, ic->ic_des_ssid[0].ssid, ic->ic_des_ssid[0].len); - if (error != 0) - return error; - - error = ipw_setbssid(sc, NULL); - if (error != 0) - return error; - - if (ic->ic_flags & IEEE80211_F_DESBSSID) { - DPRINTF(("Setting desired BSSID to %6D\n", ic->ic_des_bssid, - ":")); - error = ipw_cmd(sc, IPW_CMD_SET_DESIRED_BSSID, - ic->ic_des_bssid, IEEE80211_ADDR_LEN); - if (error != 0) - return error; - } - - memset(&security, 0, sizeof security); - security.authmode = (ic->ic_bss->ni_authmode == IEEE80211_AUTH_SHARED) ? - IPW_AUTH_SHARED : IPW_AUTH_OPEN; - security.ciphers = htole32(IPW_CIPHER_NONE); - DPRINTF(("Setting authmode to %u\n", security.authmode)); - error = ipw_cmd(sc, IPW_CMD_SET_SECURITY_INFO, &security, - sizeof security); - if (error != 0) - return error; - - if (ic->ic_flags & IEEE80211_F_PRIVACY) { - error = ipw_setwepkeys(sc); - if (error != 0) - return error; - - if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE) { - data = htole32(ic->ic_crypto.cs_def_txkey); - DPRINTF(("Setting wep tx key index to %u\n", - le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data, - sizeof data); - if (error != 0) - return error; - } - } - - data = htole32((ic->ic_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); - DPRINTF(("Setting wep flags to 0x%x\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data); - if (error != 0) - return error; - - if (ic->ic_opt_ie != NULL) { - error = ipw_setwpaie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len); - if (error != 0) - return error; - } - - if (ic->ic_opmode == IEEE80211_M_IBSS) { - data = htole32(ic->ic_bintval); - DPRINTF(("Setting beacon interval to %u\n", le32toh(data))); - error = ipw_cmd(sc, IPW_CMD_SET_BEACON_INTERVAL, &data, - sizeof data); - if (error != 0) - return error; - } - - error = ipw_setscanopts(sc, 0x3fff, 0); - if (error != 0) - return error; - - return (ipw_enable(sc)); -} - -/* - * Handler for sc_assoc_task. This is a simple wrapper around - * ipw_auth_and_assoc(). - */ -static void -ipw_assoc_task(void *context, int pending) -{ - struct ipw_softc *sc = context; - IPW_LOCK_DECL; - - IPW_LOCK(sc); - ipw_auth_and_assoc(sc); - IPW_UNLOCK(sc); -} - -static int -ipw_auth_and_assoc(struct ipw_softc *sc) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; - struct ipw_security security; - uint32_t data; - int error; - - error = ipw_disable(sc); - if (error != 0) - return (error); - - memset(&security, 0, sizeof security); - security.authmode = (ni->ni_authmode == IEEE80211_AUTH_SHARED) ? - IPW_AUTH_SHARED : IPW_AUTH_OPEN; - security.ciphers = htole32(IPW_CIPHER_NONE); - DPRINTF(("Setting authmode to %u\n", security.authmode)); - error = ipw_cmd(sc, IPW_CMD_SET_SECURITY_INFO, &security, - sizeof security); - if (error != 0) - return (error); - - if (ic->ic_flags & IEEE80211_F_PRIVACY) { + if (vap->iv_flags & IEEE80211_F_PRIVACY) { error = ipw_setwepkeys(sc); if (error != 0) - return error; + goto done; - if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE) { - data = htole32(ic->ic_crypto.cs_def_txkey); + if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE) { + data = htole32(vap->iv_def_txkey); DPRINTF(("Setting wep tx key index to %u\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_WEP_KEY_INDEX, &data, sizeof data); if (error != 0) - return error; + goto done; } } - data = htole32((ic->ic_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); + data = htole32((vap->iv_flags & IEEE80211_F_PRIVACY) ? IPW_WEPON : 0); DPRINTF(("Setting wep flags to 0x%x\n", le32toh(data))); error = ipw_cmd(sc, IPW_CMD_SET_WEP_FLAGS, &data, sizeof data); if (error != 0) - return error; + goto done; error = ipw_setssid(sc, ni->ni_essid, ni->ni_esslen); if (error != 0) - return (error); + goto done; error = ipw_setbssid(sc, ni->ni_bssid); if (error != 0) - return (error); + goto done; - if (ic->ic_opt_ie != NULL) { - error = ipw_setwpaie(sc, ic->ic_opt_ie, ic->ic_opt_ie_len); + if (vap->iv_appie_assocreq != NULL) { + struct ieee80211_appie *ie = vap->iv_appie_assocreq; + error = ipw_setwpaie(sc, ie->ie_data, ie->ie_len); if (error != 0) - return error; + goto done; } if (ic->ic_opmode == IEEE80211_M_IBSS) { error = ipw_setchannel(sc, ni->ni_chan); if (error != 0) - return (error); + goto done; } /* lock scan to ap's channel and enable associate */ error = ipw_setscanopts(sc, - 1<<(ieee80211_chan2ieee(ic, ni->ni_chan)-1), 0); + 1<<(ieee80211_chan2ieee(ic, ni->ni_chan)-1), 0); + if (error != 0) + goto done; - return ipw_enable(sc); /* finally, enable adapter */ + error = ipw_enable(sc); /* finally, enable adapter */ + if (error == 0) + sc->flags |= IPW_FLAG_ASSOCIATING; +done: + IPW_UNLOCK(sc); } -/* - * Handler for sc_disassoc_task. This is a simple wrapper around - * ipw_disassociate(). - */ static void ipw_disassoc_task(void *context, int pending) { - struct ipw_softc *sc = context; + struct ieee80211vap *vap = context; + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct ieee80211_node *ni = vap->iv_bss; + struct ipw_softc *sc = ifp->if_softc; IPW_LOCK_DECL; IPW_LOCK(sc); - ipw_disassociate(sc); - IPW_UNLOCK(sc); -} - -static int -ipw_disassociate(struct ipw_softc *sc) -{ - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; - DPRINTF(("Disassociate from %6D\n", ni->ni_bssid, ":")); - /* * NB: don't try to do this if ipw_stop_master has * shutdown the firmware and disabled interrupts. */ - if (!(sc->flags & IPW_FLAG_FW_INITED)) - return (0); - - sc->flags &= ~IPW_FLAG_ASSOCIATED; - /* - * NB: firmware currently ignores bssid parameter, but - * supply it in case this changes (follow linux driver). - */ - return ipw_cmd(sc, IPW_CMD_DISASSOCIATE, - ni->ni_bssid, IEEE80211_ADDR_LEN); + if (sc->flags & IPW_FLAG_FW_INITED) { + sc->flags &= ~IPW_FLAG_ASSOCIATED; + /* + * NB: firmware currently ignores bssid parameter, but + * supply it in case this changes (follow linux driver). + */ + (void) ipw_cmd(sc, IPW_CMD_DISASSOCIATE, + ni->ni_bssid, IEEE80211_ADDR_LEN); + } + IPW_UNLOCK(sc); } /* @@ -2496,27 +2394,31 @@ static void ipw_init(void *priv) { struct ipw_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; IPW_LOCK_DECL; IPW_LOCK(sc); - ipw_init_locked(sc, 0); + ipw_init_locked(sc); IPW_UNLOCK(sc); + + ieee80211_start_all(ic); } static void -ipw_init_locked(struct ipw_softc *sc, int force) +ipw_init_locked(struct ipw_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); const struct firmware *fp; const struct ipw_firmware_hdr *hdr; - const char *imagename, *fw; - IPW_LOCK_DECL; + const char *fw; IPW_LOCK_ASSERT(sc); DPRINTF(("%s: state %s flags 0x%x\n", __func__, - ieee80211_state_name[ic->ic_state], sc->flags)); + ieee80211_state_name[vap->iv_state], sc->flags)); /* * Avoid re-entrant calls. We need to release the mutex in ipw_init() @@ -2531,63 +2433,22 @@ ipw_init_locked(struct ipw_softc *sc, int force) if (ipw_reset(sc) != 0) { device_printf(sc->sc_dev, "could not reset adapter\n"); - goto fail1; - } - - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - imagename = "ipw_bss"; - break; - case IEEE80211_M_IBSS: - imagename = "ipw_ibss"; - break; - case IEEE80211_M_MONITOR: - imagename = "ipw_monitor"; - break; - default: - imagename = NULL; /* should not get there */ - } - - /* - * Load firmware image using the firmware(9) subsystem. We need to - * release the driver's lock first. - */ - if (sc->sc_firmware == NULL || strcmp(sc->sc_firmware->name, - imagename) != 0) { - IPW_UNLOCK(sc); - if (sc->sc_firmware != NULL) - firmware_put(sc->sc_firmware, FIRMWARE_UNLOAD); - sc->sc_firmware = firmware_get(imagename); - IPW_LOCK(sc); + goto fail; } if (sc->sc_firmware == NULL) { - device_printf(sc->sc_dev, - "could not load firmware image '%s'\n", imagename); - goto fail1; + device_printf(sc->sc_dev, "no firmware\n"); + goto fail; } - + /* NB: consistency already checked on load */ fp = sc->sc_firmware; - if (fp->datasize < sizeof *hdr) { - device_printf(sc->sc_dev, - "firmware image too short %zu\n", fp->datasize); - goto fail2; - } - hdr = (const struct ipw_firmware_hdr *)fp->data; - if (fp->datasize < sizeof *hdr + le32toh(hdr->mainsz) + - le32toh(hdr->ucodesz)) { - device_printf(sc->sc_dev, - "firmware image too short %zu\n", fp->datasize); - goto fail2; - } - - DPRINTF(("Loading firmware image '%s'\n", imagename)); + DPRINTF(("Loading firmware image '%s'\n", fp->name)); fw = (const char *)fp->data + sizeof *hdr + le32toh(hdr->mainsz); if (ipw_load_ucode(sc, fw, le32toh(hdr->ucodesz)) != 0) { device_printf(sc->sc_dev, "could not load microcode\n"); - goto fail2; + goto fail; } ipw_stop_master(sc); @@ -2615,7 +2476,7 @@ ipw_init_locked(struct ipw_softc *sc, int force) fw = (const char *)fp->data + sizeof *hdr; if (ipw_load_firmware(sc, fw, le32toh(hdr->mainsz)) != 0) { device_printf(sc->sc_dev, "could not load firmware\n"); - goto fail2; + goto fail; } sc->flags |= IPW_FLAG_FW_INITED; @@ -2628,21 +2489,9 @@ ipw_init_locked(struct ipw_softc *sc, int force) if (ipw_config(sc) != 0) { device_printf(sc->sc_dev, "device configuration failed\n"); - goto fail1; + goto fail; } - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - /* - * NB: When restarting the adapter clock the state - * machine regardless of the roaming mode; otherwise - * we need to notify user apps so they can manually - * get us going again. - */ - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL || force) - ieee80211_new_state(ic, IEEE80211_S_SCAN, 0); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - callout_reset(&sc->sc_wdtimer, hz, ipw_watchdog, sc); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; @@ -2650,13 +2499,102 @@ ipw_init_locked(struct ipw_softc *sc, int force) sc->flags &=~ IPW_FLAG_INIT_LOCKED; return; -fail2: firmware_put(fp, FIRMWARE_UNLOAD); - sc->sc_firmware = NULL; -fail1: ifp->if_flags &= ~IFF_UP; +fail: ipw_stop_locked(sc); sc->flags &=~ IPW_FLAG_INIT_LOCKED; } +static int +ipw_config(struct ipw_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ipw_configuration config; + uint32_t data; + int error; + + error = ipw_disable(sc); + if (error != 0) + return error; + + switch (ic->ic_opmode) { + case IEEE80211_M_STA: + case IEEE80211_M_HOSTAP: + case IEEE80211_M_WDS: /* XXX */ + data = htole32(IPW_MODE_BSS); + break; + case IEEE80211_M_IBSS: + case IEEE80211_M_AHDEMO: + data = htole32(IPW_MODE_IBSS); + break; + case IEEE80211_M_MONITOR: + data = htole32(IPW_MODE_MONITOR); + break; + } + DPRINTF(("Setting mode to %u\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_MODE, &data, sizeof data); + if (error != 0) + return error; + + if (ic->ic_opmode == IEEE80211_M_IBSS || + ic->ic_opmode == IEEE80211_M_MONITOR) { + error = ipw_setchannel(sc, ic->ic_curchan); + if (error != 0) + return error; + } + + if (ic->ic_opmode == IEEE80211_M_MONITOR) + return ipw_enable(sc); + + config.flags = htole32(IPW_CFG_BSS_MASK | IPW_CFG_IBSS_MASK | + IPW_CFG_PREAMBLE_AUTO | IPW_CFG_802_1x_ENABLE); + if (ic->ic_opmode == IEEE80211_M_IBSS) + config.flags |= htole32(IPW_CFG_IBSS_AUTO_START); + if (ifp->if_flags & IFF_PROMISC) + config.flags |= htole32(IPW_CFG_PROMISCUOUS); + config.bss_chan = htole32(0x3fff); /* channels 1-14 */ + config.ibss_chan = htole32(0x7ff); /* channels 1-11 */ + DPRINTF(("Setting configuration to 0x%x\n", le32toh(config.flags))); + error = ipw_cmd(sc, IPW_CMD_SET_CONFIGURATION, &config, sizeof config); + if (error != 0) + return error; + + data = htole32(0x3); /* 1, 2 */ + DPRINTF(("Setting basic tx rates to 0x%x\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_BASIC_TX_RATES, &data, sizeof data); + if (error != 0) + return error; + + /* NB: use the same rate set */ + DPRINTF(("Setting msdu tx rates to 0x%x\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_MSDU_TX_RATES, &data, sizeof data); + if (error != 0) + return error; + + data = htole32(0xf); /* 1, 2, 5.5, 11 */ + DPRINTF(("Setting tx rates to 0x%x\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_TX_RATES, &data, sizeof data); + if (error != 0) + return error; + + data = htole32(IPW_POWER_MODE_CAM); + DPRINTF(("Setting power mode to %u\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_POWER_MODE, &data, sizeof data); + if (error != 0) + return error; + + if (ic->ic_opmode == IEEE80211_M_IBSS) { + data = htole32(32); /* default value */ + DPRINTF(("Setting tx power index to %u\n", le32toh(data))); + error = ipw_cmd(sc, IPW_CMD_SET_TX_POWER_INDEX, &data, + sizeof data); + if (error != 0) + return error; + } + + return 0; +} + static void ipw_stop(void *priv) { @@ -2671,14 +2609,11 @@ ipw_stop(void *priv) static void ipw_stop_locked(struct ipw_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; int i; IPW_LOCK_ASSERT(sc); - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - callout_stop(&sc->sc_wdtimer); ipw_stop_master(sc); @@ -2795,7 +2730,7 @@ ipw_scan_start(struct ieee80211com *ic) IPW_LOCK(sc); if (!(sc->flags & IPW_FLAG_SCANNING)) - taskqueue_enqueue_fast(taskqueue_fast, &sc->sc_scan_task); + taskqueue_enqueue(taskqueue_swi, &sc->sc_scan_task); IPW_UNLOCK(sc); } @@ -2816,13 +2751,13 @@ ipw_set_channel(struct ieee80211com *ic) } static void -ipw_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) +ipw_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { /* NB: all channels are scanned at once */ } static void -ipw_scan_mindwell(struct ieee80211com *ic) +ipw_scan_mindwell(struct ieee80211_scan_state *ss) { /* NB: don't try to abort scan; wait for firmware to finish */ } diff --git a/sys/dev/ipw/if_ipwvar.h b/sys/dev/ipw/if_ipwvar.h index f6ec999..de35019 100644 --- a/sys/dev/ipw/if_ipwvar.h +++ b/sys/dev/ipw/if_ipwvar.h @@ -76,30 +76,40 @@ struct ipw_tx_radiotap_header { ((1 << IEEE80211_RADIOTAP_FLAGS) | \ (1 << IEEE80211_RADIOTAP_CHANNEL)) +struct ipw_vap { + struct ieee80211vap vap; + struct task assoc_task; + struct task disassoc_task; + struct task assoc_success_task; + struct task assoc_failed_task; + struct task scandone_task; + + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define IPW_VAP(vap) ((struct ipw_vap *)(vap)) + struct ipw_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); device_t sc_dev; struct mtx sc_mtx; struct task sc_init_task; struct task sc_scan_task; struct task sc_chan_task; - struct task sc_assoc_task; - struct task sc_disassoc_task; + struct task sc_bmiss_task; struct callout sc_wdtimer; /* watchdog timer */ uint32_t flags; -#define IPW_FLAG_FW_INITED (1 << 0) -#define IPW_FLAG_INIT_LOCKED (1 << 1) -#define IPW_FLAG_HAS_RADIO_SWITCH (1 << 2) -#define IPW_FLAG_HACK (1 << 3) -#define IPW_FLAG_SCANNING (1 << 4) -#define IPW_FLAG_ENABLED (1 << 5) -#define IPW_FLAG_BUSY (1 << 6) -#define IPW_FLAG_ASSOCIATED (1 << 7) +#define IPW_FLAG_FW_INITED 0x0001 +#define IPW_FLAG_INIT_LOCKED 0x0002 +#define IPW_FLAG_HAS_RADIO_SWITCH 0x0004 +#define IPW_FLAG_HACK 0x0008 +#define IPW_FLAG_SCANNING 0x0010 +#define IPW_FLAG_ENABLED 0x0020 +#define IPW_FLAG_BUSY 0x0040 +#define IPW_FLAG_ASSOCIATING 0x0080 +#define IPW_FLAG_ASSOCIATED 0x0100 int irq_rid; int mem_rid; @@ -152,22 +162,10 @@ struct ipw_softc { uint32_t rxcur; int txfree; - int dwelltime; - - struct bpf_if *sc_drvbpf; - - union { - struct ipw_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct ipw_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - union { - struct ipw_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct ipw_tx_radiotap_header sc_txtap; int sc_txtap_len; }; diff --git a/sys/dev/iwi/if_iwi.c b/sys/dev/iwi/if_iwi.c index 97dad68..1ddb59b 100644 --- a/sys/dev/iwi/if_iwi.c +++ b/sys/dev/iwi/if_iwi.c @@ -73,6 +73,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -90,6 +91,14 @@ __FBSDID("$FreeBSD$"); #define DPRINTFN(n, x) do { if (iwi_debug >= (n)) printf x; } while (0) int iwi_debug = 0; SYSCTL_INT(_debug, OID_AUTO, iwi, CTLFLAG_RW, &iwi_debug, 0, "iwi debug level"); + +static const char *iwi_fw_states[] = { + "IDLE", /* IWI_FW_IDLE */ + "LOADING", /* IWI_FW_LOADING */ + "ASSOCIATING", /* IWI_FW_ASSOCIATING */ + "DISASSOCIATING", /* IWI_FW_DISASSOCIATING */ + "SCANNING", /* IWI_FW_SCANNING */ +}; #else #define DPRINTF(x) #define DPRINTFN(n, x) @@ -120,6 +129,11 @@ static const struct iwi_ident iwi_ident_table[] = { { 0, 0, NULL } }; +static struct ieee80211vap *iwi_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void iwi_vap_delete(struct ieee80211vap *); static void iwi_dma_map_addr(void *, bus_dma_segment_t *, int, int); static int iwi_alloc_cmd_ring(struct iwi_softc *, struct iwi_cmd_ring *, int); @@ -135,15 +149,17 @@ static void iwi_reset_rx_ring(struct iwi_softc *, struct iwi_rx_ring *); static void iwi_free_rx_ring(struct iwi_softc *, struct iwi_rx_ring *); static struct ieee80211_node *iwi_node_alloc(struct ieee80211_node_table *); static void iwi_node_free(struct ieee80211_node *); -static int iwi_media_change(struct ifnet *); static void iwi_media_status(struct ifnet *, struct ifmediareq *); -static int iwi_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int iwi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void iwi_wme_init(struct iwi_softc *); -static int iwi_wme_setparams(struct iwi_softc *); +static int iwi_wme_setparams(struct iwi_softc *, struct ieee80211com *); static int iwi_wme_update(struct ieee80211com *); static uint16_t iwi_read_prom_word(struct iwi_softc *, uint8_t); static void iwi_frame_intr(struct iwi_softc *, struct iwi_rx_data *, int, struct iwi_frame *); +static void iwi_authsuccess(void *, int); +static void iwi_assocsuccess(void *, int); +static void iwi_assocfailed(void *, int); static void iwi_notification_intr(struct iwi_softc *, struct iwi_notif *); static void iwi_rx_intr(struct iwi_softc *); static void iwi_tx_intr(struct iwi_softc *, struct iwi_tx_ring *); @@ -152,6 +168,9 @@ static int iwi_cmd(struct iwi_softc *, uint8_t, void *, uint8_t); static void iwi_write_ibssnode(struct iwi_softc *, const u_int8_t [], int); static int iwi_tx_start(struct ifnet *, struct mbuf *, struct ieee80211_node *, int); +static int iwi_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); +static void iwi_start_locked(struct ifnet *); static void iwi_start(struct ifnet *); static void iwi_watchdog(void *); static int iwi_ioctl(struct ifnet *, u_long, caddr_t); @@ -161,27 +180,27 @@ static int iwi_load_ucode(struct iwi_softc *, const struct iwi_fw *); static int iwi_load_firmware(struct iwi_softc *, const struct iwi_fw *); static void iwi_release_fw_dma(struct iwi_softc *sc); static int iwi_config(struct iwi_softc *); -static int iwi_get_firmware(struct iwi_softc *); +static int iwi_get_firmware(struct iwi_softc *, enum ieee80211_opmode); static void iwi_put_firmware(struct iwi_softc *); static int iwi_scanchan(struct iwi_softc *, unsigned long, int); static void iwi_scan_start(struct ieee80211com *); static void iwi_scan_end(struct ieee80211com *); static void iwi_scanabort(void *, int); static void iwi_set_channel(struct ieee80211com *); -static void iwi_scan_curchan(struct ieee80211com *, unsigned long maxdwell); +static void iwi_scan_curchan(struct ieee80211_scan_state *, unsigned long maxdwell); #if 0 static void iwi_scan_allchan(struct ieee80211com *, unsigned long maxdwell); #endif -static void iwi_scan_mindwell(struct ieee80211com *); -static void iwi_assoc(struct ieee80211com *ic); -static void iwi_disassoc(struct ieee80211com *); +static void iwi_scan_mindwell(struct ieee80211_scan_state *); static void iwi_ops(void *, int); -static int iwi_queue_cmd(struct iwi_softc *, int); -static int iwi_auth_and_assoc(struct iwi_softc *); +static int iwi_queue_cmd(struct iwi_softc *, int, unsigned long); +static int iwi_auth_and_assoc(struct iwi_softc *, struct ieee80211vap *); static int iwi_disassociate(struct iwi_softc *, int quiet); +static void iwi_init_locked(struct iwi_softc *); static void iwi_init(void *); -static void iwi_init_locked(void *, int); -static void iwi_stop(void *); +static int iwi_init_fw_dma(struct iwi_softc *, int); +static void iwi_stop_locked(void *); +static void iwi_stop(struct iwi_softc *); static void iwi_restart(void *, int); static int iwi_getrfkill(struct iwi_softc *); static void iwi_radio_on(void *, int); @@ -256,18 +275,25 @@ iwi_attach(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); struct ifnet *ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; uint16_t val; - int i, error, bands; + int i, error; + uint8_t bands; sc->sc_dev = dev; + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(dev, "can not if_alloc()\n"); + return ENXIO; + } + ic = ifp->if_l2com; + IWI_LOCK_INIT(sc); IWI_CMD_LOCK_INIT(sc); sc->sc_unr = new_unrhdr(1, IWI_MAX_IBSSNODE-1, &sc->sc_mtx); -#if __FreeBSD_version >= 700000 sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO, taskqueue_thread_enqueue, &sc->sc_tq); taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", @@ -276,22 +302,14 @@ iwi_attach(device_t dev) taskqueue_thread_enqueue, &sc->sc_tq2); taskqueue_start_threads(&sc->sc_tq2, 1, PI_NET, "%s taskq2", device_get_nameunit(dev)); -#else - sc->sc_tq = taskqueue_create("iwi_taskq", M_NOWAIT | M_ZERO, - taskqueue_thread_enqueue, &sc->sc_tq, &sc->sc_tqproc); - kproc_create(taskqueue_thread_loop, &sc->sc_tq, &sc->sc_tqproc, - 0, 0, "%s taskq", device_get_nameunit(dev)); - sc->sc_tq2 = taskqueue_create("iwi_taskq2", M_NOWAIT | M_ZERO, - taskqueue_thread_enqueue, &sc->sc_tq2, &sc->sc_tqproc); - kproc_create(taskqueue_thread_loop, &sc->sc_tq2, &sc->sc_tqproc, - 0, 0, "%s taskq2", device_get_nameunit(dev)); -#endif + TASK_INIT(&sc->sc_radiontask, 0, iwi_radio_on, sc); TASK_INIT(&sc->sc_radiofftask, 0, iwi_radio_off, sc); TASK_INIT(&sc->sc_restarttask, 0, iwi_restart, sc); TASK_INIT(&sc->sc_opstask, 0, iwi_ops, sc); TASK_INIT(&sc->sc_scanaborttask, 0, iwi_scanabort, sc); callout_init_mtx(&sc->sc_wdtimer, &sc->sc_mtx, 0); + callout_init_mtx(&sc->sc_rftimer, &sc->sc_mtx, 0); if (pci_get_powerstate(dev) != PCI_POWERSTATE_D0) { device_printf(dev, "chip is in D%d power mode " @@ -354,12 +372,6 @@ iwi_attach(device_t dev) iwi_wme_init(sc); - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(dev, "can not if_alloc()\n"); - goto fail; - } - ic->ic_ifp = ifp; ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -370,10 +382,9 @@ iwi_attach(device_t dev) ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - ic->ic_wme.wme_update = iwi_wme_update; + ic->ic_ifp = ifp; + ic->ic_opmode = IEEE80211_M_STA; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = @@ -383,7 +394,9 @@ iwi_attach(device_t dev) | IEEE80211_C_SHPREAMBLE /* short preamble supported */ | IEEE80211_C_WPA /* 802.11i */ | IEEE80211_C_WME /* 802.11e */ +#if 0 | IEEE80211_C_BGSCAN /* capable of bg scanning */ +#endif ; /* read MAC address from EEPROM */ @@ -402,28 +415,26 @@ iwi_attach(device_t dev) setbit(&bands, IEEE80211_MODE_11G); if (pci_get_device(dev) >= 0x4223) setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); - ic->ic_bmissthreshold = 10; /* override default */ /* override default methods */ ic->ic_node_alloc = iwi_node_alloc; sc->sc_node_free = ic->ic_node_free; ic->ic_node_free = iwi_node_free; + ic->ic_raw_xmit = iwi_raw_xmit; ic->ic_scan_start = iwi_scan_start; ic->ic_scan_end = iwi_scan_end; ic->ic_set_channel = iwi_set_channel; ic->ic_scan_curchan = iwi_scan_curchan; ic->ic_scan_mindwell = iwi_scan_mindwell; + ic->ic_wme.wme_update = iwi_wme_update; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = iwi_newstate; - ieee80211_media_init(ic, iwi_media_change, iwi_media_status); + ic->ic_vap_create = iwi_vap_create; + ic->ic_vap_delete = iwi_vap_delete; - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); @@ -450,8 +461,9 @@ iwi_attach(device_t dev) ieee80211_announce(ic); return 0; - -fail: iwi_detach(dev); +fail: + /* XXX fix */ + iwi_detach(dev); return ENXIO; } @@ -459,19 +471,18 @@ static int iwi_detach(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; - IWI_LOCK_DECL; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; - if (ifp != NULL) { - IWI_LOCK(sc); - iwi_stop(sc); - IWI_UNLOCK(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); - } + iwi_stop(sc); + + bpfdetach(ifp); + ieee80211_ifdetach(ic); + + /* NB: do early to drain any pending tasks */ + taskqueue_free(sc->sc_tq); + taskqueue_free(sc->sc_tq2); - callout_drain(&sc->sc_wdtimer); iwi_put_firmware(sc); iwi_release_fw_dma(sc); @@ -482,29 +493,81 @@ iwi_detach(device_t dev) iwi_free_tx_ring(sc, &sc->txq[3]); iwi_free_rx_ring(sc, &sc->rxq); - if (sc->irq != NULL) { - bus_teardown_intr(dev, sc->irq, sc->sc_ih); - bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); - } - - if (sc->mem != NULL) - bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); - - if (ifp != NULL) - if_free(ifp); + bus_teardown_intr(dev, sc->irq, sc->sc_ih); + bus_release_resource(dev, SYS_RES_IRQ, sc->irq_rid, sc->irq); - taskqueue_free(sc->sc_tq); - taskqueue_free(sc->sc_tq2); + bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); - if (sc->sc_unr != NULL) - delete_unrhdr(sc->sc_unr); + delete_unrhdr(sc->sc_unr); IWI_LOCK_DESTROY(sc); IWI_CMD_LOCK_DESTROY(sc); + if_free(ifp); + return 0; } +static struct ieee80211vap * +iwi_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ifnet *ifp = ic->ic_ifp; + struct iwi_softc *sc = ifp->if_softc; + struct iwi_vap *ivp; + struct ieee80211vap *vap; + int i; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + /* + * Get firmware image (and possibly dma memory) on mode change. + */ + if (iwi_get_firmware(sc, opmode)) + return NULL; + /* allocate DMA memory for mapping firmware image */ + i = sc->fw_fw.size; + if (sc->fw_boot.size > i) + i = sc->fw_boot.size; + /* XXX do we dma the ucode as well ? */ + if (sc->fw_uc.size > i) + i = sc->fw_uc.size; + if (iwi_init_fw_dma(sc, i)) + return NULL; + + ivp = (struct iwi_vap *) malloc(sizeof(struct iwi_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (ivp == NULL) + return NULL; + vap = &ivp->iwi_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + /* override the default, the setting comes from the linux driver */ + vap->iv_bmissthreshold = 24; + /* override with driver methods */ + ivp->iwi_newstate = vap->iv_newstate; + vap->iv_newstate = iwi_newstate; + + TASK_INIT(&ivp->iwi_authsuccess_task, 0, iwi_authsuccess, vap); + TASK_INIT(&ivp->iwi_assocsuccess_task, 0, iwi_assocsuccess, vap); + TASK_INIT(&ivp->iwi_assocfailed_task, 0, iwi_assocfailed, vap); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, iwi_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +iwi_vap_delete(struct ieee80211vap *vap) +{ + struct iwi_vap *ivp = IWI_VAP(vap); + + ieee80211_vap_detach(vap); + free(ivp, M_80211_VAP); +} + static void iwi_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nseg, int error) { @@ -807,11 +870,8 @@ static int iwi_shutdown(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - IWI_LOCK_DECL; - IWI_LOCK(sc); iwi_stop(sc); - IWI_UNLOCK(sc); iwi_put_firmware(sc); /* ??? XXX */ return 0; @@ -821,11 +881,8 @@ static int iwi_suspend(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - IWI_LOCK_DECL; - IWI_LOCK(sc); iwi_stop(sc); - IWI_UNLOCK(sc); return 0; } @@ -834,20 +891,12 @@ static int iwi_resume(device_t dev) { struct iwi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ic.ic_ifp; - IWI_LOCK_DECL; - - IWI_LOCK(sc); + struct ifnet *ifp = sc->sc_ifp; pci_write_config(dev, 0x41, 0, 1); - if (ifp->if_flags & IFF_UP) { - ifp->if_init(ifp->if_softc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ifp->if_start(ifp); - } - - IWI_UNLOCK(sc); + if (ifp->if_flags & IFF_UP) + iwi_init(sc); return 0; } @@ -882,25 +931,6 @@ iwi_node_free(struct ieee80211_node *ni) sc->sc_node_free(ni); } -static int -iwi_media_change(struct ifnet *ifp) -{ - struct iwi_softc *sc = ifp->if_softc; - int error; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - - error = ieee80211_media_change(ifp); - if (error == ENETRESET && - (ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - iwi_init_locked(sc, 0); - - IWI_UNLOCK(sc); - - return error; -} - /* * Convert h/w rate code to IEEE rate code. */ @@ -931,43 +961,47 @@ iwi_cvtrate(int iwirate) static void iwi_media_status(struct ifnet *ifp, struct ifmediareq *imr) { - struct iwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int rate; - - imr->ifm_status = IFM_AVALID; - imr->ifm_active = IFM_IEEE80211; - if (ic->ic_state == IEEE80211_S_RUN) - imr->ifm_status |= IFM_ACTIVE; + struct ieee80211vap *vap = ifp->if_softc; + struct ieee80211com *ic = vap->iv_ic; + struct iwi_softc *sc = ic->ic_ifp->if_softc; /* read current transmission rate from adapter */ - rate = iwi_cvtrate(CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE)); - imr->ifm_active |= ieee80211_rate2media(ic, rate, ic->ic_curmode); - - if (ic->ic_opmode == IEEE80211_M_IBSS) - imr->ifm_active |= IFM_IEEE80211_ADHOC; - else if (ic->ic_opmode == IEEE80211_M_MONITOR) - imr->ifm_active |= IFM_IEEE80211_MONITOR; + vap->iv_bss->ni_txrate = + iwi_cvtrate(CSR_READ_4(sc, IWI_CSR_CURRENT_TX_RATE)); + ieee80211_media_status(ifp, imr); } static int -iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +iwi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct iwi_vap *ivp = IWI_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - int error = 0; + IWI_LOCK_DECL; DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, - ieee80211_state_name[ic->ic_state], + ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate], sc->flags)); - /* XXX state change race with taskqueue */ switch (nstate) { - case IEEE80211_S_AUTH: - iwi_assoc(ic); + case IEEE80211_S_INIT: + IWI_LOCK(sc); + /* + * NB: don't try to do this if iwi_stop_master has + * shutdown the firmware and disabled interrupts. + */ + if (vap->iv_state == IEEE80211_S_RUN && + (sc->flags & IWI_FLAG_FW_INITED)) + iwi_queue_cmd(sc, IWI_DISASSOC, 1); + IWI_UNLOCK(sc); break; + case IEEE80211_S_AUTH: + iwi_queue_cmd(sc, IWI_AUTH, arg); + return EINPROGRESS; case IEEE80211_S_RUN: - if (ic->ic_opmode == IEEE80211_M_IBSS) { + if (vap->iv_opmode == IEEE80211_M_IBSS && + vap->iv_state == IEEE80211_S_SCAN) { /* * XXX when joining an ibss network we are called * with a SCAN -> RUN transition on scan complete. @@ -976,35 +1010,24 @@ iwi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) * AUTH -> RUN transition and we want to do nothing. * This is all totally bogus and needs to be redone. */ - if (ic->ic_state == IEEE80211_S_SCAN) - iwi_assoc(ic); - } - break; - case IEEE80211_S_INIT: - /* - * NB: don't try to do this if iwi_stop_master has - * shutdown the firmware and disabled interrupts. - */ - if (ic->ic_state == IEEE80211_S_RUN && - (sc->flags & IWI_FLAG_FW_INITED)) - iwi_disassoc(ic); - if (ic->ic_state == IEEE80211_S_SCAN && - (sc->fw_state == IWI_FW_SCANNING)) - ieee80211_cancel_scan(ic); + iwi_queue_cmd(sc, IWI_ASSOC, 0); + return EINPROGRESS; + } break; case IEEE80211_S_ASSOC: /* - * If we are not transitioning from AUTH the resend the - * association request. + * If we are transitioning from AUTH then just wait + * for the ASSOC status to come back from the firmware. + * Otherwise we need to issue the association request. */ - if (ic->ic_state != IEEE80211_S_AUTH) - iwi_assoc(ic); - break; + if (vap->iv_state == IEEE80211_S_AUTH) + break; + iwi_queue_cmd(sc, IWI_ASSOC, arg); + return EINPROGRESS; default: break; } - return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg); - + return ivp->iwi_newstate(vap, nstate, arg); } /* @@ -1055,9 +1078,8 @@ iwi_wme_init(struct iwi_softc *sc) } static int -iwi_wme_setparams(struct iwi_softc *sc) +iwi_wme_setparams(struct iwi_softc *sc, struct ieee80211com *ic) { - struct ieee80211com *ic = &sc->sc_ic; const struct wmeParams *wmep; int ac; @@ -1090,7 +1112,7 @@ iwi_wme_update(struct ieee80211com *ic) * will get sent down to the adapter as part of the * work iwi_auth_and_assoc does. */ - return (iwi_queue_cmd(sc, IWI_SET_WME)); + return iwi_queue_cmd(sc, IWI_SET_WME, 0); } static int @@ -1171,7 +1193,8 @@ iwi_read_prom_word(struct iwi_softc *sc, uint8_t addr) static void iwi_setcurchan(struct iwi_softc *sc, int chan) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; sc->curchan = chan; @@ -1185,8 +1208,8 @@ static void iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, struct iwi_frame *frame) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct mbuf *mnew, *m; struct ieee80211_node *ni; int type, error, framelen; @@ -1261,7 +1284,7 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, m_adj(m, sizeof (struct iwi_hdr) + sizeof (struct iwi_frame)); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct iwi_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; @@ -1269,17 +1292,16 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, tap->wr_antsignal = frame->signal; tap->wr_antenna = frame->antenna; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } IWI_UNLOCK(sc); ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); - - /* send the frame to the 802.11 layer */ - type = ieee80211_input(ic, m, ni, frame->rssi_dbm, 0, 0); - - /* node is no longer needed */ - ieee80211_free_node(ni); + if (ni != NULL) { + type = ieee80211_input(ni, m, frame->rssi_dbm, 0, 0); + ieee80211_free_node(ni); + } else + type = ieee80211_input_all(ic, m, frame->rssi_dbm, 0, 0); IWI_LOCK(sc); if (sc->sc_softled) { @@ -1297,30 +1319,6 @@ iwi_frame_intr(struct iwi_softc *sc, struct iwi_rx_data *data, int i, } } -/* unaligned little endian access */ -#define LE_READ_2(p) \ - ((u_int16_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8))) -#define LE_READ_4(p) \ - ((u_int32_t) \ - ((((const u_int8_t *)(p))[0] ) | \ - (((const u_int8_t *)(p))[1] << 8) | \ - (((const u_int8_t *)(p))[2] << 16) | \ - (((const u_int8_t *)(p))[3] << 24))) - -#define IEEE80211_VERIFY_LENGTH(_len, _minlen) do { \ - if ((_len) < (_minlen)) { \ - return; \ - } \ -} while (0) - -static int __inline -iswmeoui(const u_int8_t *frm) -{ - return frm[1] > 3 && LE_READ_4(frm+2) == ((WME_OUI_TYPE<<24)|WME_OUI); -} - /* * Check for an association response frame to see if QoS * has been negotiated. We parse just enough to figure @@ -1330,7 +1328,8 @@ iswmeoui(const u_int8_t *frm) * done in the driver. */ static void -iwi_checkforqos(struct iwi_softc *sc, const struct ieee80211_frame *wh, int len) +iwi_checkforqos(struct ieee80211vap *vap, + const struct ieee80211_frame *wh, int len) { #define SUBTYPE(wh) ((wh)->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK) const uint8_t *frm, *efrm, *wme; @@ -1362,7 +1361,7 @@ iwi_checkforqos(struct iwi_softc *sc, const struct ieee80211_frame *wh, int len) wme = NULL; while (frm < efrm) { - IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1]); + IEEE80211_VERIFY_LENGTH(efrm - frm, frm[1], return); switch (*frm) { case IEEE80211_ELEMID_VENDOR: if (iswmeoui(frm)) @@ -1372,7 +1371,7 @@ iwi_checkforqos(struct iwi_softc *sc, const struct ieee80211_frame *wh, int len) frm += frm[1] + 2; } - ni = sc->sc_ic.ic_bss; + ni = vap->iv_bss; ni->ni_capinfo = capinfo; ni->ni_associd = associd; if (wme != NULL) @@ -1382,10 +1381,40 @@ iwi_checkforqos(struct iwi_softc *sc, const struct ieee80211_frame *wh, int len) #undef SUBTYPE } +/* + * Task queue callbacks for iwi_notification_intr used to avoid LOR's. + */ + +static void +iwi_authsuccess(void *arg, int npending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_new_state(vap, IEEE80211_S_ASSOC, -1); +} + +static void +iwi_assocsuccess(void *arg, int npending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_new_state(vap, IEEE80211_S_RUN, -1); +} + +static void +iwi_assocfailed(void *arg, int npending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_new_state(vap, IEEE80211_S_SCAN, -1); +} + static void iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct iwi_notif_scan_channel *chan; struct iwi_notif_scan_complete *scan; struct iwi_notif_authentication *auth; @@ -1411,85 +1440,95 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif) IWI_STATE_END(sc, IWI_FW_SCANNING); - if (scan->status == IWI_SCAN_COMPLETED) - ieee80211_scan_next(ic); - + if (scan->status == IWI_SCAN_COMPLETED) { + /* NB: don't need to defer, net80211 does it for us */ + ieee80211_scan_next(vap); + } break; case IWI_NOTIF_TYPE_AUTHENTICATION: auth = (struct iwi_notif_authentication *)(notif + 1); - switch (auth->state) { case IWI_AUTH_SUCCESS: DPRINTFN(2, ("Authentication succeeeded\n")); - ieee80211_node_authorize(ic->ic_bss); - ieee80211_new_state(ic, IEEE80211_S_ASSOC, -1); + taskqueue_enqueue(taskqueue_swi, + &IWI_VAP(vap)->iwi_authsuccess_task); break; - case IWI_AUTH_FAIL: - DPRINTFN(2, ("Authentication failed\n")); + /* + * These are delivered as an unsolicited deauth + * (e.g. due to inactivity) or in response to an + * associate request. + */ sc->flags &= ~IWI_FLAG_ASSOCIATED; - IWI_STATE_END(sc, IWI_FW_ASSOCIATING); - /* XXX */ + if (vap->iv_state != IEEE80211_S_RUN) { + DPRINTFN(2, ("Authentication failed\n")); + vap->iv_stats.is_rx_auth_fail++; + IWI_STATE_END(sc, IWI_FW_ASSOCIATING); + } else { + DPRINTFN(2, ("Deauthenticated\n")); + vap->iv_stats.is_rx_deauth++; + } + taskqueue_enqueue(taskqueue_swi, + &IWI_VAP(vap)->iwi_assocfailed_task); break; - case IWI_AUTH_SENT_1: case IWI_AUTH_RECV_2: case IWI_AUTH_SEQ1_PASS: break; - case IWI_AUTH_SEQ1_FAIL: DPRINTFN(2, ("Initial authentication handshake failed; " "you probably need shared key\n")); + vap->iv_stats.is_rx_auth_fail++; IWI_STATE_END(sc, IWI_FW_ASSOCIATING); /* XXX retry shared key when in auto */ break; - default: device_printf(sc->sc_dev, "unknown authentication state %u\n", auth->state); + break; } break; case IWI_NOTIF_TYPE_ASSOCIATION: assoc = (struct iwi_notif_association *)(notif + 1); - switch (assoc->state) { case IWI_AUTH_SUCCESS: /* re-association, do nothing */ break; - case IWI_ASSOC_SUCCESS: DPRINTFN(2, ("Association succeeded\n")); sc->flags |= IWI_FLAG_ASSOCIATED; IWI_STATE_END(sc, IWI_FW_ASSOCIATING); - iwi_checkforqos(sc, + iwi_checkforqos(vap, (const struct ieee80211_frame *)(assoc+1), le16toh(notif->len) - sizeof(*assoc)); - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + taskqueue_enqueue(taskqueue_swi, + &IWI_VAP(vap)->iwi_assocsuccess_task); break; - case IWI_ASSOC_INIT: + sc->flags &= ~IWI_FLAG_ASSOCIATED; switch (sc->fw_state) { - case IWI_FW_ASSOCIATING: - DPRINTFN(2, ("Association failed\n")); - IWI_STATE_END(sc, IWI_FW_ASSOCIATING); - ieee80211_new_state(ic, - IEEE80211_S_SCAN, -1); - break; + case IWI_FW_ASSOCIATING: + DPRINTFN(2, ("Association failed\n")); + IWI_STATE_END(sc, IWI_FW_ASSOCIATING); + taskqueue_enqueue(taskqueue_swi, + &IWI_VAP(vap)->iwi_assocfailed_task); + break; - case IWI_FW_DISASSOCIATING: - DPRINTFN(2, ("Dissassociated\n")); - IWI_STATE_END(sc, - IWI_FW_DISASSOCIATING); - break; + case IWI_FW_DISASSOCIATING: + DPRINTFN(2, ("Dissassociated\n")); + IWI_STATE_END(sc, IWI_FW_DISASSOCIATING); + vap->iv_stats.is_rx_disassoc++; + taskqueue_enqueue(taskqueue_swi, + &IWI_VAP(vap)->iwi_assocfailed_task); + break; } - sc->flags &= ~IWI_FLAG_ASSOCIATED; break; - default: device_printf(sc->sc_dev, "unknown association state %u\n", assoc->state); + break; } break; @@ -1508,11 +1547,20 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif) * 802.11 layer. * XXX try to roam, drop assoc only on much higher count */ - if (le32toh(beacon->number) >= ic->ic_bmissthreshold) { + if (le32toh(beacon->number) >= vap->iv_bmissthreshold) { DPRINTF(("Beacon miss: %u >= %u\n", le32toh(beacon->number), - ic->ic_bmissthreshold)); - ieee80211_beacon_miss(ic); + vap->iv_bmissthreshold)); + vap->iv_stats.is_beacon_miss++; + /* + * It's pointless to notify the 802.11 layer + * as it'll try to send a probe request (which + * we'll discard) and then timeout and drop us + * into scan state. Instead tell the firmware + * to disassociate and then on completion we'll + * kick the state machine to scan. + */ + iwi_queue_cmd(sc, IWI_DISASSOC, 1); } } break; @@ -1526,6 +1574,7 @@ iwi_notification_intr(struct iwi_softc *sc, struct iwi_notif *notif) default: DPRINTF(("unknown notification type %u flags 0x%x len %u\n", notif->type, notif->flags, le16toh(notif->len))); + break; } } @@ -1575,8 +1624,7 @@ iwi_rx_intr(struct iwi_softc *sc) static void iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct iwi_tx_data *data; uint32_t hw; @@ -1609,7 +1657,7 @@ iwi_tx_intr(struct iwi_softc *sc, struct iwi_tx_ring *txq) if (sc->sc_softled) iwi_led_event(sc, IWI_LED_TX); - iwi_start(ifp); + iwi_start_locked(ifp); } static void @@ -1631,9 +1679,7 @@ iwi_intr(void *arg) if (r & IWI_INTR_FATAL_ERROR) { device_printf(sc->sc_dev, "firmware error\n"); - /* don't restart if the interface isn't up */ - if (sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING) - taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask); + taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask); sc->flags &= ~IWI_FLAG_BUSY; sc->sc_busy_timer = 0; @@ -1734,7 +1780,8 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, int ac) { struct iwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; struct iwi_node *in = (struct iwi_node *)ni; const struct ieee80211_frame *wh; struct ieee80211_key *k; @@ -1756,7 +1803,7 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, if (!ismcast) flags |= IWI_DATA_FLAG_NEED_ACK; - if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) + if (vap->iv_flags & IEEE80211_F_SHPREAMBLE) flags |= IWI_DATA_FLAG_SHPREAMBLE; if (IEEE80211_QOS_HAS_SEQ(wh)) { xflags |= IWI_DATA_XFLAG_QOS; @@ -1769,7 +1816,7 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, * This is only used in IBSS mode where the firmware expect an index * in a h/w table instead of a destination address. */ - if (ic->ic_opmode == IEEE80211_M_IBSS) { + if (vap->iv_opmode == IEEE80211_M_IBSS) { if (!ismcast) { if (in->in_station == -1) { in->in_station = alloc_unr(sc->sc_unr); @@ -1803,7 +1850,7 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, staid = 0; if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1813,12 +1860,12 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct iwi_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data = &txq->data[txq->cur]; @@ -1868,8 +1915,8 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, desc->xflags = xflags; #if 0 - if (ic->ic_flags & IEEE80211_F_PRIVACY) - desc->wep_txkey = ic->ic_crypto.cs_def_txkey; + if (vap->iv_flags & IEEE80211_F_PRIVACY) + desc->wep_txkey = vap->iv_def_txkey; else #endif desc->flags |= IWI_DATA_FLAG_NO_WEP; @@ -1893,99 +1940,70 @@ iwi_tx_start(struct ifnet *ifp, struct mbuf *m0, struct ieee80211_node *ni, return 0; } +static int +iwi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + /* no support; just discard */ + m_freem(m); + ieee80211_free_node(ni); + return 0; +} + static void -iwi_start(struct ifnet *ifp) +iwi_start_locked(struct ifnet *ifp) { struct iwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct mbuf *m0; - struct ether_header *eh; + struct mbuf *m; struct ieee80211_node *ni; int ac; - IWI_LOCK_DECL; - IWI_LOCK(sc); + IWI_LOCK_ASSERT(sc); - if (ic->ic_state != IEEE80211_S_RUN) { - IWI_UNLOCK(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - } for (;;) { - IF_DEQUEUE(&ic->ic_mgtq, m0); - if (m0 == NULL) { - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - if (m0->m_len < sizeof (struct ether_header) && - (m0 = m_pullup(m0, sizeof (struct ether_header))) == NULL) { - ifp->if_oerrors++; - continue; - } - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - ifp->if_oerrors++; - continue; - } - - /* classify mbuf so we can find which tx ring to use */ - if (ieee80211_classify(ic, m0, ni) != 0) { - m_freem(m0); - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - - /* XXX does not belong here */ - /* no QoS encapsulation for EAPOL frames */ - ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ? - M_WME_GETAC(m0) : WME_AC_BE; - - if (sc->txq[ac].queued > IWI_TX_RING_COUNT - 8) { - /* there is no place left in this ring */ - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + ac = M_WME_GETAC(m); + if (sc->txq[ac].queued > IWI_TX_RING_COUNT - 8) { + /* there is no place left in this ring; tail drop */ + /* XXX tail drop */ + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } - BPF_MTAP(ifp, m0); + BPF_MTAP(ifp, m); - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - } else { - ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - /* XXX no way to send mgt frames (yet), discard */ - m_freem(m0); + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { ieee80211_free_node(ni); + ifp->if_oerrors++; continue; } - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (iwi_tx_start(ifp, m0, ni, ac) != 0) { + if (iwi_tx_start(ifp, m, ni, ac) != 0) { ieee80211_free_node(ni); ifp->if_oerrors++; break; } sc->sc_tx_timer = 5; - ic->ic_lastdata = ticks; } +} + +static void +iwi_start(struct ifnet *ifp) +{ + struct iwi_softc *sc = ifp->if_softc; + IWI_LOCK_DECL; + IWI_LOCK(sc); + iwi_start_locked(ifp); IWI_UNLOCK(sc); } @@ -2004,26 +2022,15 @@ iwi_watchdog(void *arg) taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask); } } - if (sc->sc_rfkill_timer > 0) { - if (--sc->sc_rfkill_timer == 0) { - /* - * Check for a change in rfkill state. We get an - * interrupt when a radio is disabled but not when - * it is enabled so we must poll for the latter. - */ - if (!iwi_getrfkill(sc)) - taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask); - else - sc->sc_rfkill_timer = 2; - } - } if (sc->sc_state_timer > 0) { if (--sc->sc_state_timer == 0) { if_printf(ifp, "firmware stuck in state %d, resetting\n", sc->fw_state); taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask); - if (sc->fw_state == IWI_FW_SCANNING) - ieee80211_cancel_scan(&sc->sc_ic); + if (sc->fw_state == IWI_FW_SCANNING) { + struct ieee80211com *ic = ifp->if_l2com; + ieee80211_cancel_scan(TAILQ_FIRST(&ic->ic_vaps)); + } sc->sc_state_timer = 3; } } @@ -2033,61 +2040,43 @@ iwi_watchdog(void *arg) taskqueue_enqueue(sc->sc_tq2, &sc->sc_restarttask); } } - - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); + callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); } static int iwi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct iwi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; IWI_LOCK_DECL; IWI_LOCK(sc); - - /* - * wait until pending iwi_cmd() are completed, to avoid races - * that could cause problems. - */ - while (sc->flags & IWI_FLAG_BUSY) - msleep(sc, &sc->sc_mtx, 0, "iwiioctl", hz); - switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) - iwi_init_locked(sc, 0); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + iwi_init_locked(sc); + startall = 1; + } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - iwi_stop(sc); - else { - /* - * If device was stopped due to rfkill then - * marked down we'll have the polling thread - * running; stop it explicitly. - */ - sc->sc_rfkill_timer = 0; - } + iwi_stop_locked(sc); } break; - + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - iwi_init_locked(sc, 0); - error = 0; + error = ether_ioctl(ifp, cmd, data); + break; } - IWI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } @@ -2221,30 +2210,26 @@ iwi_getfw(struct iwi_fw *fw, const char *fwname, * the boot firmware as "master". */ static int -iwi_get_firmware(struct iwi_softc *sc) +iwi_get_firmware(struct iwi_softc *sc, enum ieee80211_opmode opmode) { - struct ieee80211com *ic = &sc->sc_ic; const struct iwi_firmware_hdr *hdr; const struct firmware *fp; /* invalidate cached firmware on mode change */ - if (sc->fw_mode != ic->ic_opmode) + if (sc->fw_mode != opmode) iwi_put_firmware(sc); - switch (ic->ic_opmode) { + switch (opmode) { case IEEE80211_M_STA: iwi_getfw(&sc->fw_fw, "iwi_bss", &sc->fw_uc, "iwi_ucode_bss"); break; - case IEEE80211_M_IBSS: iwi_getfw(&sc->fw_fw, "iwi_ibss", &sc->fw_uc, "iwi_ucode_ibss"); break; - case IEEE80211_M_MONITOR: iwi_getfw(&sc->fw_fw, "iwi_monitor", &sc->fw_uc, "iwi_ucode_monitor"); break; - default: break; } @@ -2324,7 +2309,7 @@ iwi_get_firmware(struct iwi_softc *sc) sc->fw_boot.size, sc->fw_uc.size, sc->fw_fw.size); #endif - sc->fw_mode = ic->ic_opmode; + sc->fw_mode = opmode; return 0; bad: iwi_put_firmware(sc); @@ -2437,6 +2422,7 @@ iwi_load_firmware(struct iwi_softc *sc, const struct iwi_fw *fw) int ntries, error; IWI_LOCK_ASSERT(sc); + /* copy firmware image to DMA memory */ memcpy(sc->fw_virtaddr, fw->data, fw->size); @@ -2527,12 +2513,11 @@ iwi_load_firmware(struct iwi_softc *sc, const struct iwi_fw *fw) } static int -iwi_setpowermode(struct iwi_softc *sc) +iwi_setpowermode(struct iwi_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; uint32_t data; - if (ic->ic_flags & IEEE80211_F_PMGTON) { + if (vap->iv_flags & IEEE80211_F_PMGTON) { /* XXX set more fine-grained operation */ data = htole32(IWI_POWER_MODE_MAX); } else @@ -2543,15 +2528,14 @@ iwi_setpowermode(struct iwi_softc *sc) } static int -iwi_setwepkeys(struct iwi_softc *sc) +iwi_setwepkeys(struct iwi_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; struct iwi_wep_key wepkey; struct ieee80211_key *wk; int error, i; for (i = 0; i < IEEE80211_WEP_NKID; i++) { - wk = &ic->ic_crypto.cs_nw_keys[i]; + wk = &vap->iv_nw_keys[i]; wepkey.cmd = IWI_WEP_KEY_CMD_SETKEY; wepkey.idx = i; @@ -2571,13 +2555,14 @@ iwi_setwepkeys(struct iwi_softc *sc) static int iwi_config(struct iwi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct iwi_configuration config; struct iwi_rateset rs; struct iwi_txpower power; uint32_t data; int error, i; + IWI_LOCK_ASSERT(sc); IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); @@ -2599,23 +2584,6 @@ iwi_config(struct iwi_softc *sc) error = iwi_cmd(sc, IWI_CMD_SET_CONFIG, &config, sizeof config); if (error != 0) return error; - - error = iwi_setpowermode(sc); - if (error != 0) - return error; - - data = htole32(ic->ic_rtsthreshold); - DPRINTF(("Setting RTS threshold to %u\n", le32toh(data))); - error = iwi_cmd(sc, IWI_CMD_SET_RTS_THRESHOLD, &data, sizeof data); - if (error != 0) - return error; - - data = htole32(ic->ic_fragthreshold); - DPRINTF(("Setting fragmentation threshold to %u\n", le32toh(data))); - error = iwi_cmd(sc, IWI_CMD_SET_FRAG_THRESHOLD, &data, sizeof data); - if (error != 0) - return error; - if (ic->ic_opmode == IEEE80211_M_IBSS) { power.mode = IWI_MODE_11B; power.nchan = 11; @@ -2657,32 +2625,12 @@ iwi_config(struct iwi_softc *sc) if (error != 0) return error; - /* if we have a desired ESSID, set it now */ - if (ic->ic_des_ssid[0].len != 0) { -#ifdef IWI_DEBUG - if (iwi_debug > 0) { - printf("Setting desired ESSID to "); - ieee80211_print_essid(ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - printf("\n"); - } -#endif - error = iwi_cmd(sc, IWI_CMD_SET_ESSID, ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - if (error != 0) - return error; - } - data = htole32(arc4random()); DPRINTF(("Setting initialization vector to %u\n", le32toh(data))); error = iwi_cmd(sc, IWI_CMD_SET_IV, &data, sizeof data); if (error != 0) return error; - error = iwi_setwepkeys(sc); - if (error != 0) - return error; - /* enable adapter */ DPRINTF(("Enabling adapter\n")); return iwi_cmd(sc, IWI_CMD_ENABLE, NULL, 0); @@ -2740,7 +2688,7 @@ iwi_scanchan(struct iwi_softc *sc, unsigned long maxdwell, int mode) } IWI_STATE_BEGIN(sc, IWI_FW_SCANNING); - ic = &sc->sc_ic; + ic = sc->sc_ifp->if_l2com; ss = ic->ic_scan; memset(&scan, 0, sizeof scan); @@ -2864,15 +2812,16 @@ iwi_set_sensitivity(struct iwi_softc *sc, int8_t rssi_dbm) } static int -iwi_auth_and_assoc(struct iwi_softc *sc) +iwi_auth_and_assoc(struct iwi_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = vap->iv_ifp; + struct ieee80211_node *ni = vap->iv_bss; struct iwi_configuration config; struct iwi_associate *assoc = &sc->assoc; struct iwi_rateset rs; uint16_t capinfo; + uint32_t data; int error, mode; IWI_LOCK_ASSERT(sc); @@ -2901,7 +2850,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc) if (mode == IWI_MODE_11G) config.use_protection = 1; config.answer_pbreq = - (ic->ic_opmode == IEEE80211_M_IBSS) ? 1 : 0; + (vap->iv_opmode == IEEE80211_M_IBSS) ? 1 : 0; config.disable_unicast_decryption = 1; config.disable_multicast_decryption = 1; DPRINTF(("Configuring adapter\n")); @@ -2921,6 +2870,22 @@ iwi_auth_and_assoc(struct iwi_softc *sc) if (error != 0) goto done; + error = iwi_setpowermode(sc, vap); + if (error != 0) + goto done; + + data = htole32(vap->iv_rtsthreshold); + DPRINTF(("Setting RTS threshold to %u\n", le32toh(data))); + error = iwi_cmd(sc, IWI_CMD_SET_RTS_THRESHOLD, &data, sizeof data); + if (error != 0) + goto done; + + data = htole32(vap->iv_fragthreshold); + DPRINTF(("Setting fragmentation threshold to %u\n", le32toh(data))); + error = iwi_cmd(sc, IWI_CMD_SET_FRAG_THRESHOLD, &data, sizeof data); + if (error != 0) + goto done; + /* the rate set has already been "negotiated" */ memset(&rs, 0, sizeof rs); rs.mode = mode; @@ -2939,22 +2904,23 @@ iwi_auth_and_assoc(struct iwi_softc *sc) memset(assoc, 0, sizeof *assoc); - if ((ic->ic_flags & IEEE80211_F_WME) && ni->ni_wme_ie != NULL) { + if ((vap->iv_flags & IEEE80211_F_WME) && ni->ni_ies.wme_ie != NULL) { /* NB: don't treat WME setup as failure */ - if (iwi_wme_setparams(sc) == 0 && iwi_wme_setie(sc) == 0) + if (iwi_wme_setparams(sc, ic) == 0 && iwi_wme_setie(sc) == 0) assoc->policy |= htole16(IWI_POLICY_WME); /* XXX complain on failure? */ } - if (ic->ic_opt_ie != NULL) { - DPRINTF(("Setting optional IE (len=%u)\n", ic->ic_opt_ie_len)); - error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ic->ic_opt_ie, - ic->ic_opt_ie_len); + if (vap->iv_appie_wpa != NULL) { + struct ieee80211_appie *ie = vap->iv_appie_wpa; + + DPRINTF(("Setting optional IE (len=%u)\n", ie->ie_len)); + error = iwi_cmd(sc, IWI_CMD_SET_OPTIE, ie->ie_data, ie->ie_len); if (error != 0) goto done; } - error = iwi_set_sensitivity(sc, ni->ni_rssi); + error = iwi_set_sensitivity(sc, ic->ic_node_getrssi(ni)); if (error != 0) goto done; @@ -2964,7 +2930,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc) * NB: do not arrange for shared key auth w/o privacy * (i.e. a wep key); it causes a firmware error. */ - if ((ic->ic_flags & IEEE80211_F_PRIVACY) && + if ((vap->iv_flags & IEEE80211_F_PRIVACY) && ni->ni_authmode == IEEE80211_AUTH_SHARED) { assoc->auth = IWI_AUTH_SHARED; /* @@ -2973,26 +2939,26 @@ iwi_auth_and_assoc(struct iwi_softc *sc) * but if we blindly grab the key the firmware will * barf so avoid it for now. */ - if (ic->ic_crypto.cs_def_txkey != IEEE80211_KEYIX_NONE) - assoc->auth |= ic->ic_crypto.cs_def_txkey << 4; + if (vap->iv_def_txkey != IEEE80211_KEYIX_NONE) + assoc->auth |= vap->iv_def_txkey << 4; - error = iwi_setwepkeys(sc); + error = iwi_setwepkeys(sc, vap); if (error != 0) goto done; } - if (ic->ic_flags & IEEE80211_F_WPA) + if (vap->iv_flags & IEEE80211_F_WPA) assoc->policy |= htole16(IWI_POLICY_WPA); - if (ic->ic_opmode == IEEE80211_M_IBSS && ni->ni_tstamp.tsf == 0) + if (vap->iv_opmode == IEEE80211_M_IBSS && ni->ni_tstamp.tsf == 0) assoc->type = IWI_HC_IBSS_START; else assoc->type = IWI_HC_ASSOC; memcpy(assoc->tstamp, ni->ni_tstamp.data, 8); - if (ic->ic_opmode == IEEE80211_M_IBSS) + if (vap->iv_opmode == IEEE80211_M_IBSS) capinfo = IEEE80211_CAPINFO_IBSS; else capinfo = IEEE80211_CAPINFO_ESS; - if (ic->ic_flags & IEEE80211_F_PRIVACY) + if (vap->iv_flags & IEEE80211_F_PRIVACY) capinfo |= IEEE80211_CAPINFO_PRIVACY; if ((ic->ic_flags & IEEE80211_F_SHPREAMBLE) && IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) @@ -3004,7 +2970,7 @@ iwi_auth_and_assoc(struct iwi_softc *sc) assoc->lintval = htole16(ic->ic_lintval); assoc->intval = htole16(ni->ni_intval); IEEE80211_ADDR_COPY(assoc->bssid, ni->ni_bssid); - if (ic->ic_opmode == IEEE80211_M_IBSS) + if (vap->iv_opmode == IEEE80211_M_IBSS) IEEE80211_ADDR_COPY(assoc->dst, ifp->if_broadcastaddr); else IEEE80211_ADDR_COPY(assoc->dst, ni->ni_bssid); @@ -3046,17 +3012,6 @@ iwi_disassociate(struct iwi_softc *sc, int quiet) return iwi_cmd(sc, IWI_CMD_ASSOCIATE, assoc, sizeof *assoc); } -static void -iwi_init(void *priv) -{ - struct iwi_softc *sc = priv; - IWI_LOCK_DECL; - - IWI_LOCK(sc); - iwi_init_locked(sc, 0); - IWI_UNLOCK(sc); -} - /* * release dma resources for the firmware */ @@ -3118,54 +3073,35 @@ error: } static void -iwi_init_locked(void *priv, int force) +iwi_init_locked(struct iwi_softc *sc) { - struct iwi_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct iwi_rx_data *data; int i; - IWI_LOCK_DECL; IWI_LOCK_ASSERT(sc); + if (sc->fw_state == IWI_FW_LOADING) { device_printf(sc->sc_dev, "%s: already loading\n", __func__); return; /* XXX: condvar? */ } - iwi_stop(sc); + iwi_stop_locked(sc); + IWI_STATE_BEGIN(sc, IWI_FW_LOADING); + taskqueue_unblock(sc->sc_tq); + taskqueue_unblock(sc->sc_tq2); + if (iwi_reset(sc) != 0) { device_printf(sc->sc_dev, "could not reset adapter\n"); goto fail; } - - IWI_UNLOCK(sc); - if (iwi_get_firmware(sc)) { - IWI_LOCK(sc); - goto fail; - } - - /* allocate DMA memory for mapping firmware image */ - i = sc->fw_fw.size; - if (sc->fw_boot.size > i) - i = sc->fw_boot.size; - /* XXX do we dma the ucode as well ? */ - if (sc->fw_uc.size > i) - i = sc->fw_uc.size; - if (iwi_init_fw_dma(sc, i)) { - IWI_LOCK(sc); - goto fail; - } - IWI_LOCK(sc); - if (iwi_load_firmware(sc, &sc->fw_boot) != 0) { device_printf(sc->sc_dev, "could not load boot firmware %s\n", sc->fw_boot.name); goto fail; } - if (iwi_load_ucode(sc, &sc->fw_uc) != 0) { device_printf(sc->sc_dev, "could not load microcode %s\n", sc->fw_uc.name); @@ -3208,50 +3144,58 @@ iwi_init_locked(void *priv, int force) } sc->flags |= IWI_FLAG_FW_INITED; + IWI_STATE_END(sc, IWI_FW_LOADING); + if (iwi_config(sc) != 0) { - device_printf(sc->sc_dev, "device configuration failed\n"); - goto fail; + device_printf(sc->sc_dev, "unable to enable adapter\n"); + goto fail2; } - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - /* - * NB: When restarting the adapter clock the state - * machine regardless of the roaming mode; otherwise - * we need to notify user apps so they can manually - * get us going again. - */ - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL || force) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - callout_reset(&sc->sc_wdtimer, hz, iwi_watchdog, sc); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; - - IWI_STATE_END(sc, IWI_FW_LOADING); return; - -fail: ifp->if_flags &= ~IFF_UP; +fail: IWI_STATE_END(sc, IWI_FW_LOADING); - iwi_stop(sc); - iwi_put_firmware(sc); +fail2: + iwi_stop_locked(sc); } static void -iwi_stop(void *priv) +iwi_init(void *priv) { struct iwi_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + IWI_LOCK_DECL; + + IWI_LOCK(sc); + iwi_init_locked(sc); + IWI_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); +} + +static void +iwi_stop_locked(void *priv) +{ + struct iwi_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; IWI_LOCK_ASSERT(sc); + + ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); + + taskqueue_block(sc->sc_tq); + taskqueue_block(sc->sc_tq2); if (sc->sc_softled) { callout_stop(&sc->sc_ledtimer); sc->sc_blinking = 0; } - callout_stop(&sc->sc_wdtimer); + callout_stop(&sc->sc_rftimer); + iwi_stop_master(sc); CSR_WRITE_4(sc, IWI_CSR_RST, IWI_RST_SOFT_RESET); @@ -3264,31 +3208,33 @@ iwi_stop(void *priv) iwi_reset_tx_ring(sc, &sc->txq[3]); iwi_reset_rx_ring(sc, &sc->rxq); - ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - memset(sc->sc_cmd, 0, sizeof(sc->sc_cmd)); sc->sc_tx_timer = 0; - sc->sc_rfkill_timer = 0; sc->sc_state_timer = 0; sc->sc_busy_timer = 0; sc->flags &= ~(IWI_FLAG_BUSY | IWI_FLAG_ASSOCIATED); sc->fw_state = IWI_FW_IDLE; wakeup(sc); - - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); } static void -iwi_restart(void *arg, int npending) +iwi_stop(struct iwi_softc *sc) { - struct iwi_softc *sc = arg; IWI_LOCK_DECL; IWI_LOCK(sc); - iwi_init_locked(sc, 1); /* NB: force state machine */ + iwi_stop_locked(sc); IWI_UNLOCK(sc); } +static void +iwi_restart(void *arg, int npending) +{ + struct iwi_softc *sc = arg; + + iwi_init(sc); +} + /* * Return whether or not the radio is enabled in hardware * (i.e. the rfkill switch is "off"). @@ -3303,21 +3249,48 @@ static void iwi_radio_on(void *arg, int pending) { struct iwi_softc *sc = arg; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; device_printf(sc->sc_dev, "radio turned on\n"); + iwi_init(sc); + ieee80211_notify_radio(ic, 1); +} + +static void +iwi_rfkill_poll(void *arg) +{ + struct iwi_softc *sc = arg; + + IWI_LOCK_ASSERT(sc); + + /* + * Check for a change in rfkill state. We get an + * interrupt when a radio is disabled but not when + * it is enabled so we must poll for the latter. + */ + if (!iwi_getrfkill(sc)) { + taskqueue_unblock(sc->sc_tq); + taskqueue_enqueue(sc->sc_tq, &sc->sc_radiontask); + return; + } + callout_reset(&sc->sc_rftimer, 2*hz, iwi_rfkill_poll, sc); } static void iwi_radio_off(void *arg, int pending) { struct iwi_softc *sc = arg; + struct ieee80211com *ic = sc->sc_ifp->if_l2com; IWI_LOCK_DECL; device_printf(sc->sc_dev, "radio turned off\n"); + + ieee80211_notify_radio(ic, 0); + IWI_LOCK(sc); - iwi_stop(sc); - sc->sc_rfkill_timer = 2; + iwi_stop_locked(sc); + iwi_rfkill_poll(sc); IWI_UNLOCK(sc); } @@ -3564,22 +3537,37 @@ iwi_ledattach(struct iwi_softc *sc) } static void -iwi_ops(void *arg, int npending) -{ - struct iwi_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; +iwi_ops(void *arg0, int npending) +{ + static const char *opnames[] = { + [IWI_CMD_FREE] = "FREE", + [IWI_SCAN_START] = "SCAN_START", + [IWI_SET_CHANNEL] = "SET_CHANNEL", + [IWI_AUTH] = "AUTH", + [IWI_ASSOC] = "ASSOC", + [IWI_DISASSOC] = "DISASSOC", + [IWI_SCAN_CURCHAN] = "SCAN_CURCHAN", + [IWI_SCAN_ALLCHAN] = "SCAN_ALLCHAN", + [IWI_SET_WME] = "SET_WME", + }; + struct iwi_softc *sc = arg0; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); IWI_LOCK_DECL; int cmd; + unsigned long arg; again: IWI_CMD_LOCK(sc); cmd = sc->sc_cmd[sc->sc_cmd_cur]; - if (cmd == 0) { + if (cmd == IWI_CMD_FREE) { /* No more commands to process */ IWI_CMD_UNLOCK(sc); return; } - sc->sc_cmd[sc->sc_cmd_cur] = 0; /* free the slot */ + arg = sc->sc_arg[sc->sc_cmd_cur]; + sc->sc_cmd[sc->sc_cmd_cur] = IWI_CMD_FREE; /* free the slot */ sc->sc_cmd_cur = (sc->sc_cmd_cur + 1) % IWI_CMD_MAXOPS; IWI_CMD_UNLOCK(sc); @@ -3588,21 +3576,28 @@ again: msleep(sc, &sc->sc_mtx, 0, "iwicmd", hz/10); } - if (!(sc->sc_ifp->if_drv_flags & IFF_DRV_RUNNING)) { + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { IWI_UNLOCK(sc); return; } + DPRINTF(("%s: %s arg %lu\n", __func__, opnames[cmd], arg)); switch (cmd) { + case IWI_AUTH: case IWI_ASSOC: - iwi_auth_and_assoc(sc); + if (cmd == IWI_AUTH) + vap->iv_state = IEEE80211_S_AUTH; + else + vap->iv_state = IEEE80211_S_ASSOC; + iwi_auth_and_assoc(sc, vap); + /* NB: completion done in iwi_notification_intr */ break; case IWI_DISASSOC: iwi_disassociate(sc, 0); break; case IWI_SET_WME: - if (ic->ic_state == IEEE80211_S_RUN) - (void) iwi_wme_setparams(sc); + if (vap->iv_state == IEEE80211_S_RUN) + (void) iwi_wme_setparams(sc, ic); break; case IWI_SCAN_START: sc->flags |= IWI_FLAG_CHANNEL_SCAN; @@ -3614,9 +3609,8 @@ again: __func__)); goto done; } - if (iwi_scanchan(sc, sc->sc_maxdwell, cmd)) - ieee80211_cancel_scan(ic); - + if (iwi_scanchan(sc, arg, cmd)) + ieee80211_cancel_scan(vap); break; } done: @@ -3627,7 +3621,7 @@ done: } static int -iwi_queue_cmd(struct iwi_softc *sc, int cmd) +iwi_queue_cmd(struct iwi_softc *sc, int cmd, unsigned long arg) { IWI_CMD_LOCK(sc); if (sc->sc_cmd[sc->sc_cmd_next] != 0) { @@ -3637,6 +3631,7 @@ iwi_queue_cmd(struct iwi_softc *sc, int cmd) } sc->sc_cmd[sc->sc_cmd_next] = cmd; + sc->sc_arg[sc->sc_cmd_next] = arg; sc->sc_cmd_next = (sc->sc_cmd_next + 1) % IWI_CMD_MAXOPS; taskqueue_enqueue(sc->sc_tq, &sc->sc_opstask); IWI_CMD_UNLOCK(sc); @@ -3649,7 +3644,7 @@ iwi_scan_start(struct ieee80211com *ic) struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - iwi_queue_cmd(sc, IWI_SCAN_START); + iwi_queue_cmd(sc, IWI_SCAN_START, 0); } static void @@ -3662,13 +3657,13 @@ iwi_set_channel(struct ieee80211com *ic) } static void -iwi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) +iwi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { - struct ifnet *ifp = ic->ic_ifp; + struct ieee80211vap *vap = ss->ss_vap; + struct ifnet *ifp = vap->iv_ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_maxdwell = maxdwell; - iwi_queue_cmd(sc, IWI_SCAN_CURCHAN); + iwi_queue_cmd(sc, IWI_SCAN_CURCHAN, maxdwell); } #if 0 @@ -3678,13 +3673,12 @@ iwi_scan_allchan(struct ieee80211com *ic, unsigned long maxdwell) struct ifnet *ifp = ic->ic_ifp; struct iwi_softc *sc = ifp->if_softc; - sc->sc_maxdwell = maxdwell; - iwi_queue_cmd(sc, IWI_SCAN_ALLCHAN); + iwi_queue_cmd(sc, IWI_SCAN_ALLCHAN, maxdwell); } #endif static void -iwi_scan_mindwell(struct ieee80211com *ic) +iwi_scan_mindwell(struct ieee80211_scan_state *ss) { /* NB: don't try to abort scan; wait for firmware to finish */ } @@ -3697,25 +3691,3 @@ iwi_scan_end(struct ieee80211com *ic) taskqueue_enqueue(sc->sc_tq2, &sc->sc_scanaborttask); } - -static void -iwi_assoc(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; - - /* The firmware will fail if we are already associated */ - if (sc->flags & IWI_FLAG_ASSOCIATED) - iwi_disassoc(ic); - - iwi_queue_cmd(sc, IWI_ASSOC); -} - -static void -iwi_disassoc(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct iwi_softc *sc = ifp->if_softc; - - iwi_queue_cmd(sc, IWI_DISASSOC); -} diff --git a/sys/dev/iwi/if_iwivar.h b/sys/dev/iwi/if_iwivar.h index fca0b7a..abc6f9c 100644 --- a/sys/dev/iwi/if_iwivar.h +++ b/sys/dev/iwi/if_iwivar.h @@ -114,11 +114,19 @@ struct iwi_fw { const char *name; /* associated image name */ }; +struct iwi_vap { + struct ieee80211vap iwi_vap; + struct task iwi_authsuccess_task; + struct task iwi_assocsuccess_task; + struct task iwi_assocfailed_task; + + int (*iwi_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define IWI_VAP(vap) ((struct iwi_vap *)(vap)) + struct iwi_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); void (*sc_node_free)(struct ieee80211_node *); device_t sc_dev; @@ -129,9 +137,6 @@ struct iwi_softc { struct unrhdr *sc_unr; struct taskqueue *sc_tq; /* private task queue */ struct taskqueue *sc_tq2; /* reset task queue */ -#if __FreeBSD_version < 700000 - struct proc *sc_tqproc; -#endif uint32_t flags; #define IWI_FLAG_FW_INITED (1 << 0) @@ -208,39 +213,31 @@ struct iwi_softc { u_int16_t sc_ledoff; /* off time for current blink */ struct callout sc_ledtimer; /* led off timer */ struct callout sc_wdtimer; /* watchdog timer */ + struct callout sc_rftimer; /* rfkill timer */ int sc_tx_timer; - int sc_rfkill_timer;/* poll for rfkill change */ int sc_state_timer; /* firmware state timer */ int sc_busy_timer; /* firmware cmd timer */ -#define IWI_SCAN_START (1 << 0) -#define IWI_SET_CHANNEL (1 << 1) -#define IWI_SCAN_END (1 << 2) -#define IWI_ASSOC (1 << 3) -#define IWI_DISASSOC (1 << 4) -#define IWI_SCAN_CURCHAN (1 << 5) -#define IWI_SCAN_ALLCHAN (1 << 6) -#define IWI_SET_WME (1 << 7) #define IWI_CMD_MAXOPS 10 - int sc_cmd[IWI_CMD_MAXOPS]; - int sc_cmd_cur; /* current queued scan task */ - int sc_cmd_next; /* last queued scan task */ - unsigned long sc_maxdwell; /* max dwell time for curchan */ - struct bpf_if *sc_drvbpf; + int sc_cmd[IWI_CMD_MAXOPS]; + unsigned long sc_arg[IWI_CMD_MAXOPS]; + int sc_cmd_cur; /* current queued scan task */ + int sc_cmd_next; /* last queued scan task */ +#define IWI_CMD_FREE 0 /* for marking slots unused */ +#define IWI_SCAN_START 1 +#define IWI_SET_CHANNEL 2 +#define IWI_AUTH 3 +#define IWI_ASSOC 4 +#define IWI_DISASSOC 5 +#define IWI_SCAN_CURCHAN 6 +#define IWI_SCAN_ALLCHAN 7 +#define IWI_SET_WME 8 - union { - struct iwi_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct iwi_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - union { - struct iwi_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct iwi_tx_radiotap_header sc_txtap; int sc_txtap_len; }; @@ -249,15 +246,15 @@ struct iwi_softc { ("iwi firmware not idle")); \ _sc->fw_state = _state; \ _sc->sc_state_timer = 5; \ - DPRINTF(("enter FW state %d\n", _state)); \ + DPRINTF(("enter %s state\n", iwi_fw_states[_state])); \ } while (0) #define IWI_STATE_END(_sc, _state) do { \ if (_sc->fw_state == _state) \ - DPRINTF(("exit FW state %d\n", _state)); \ + DPRINTF(("exit %s state\n", iwi_fw_states[_state])); \ else \ - DPRINTF(("expected FW state %d, got %d\n", \ - _state, _sc->fw_state)); \ + DPRINTF(("expected %s state, got %s\n", \ + iwi_fw_states[_state], iwi_fw_states[_sc->fw_state])); \ _sc->fw_state = IWI_FW_IDLE; \ wakeup(_sc); \ _sc->sc_state_timer = 0; \ diff --git a/sys/dev/malo/if_malo.c b/sys/dev/malo/if_malo.c index a1a6285..8e70f40 100644 --- a/sys/dev/malo/if_malo.c +++ b/sys/dev/malo/if_malo.c @@ -34,6 +34,8 @@ __FBSDID("$FreeBSD$"); #endif +#include "opt_malo.h" + #include #include #include @@ -123,6 +125,11 @@ enum { MALLOC_DEFINE(M_MALODEV, "malodev", "malo driver dma buffers"); +static struct ieee80211vap *malo_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void malo_vap_delete(struct ieee80211vap *); static int malo_dma_setup(struct malo_softc *); static int malo_setup_hwdma(struct malo_softc *); static void malo_txq_init(struct malo_softc *, struct malo_txq *, int); @@ -131,13 +138,12 @@ static void malo_start(struct ifnet *); static void malo_watchdog(struct ifnet *); static int malo_ioctl(struct ifnet *, u_long, caddr_t); static void malo_updateslot(struct ifnet *); -static int malo_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int malo_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void malo_scan_start(struct ieee80211com *); static void malo_scan_end(struct ieee80211com *); static void malo_set_channel(struct ieee80211com *); static int malo_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static int malo_media_change(struct ifnet *); static void malo_bpfattach(struct malo_softc *); static void malo_sysctlattach(struct malo_softc *); static void malo_announce(struct malo_softc *); @@ -163,7 +169,7 @@ malo_bar0_read4(struct malo_softc *sc, bus_size_t off) static void malo_bar0_write4(struct malo_softc *sc, bus_size_t off, uint32_t val) { - DPRINTF(sc, MALO_DEBUG_FW, "%s: off 0x%x val 0x%x\n", + DPRINTF(sc, MALO_DEBUG_FW, "%s: off 0x%zx val 0x%x\n", __func__, off, val); bus_space_write_4(sc->malo_io0t, sc->malo_io0h, off, val); @@ -178,17 +184,18 @@ malo_bar1_read1(struct malo_softc *sc, bus_size_t off) int malo_attach(uint16_t devid, struct malo_softc *sc) { - int error, i; - struct ieee80211com *ic = &sc->malo_ic; + int error; + struct ieee80211com *ic; struct ifnet *ifp; struct malo_hal *mh; uint8_t bands; - ifp = sc->malo_ifp = if_alloc(IFT_ETHER); + ifp = sc->malo_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(sc->malo_dev, "can not if_alloc()\n"); return ENOSPC; } + ic = ifp->if_l2com; MALO_LOCK_INIT(sc); @@ -215,6 +222,45 @@ malo_attach(uint16_t devid, struct malo_softc *sc) } sc->malo_mh = mh; + /* + * Load firmware so we can get setup. We arbitrarily pick station + * firmware; we'll re-load firmware as needed so setting up + * the wrong mode isn't a big deal. + */ + error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m"); + if (error != 0) { + if_printf(ifp, "unable to setup firmware\n"); + goto bad1; + } + /* XXX gethwspecs() extracts correct informations? not maybe! */ + error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs); + if (error != 0) { + if_printf(ifp, "unable to fetch h/w specs\n"); + goto bad1; + } + + DPRINTF(sc, MALO_DEBUG_FW, + "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x" + "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x" + "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x" + "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x" + "ul_fw_awakecookie 0x%x w[4] = %x %x %x %x", + sc->malo_hwspecs.hwversion, + sc->malo_hwspecs.hostinterface, sc->malo_hwspecs.maxnum_wcb, + sc->malo_hwspecs.maxnum_mcaddr, sc->malo_hwspecs.maxnum_tx_wcb, + sc->malo_hwspecs.regioncode, sc->malo_hwspecs.num_antenna, + sc->malo_hwspecs.fw_releasenum, sc->malo_hwspecs.wcbbase0, + sc->malo_hwspecs.rxdesc_read, sc->malo_hwspecs.rxdesc_write, + sc->malo_hwspecs.ul_fw_awakecookie, + sc->malo_hwspecs.wcbbase[0], sc->malo_hwspecs.wcbbase[1], + sc->malo_hwspecs.wcbbase[2], sc->malo_hwspecs.wcbbase[3]); + + /* NB: firmware looks that it does not export regdomain info API. */ + bands = 0; + setbit(&bands, IEEE80211_MODE_11B); + setbit(&bands, IEEE80211_MODE_11G); + ieee80211_init_channels(ic, NULL, &bands); + sc->malo_txantenna = 0x2; /* h/w default */ sc->malo_rxantenna = 0xffff; /* h/w default */ @@ -228,6 +274,9 @@ malo_attach(uint16_t devid, struct malo_softc *sc) if_printf(ifp, "failed to setup descriptors: %d\n", error); goto bad1; } + error = malo_setup_hwdma(sc); /* push to firmware */ + if (error != 0) /* NB: malo_setupdma prints msg */ + goto bad1; sc->malo_tq = taskqueue_create_fast("malo_taskq", M_NOWAIT, taskqueue_thread_enqueue, &sc->malo_tq); @@ -247,12 +296,6 @@ malo_attach(uint16_t devid, struct malo_softc *sc) ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - /* NB: firmware looks that it does not export regdomain info API. */ - bands = 0; - setbit(&bands, IEEE80211_MODE_11B); - setbit(&bands, IEEE80211_MODE_11G); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); - ic->ic_ifp = ifp; /* XXX not right but it's not used anywhere important */ ic->ic_phytype = IEEE80211_T_OFDM; @@ -273,24 +316,23 @@ malo_attach(uint16_t devid, struct malo_softc *sc) * packets so we can add it efficiently. */ ic->ic_headroom = sizeof(struct malo_txrec) - - sizeof(struct ieee80211_frame); + sizeof(struct ieee80211_frame); + + /* get mac address from hardware */ + IEEE80211_ADDR_COPY(ic->ic_myaddr, sc->malo_hwspecs.macaddr); /* call MI attach routine. */ ieee80211_ifattach(ic); /* override default methods */ - ic->ic_updateslot = malo_updateslot; + ic->ic_vap_create = malo_vap_create; + ic->ic_vap_delete = malo_vap_delete; ic->ic_raw_xmit = malo_raw_xmit; - - sc->malo_newstate = ic->ic_newstate; - ic->ic_newstate = malo_newstate; + ic->ic_updateslot = malo_updateslot; ic->ic_scan_start = malo_scan_start; ic->ic_scan_end = malo_scan_end; ic->ic_set_channel = malo_set_channel; - /* complete initialization */ - ieee80211_media_init(ic, malo_media_change, ieee80211_media_status); - sc->malo_invalid = 0; /* ready to go, enable int handling */ malo_bpfattach(sc); @@ -302,6 +344,7 @@ malo_attach(uint16_t devid, struct malo_softc *sc) if (bootverbose) ieee80211_announce(ic); + malo_announce(sc); return 0; bad1: @@ -313,6 +356,61 @@ bad: return error; } +static struct ieee80211vap * +malo_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ifnet *ifp = ic->ic_ifp; + struct malo_vap *mvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) { + if_printf(ifp, "multiple vaps not supported\n"); + return NULL; + } + switch (opmode) { + case IEEE80211_M_STA: + if (opmode == IEEE80211_M_STA) + flags |= IEEE80211_CLONE_NOBEACONS; + /* fall thru... */ + case IEEE80211_M_MONITOR: + break; + default: + if_printf(ifp, "%s mode not supported\n", + ieee80211_opmode_name[opmode]); + return NULL; /* unsupported */ + } + mvp = (struct malo_vap *) malloc(sizeof(struct malo_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (mvp == NULL) { + if_printf(ifp, "cannot allocate vap state block\n"); + return NULL; + } + vap = &mvp->malo_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + + /* override state transition machine */ + mvp->malo_newstate = vap->iv_newstate; + vap->iv_newstate = malo_newstate; + + /* complete setup */ + ieee80211_vap_attach(vap, + ieee80211_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +malo_vap_delete(struct ieee80211vap *vap) +{ + struct malo_vap *mvp = MALO_VAP(vap); + + ieee80211_vap_detach(vap); + free(mvp, M_80211_VAP); +} + int malo_intr(void *arg) { @@ -353,14 +451,12 @@ malo_intr(void *arg) /* TKIP ICV error */ sc->malo_stats.mst_rx_badtkipicv++; } - #ifdef MALO_DEBUG if (((status | sc->malo_imask) ^ sc->malo_imask) != 0) DPRINTF(sc, MALO_DEBUG_INTR, "%s: can't handle interrupt status 0x%x\n", __func__, status); #endif - return (FILTER_HANDLED); } @@ -1009,8 +1105,8 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, int error, ismcast, iswep; int copyhdrlen, hdrlen, pktlen; struct ieee80211_frame *wh; - struct ieee80211com *ic = &sc->malo_ic; struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct malo_txdesc *ds; struct malo_txrec *tr; struct malo_txq *txq; @@ -1045,7 +1141,7 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, * ExtIV filled in for CCMP and this also adjusts * the headers which simplifies our work below. */ - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { /* * This can happen when the key is yanked after the @@ -1068,15 +1164,14 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(sc->malo_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { sc->malo_tx_th.wt_flags = 0; /* XXX */ if (iswep) sc->malo_tx_th.wt_flags |= IEEE80211_RADIOTAP_F_WEP; sc->malo_tx_th.wt_txpower = ni->ni_txpower; sc->malo_tx_th.wt_antenna = sc->malo_txantenna; - bpf_mtap2(sc->malo_drvbpf, - &sc->malo_tx_th, sc->malo_tx_th_len, m0); + bpf_mtap2(ifp->if_bpf, &sc->malo_tx_th, sc->malo_tx_th_len, m0); } /* @@ -1186,137 +1281,40 @@ malo_tx_start(struct malo_softc *sc, struct ieee80211_node *ni, static void malo_start(struct ifnet *ifp) { - int nqueued = 0; - struct ether_header *eh; struct malo_softc *sc = ifp->if_softc; - struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct ieee80211com *ic = &sc->malo_ic; + struct malo_txq *txq = &sc->malo_txq[0]; struct malo_txbuf *bf = NULL; - struct malo_txq *txq = NULL; struct mbuf *m; + int nqueued = 0; if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0 || sc->malo_invalid) return; for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + bf = malo_getbuf(sc, txq); + if (bf == NULL) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + + /* XXX blocks other traffic */ + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + sc->malo_stats.mst_tx_qstop++; + break; + } /* - * Poll the management queue for frames; they - * have priority over normal data frames. + * Encapsulate the packet in prep for transmission. */ - IF_DEQUEUE(&ic->ic_mgtq, m); + m = ieee80211_encap(ni, m); if (m == NULL) { - /* - * No data frames go out unless we're associated. - */ - if (ic->ic_state != IEEE80211_S_RUN) { - DPRINTF(sc, MALO_DEBUG_XMIT, - "%s: discard data packet, state %s\n", - __func__, - ieee80211_state_name[ic->ic_state]); - sc->malo_stats.mst_tx_discard++; - break; - } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m); - if (m == NULL) - break; - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - /* - * Find the node for the destination so we can do - * things like power save and fast frames aggregation. - */ - if (m->m_len < sizeof(struct ether_header) && - (m = m_pullup(m, sizeof(struct ether_header))) == - NULL) { - ic->ic_stats.is_tx_nobuf++; /* XXX */ - ni = NULL; - goto bad; - } - eh = mtod(m, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - /* NB: ieee80211_find_txnode does stat+msg */ - m_freem(m); - goto bad; - } - /* calculate priority so we can find the tx queue */ - if (ieee80211_classify(ic, m, ni)) { - DPRINTF(sc, MALO_DEBUG_XMIT, - "%s: discard, classification failure\n", - __func__); - m_freem(m); - goto bad; - } - - txq = &sc->malo_txq[0]; - - bf = malo_getbuf(sc, txq); - if (bf == NULL) { - IFQ_DRV_PREPEND(&ifp->if_snd, m); - ieee80211_free_node(ni); - - /* XXX blocks other traffic */ - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->malo_stats.mst_tx_qstop++; - break; - } - ifp->if_opackets++; - - if (bpf_peers_present(ifp->if_bpf)) - bpf_mtap(ifp->if_bpf, m); - - /* - * Encapsulate the packet in prep for transmission. - */ - m = ieee80211_encap(ic, m, ni); - if (m == NULL) { - DPRINTF(sc, MALO_DEBUG_XMIT, - "%s: encapsulation failure\n", __func__); - sc->malo_stats.mst_tx_encap++; - goto bad; - } - } else { - /* - * Grab a TX buffer and associated resources. - * Note that we depend on the classification - * by the 802.11 layer to get to the right h/w - * queue. Management frames must ALWAYS go on - * queue 1 but we cannot just force that here - * because we may receive non-mgt frames through - * the ic_mgtq (e.g. null data frames). - */ - txq = &sc->malo_txq[0]; - bf = malo_getbuf(sc, txq); - if (bf == NULL) { - IF_PREPEND(&ic->ic_mgtq, m); - /* XXX stat */ - break; - } - - /* - * Hack! The referenced node pointer is in the - * rcvif field of the packet header. This is - * placed there by ieee80211_mgmt_output because - * we need to hold the reference with the frame - * and there's no other way (other than packet - * tags which we consider too expensive to use) - * to pass it along. - */ - ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; - m->m_pkthdr.rcvif = NULL; - - wh = mtod(m, struct ieee80211_frame *); - sc->malo_stats.mst_tx_mgmt++; - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m); + DPRINTF(sc, MALO_DEBUG_XMIT, + "%s: encapsulation failure\n", __func__); + sc->malo_stats.mst_tx_encap++; + goto bad; } - /* * Pass the frame to the h/w for transmission. */ @@ -1382,7 +1380,8 @@ static int malo_hal_reset(struct malo_softc *sc) { static int first = 0; - struct ieee80211com *ic = &sc->malo_ic; + struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct malo_hal *mh = sc->malo_mh; if (first == 0) { @@ -1511,10 +1510,8 @@ malo_startrecv(struct malo_softc *sc) } static void -malo_init(void *arg) +malo_init_locked(struct malo_softc *sc) { - struct malo_softc *sc = (struct malo_softc *) arg; - struct ieee80211com *ic = &sc->malo_ic; struct ifnet *ifp = sc->malo_ifp; struct malo_hal *mh = sc->malo_mh; int error; @@ -1522,56 +1519,7 @@ malo_init(void *arg) DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n", __func__, ifp->if_flags); - if (!sc->malo_fw_loaded) { - /* - * Load firmware so we can get setup. - */ - error = malo_hal_fwload(mh, "malo8335-h", "malo8335-m"); - if (error != 0) { - if_printf(ifp, "unable to setup firmware\n"); - return; - } - /* XXX gethwspecs() extracts correct informations? not maybe! */ - error = malo_hal_gethwspecs(mh, &sc->malo_hwspecs); - if (error != 0) { - if_printf(ifp, "unable to fetch h/w specs\n"); - return; - } - - DPRINTF(sc, MALO_DEBUG_FW, - "malo_hal_gethwspecs: hwversion 0x%x hostif 0x%x" - "maxnum_wcb 0x%x maxnum_mcaddr 0x%x maxnum_tx_wcb 0x%x" - "regioncode 0x%x num_antenna 0x%x fw_releasenum 0x%x" - "wcbbase0 0x%x rxdesc_read 0x%x rxdesc_write 0x%x" - "ul_fw_awakecookie 0x%x w[4] = %x %x %x %x", - sc->malo_hwspecs.hwversion, - sc->malo_hwspecs.hostinterface, sc->malo_hwspecs.maxnum_wcb, - sc->malo_hwspecs.maxnum_mcaddr, - sc->malo_hwspecs.maxnum_tx_wcb, - sc->malo_hwspecs.regioncode, sc->malo_hwspecs.num_antenna, - sc->malo_hwspecs.fw_releasenum, sc->malo_hwspecs.wcbbase0, - sc->malo_hwspecs.rxdesc_read, sc->malo_hwspecs.rxdesc_write, - sc->malo_hwspecs.ul_fw_awakecookie, - sc->malo_hwspecs.wcbbase[0], sc->malo_hwspecs.wcbbase[1], - sc->malo_hwspecs.wcbbase[2], sc->malo_hwspecs.wcbbase[3]); - - error = malo_setup_hwdma(sc); /* push to firmware */ - /* NB: malo_setupdma prints msg */ - if (error != 0) { - if_printf(ifp, "%s: failed to set up h/w dma\n", - __func__); - return; - } - - /* set reddomain. */ - ic->ic_regdomain = sc->malo_hwspecs.regioncode; - - malo_announce(sc); - - sc->malo_fw_loaded = 1; - } - - MALO_LOCK(sc); + MALO_LOCK_ASSERT(sc); /* * Stop anything previously setup. This is safe whether this is @@ -1584,7 +1532,7 @@ malo_init(void *arg) */ if (!malo_hal_reset(sc)) { if_printf(ifp, "%s: unable to reset hardware\n", __func__); - goto done; + return; } /* @@ -1594,7 +1542,7 @@ malo_init(void *arg) if (error != 0) { if_printf(ifp, "%s: unable to start recv logic, error %d\n", __func__, error); - goto done; + return; } /* @@ -1610,30 +1558,26 @@ malo_init(void *arg) | MALO_A2HRIC_BIT_CHAN_SWITCH; ifp->if_drv_flags |= IFF_DRV_RUNNING; - ic->ic_state = IEEE80211_S_INIT; - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - malo_hal_intrset(mh, sc->malo_imask); +} - /* - * The hardware should be ready to go now so it's safe to kick - * the 802.11 state machine as it's likely to immediately call back - * to us to send mgmt frames. - */ - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); +static void +malo_init(void *arg) +{ + struct malo_softc *sc = (struct malo_softc *) arg; + struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags 0x%x\n", + __func__, ifp->if_flags); -done: - if (error != 0) - if_printf(ifp, - "error(%d) occurred during the initializing.\n", error); + MALO_LOCK(sc); + malo_init_locked(sc); MALO_UNLOCK(sc); - return; + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ } /* @@ -1642,9 +1586,9 @@ done: static void malo_setmcastfilter(struct malo_softc *sc) { - struct ieee80211com *ic = &sc->malo_ic; - struct ifmultiaddr *ifma; struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ifmultiaddr *ifma; uint8_t macs[IEEE80211_ADDR_LEN * MALO_HAL_MCAST_MAX]; uint8_t *mp; int nmc; @@ -1686,8 +1630,8 @@ all: static int malo_mode_init(struct malo_softc *sc) { - struct ieee80211com *ic = &sc->malo_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct malo_hal *mh = sc->malo_mh; /* @@ -1733,11 +1677,12 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq) MALO_TXQ_UNLOCK(txq); #ifdef MALO_DEBUG if (sc->malo_debug & MALO_DEBUG_RESET) { + struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct malo_txrec *tr = mtod(bf->bf_m, const struct malo_txrec *); malo_printtxbuf(bf, txq->qnum, ix); - ieee80211_dump_pkt(&sc->malo_ic, - (const uint8_t *)&tr->wh, + ieee80211_dump_pkt(ic, (const uint8_t *)&tr->wh, bf->bf_m->m_len - sizeof(tr->fwlen), 0, -1); } #endif /* MALO_DEBUG */ @@ -1763,10 +1708,9 @@ malo_tx_draintxq(struct malo_softc *sc, struct malo_txq *txq) static void malo_stop_locked(struct ifnet *ifp, int disable) { - int i; struct malo_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->malo_ic; struct malo_hal *mh = sc->malo_mh; + int i; DPRINTF(sc, MALO_DEBUG_ANY, "%s: invalid %u if_flags 0x%x\n", __func__, sc->malo_invalid, ifp->if_flags); @@ -1778,28 +1722,19 @@ malo_stop_locked(struct ifnet *ifp, int disable) /* * Shutdown the hardware and driver: - * reset 802.11 state machine - * turn off timers * disable interrupts * turn off the radio - * clear transmit machinery - * clear receive machinery * drain and release tx queues - * reclaim beacon resources - * power down hardware * * Note that some of this work is not possible if the hardware * is gone (invalid). */ - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); ifp->if_drv_flags &= ~IFF_DRV_RUNNING; ifp->if_timer = 0; - if (sc->malo_fw_loaded == 1) { - /* diable interrupt. */ - malo_hal_intrset(mh, 0); - /* turn off the radio. */ - malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE); - } + /* diable interrupt. */ + malo_hal_intrset(mh, 0); + /* turn off the radio. */ + malo_hal_setradio(mh, 0, MHP_AUTO_PREAMBLE); /* drain and release tx queues. */ for (i = 0; i < MALO_NUM_TX_QUEUES; i++) @@ -1812,11 +1747,11 @@ malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) #define MALO_IS_RUNNING(ifp) \ ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) struct malo_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->malo_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; MALO_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: if (MALO_IS_RUNNING(ifp)) { @@ -1836,38 +1771,25 @@ malo_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * torn down much of our state. There's * probably a better way to deal with this. */ - if (!sc->malo_invalid) - malo_init(sc); + if (!sc->malo_invalid) { + malo_init_locked(sc); + startall = 1; + } } else malo_stop_locked(ifp, 1); break; - case SIOCADDMULTI: - case SIOCDELMULTI: - /* - * The upper layer has already installed/removed - * the multicast address(es), just recalculate the - * multicast filter for the card. - */ - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - malo_mode_init(sc); + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); break; default: - error = ieee80211_ioctl(ic, cmd, data); - if (error == ENETRESET) { - if (MALO_IS_RUNNING(ifp) && - ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - malo_init(sc); - error = 0; - } - if (error == ERESTART) { - /* XXX we need to reset the device here. */ - error = 0; - } + error = ether_ioctl(ifp, cmd, data); break; } - MALO_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; #undef MALO_IS_RUNNING } @@ -1882,7 +1804,7 @@ static void malo_updateslot(struct ifnet *ifp) { struct malo_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->malo_ic; + struct ieee80211com *ic = ifp->if_l2com; struct malo_hal *mh = sc->malo_mh; int error; @@ -1906,72 +1828,46 @@ malo_updateslot(struct ifnet *ifp) } static int -malo_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +malo_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct ieee80211_node *ni = ic->ic_bss; - struct ifnet *ifp = ic->ic_ifp; - struct malo_softc *sc = ifp->if_softc; + struct ieee80211com *ic = vap->iv_ic; + struct malo_softc *sc = ic->ic_ifp->if_softc; struct malo_hal *mh = sc->malo_mh; int error; DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s -> %s\n", __func__, - ieee80211_state_name[ic->ic_state], + ieee80211_state_name[vap->iv_state], ieee80211_state_name[nstate]); /* - * Carry out firmware actions per-state. + * Invoke the net80211 layer first so iv_bss is setup. */ - switch (nstate) { - case IEEE80211_S_INIT: - case IEEE80211_S_SCAN: - case IEEE80211_S_AUTH: - /* NB: do nothing. */ - break; - case IEEE80211_S_ASSOC: - malo_hal_setradio(mh, 1, - (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? - MHP_SHORT_PREAMBLE : MHP_LONG_PREAMBLE); - break; - case IEEE80211_S_RUN: + error = MALO_VAP(vap)->malo_newstate(vap, nstate, arg); + if (error != 0) + return error; + + if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) { + struct ieee80211_node *ni = vap->iv_bss; + enum ieee80211_phymode mode = ieee80211_chan2mode(ni->ni_chan); + const struct ieee80211_txparam *tp = &vap->iv_txparms[mode]; + DPRINTF(sc, MALO_DEBUG_STATE, - "%s: %s(RUN): ic_flags 0x%08x bintvl %d bssid %s " - "capinfo 0x%04x chan %d\n", - ifp->if_xname, __func__, ic->ic_flags, + "%s: %s(RUN): iv_flags 0x%08x bintvl %d bssid %s " + "capinfo 0x%04x chan %d associd 0x%x mode %d rate %d\n", + vap->iv_ifp->if_xname, __func__, vap->iv_flags, ni->ni_intval, ether_sprintf(ni->ni_bssid), ni->ni_capinfo, - ieee80211_chan2ieee(ic, ic->ic_curchan)); - - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - DPRINTF(sc, MALO_DEBUG_STATE, "%s: %s: aid 0x%x\n", - ic->ic_ifp->if_xname, __func__, ni->ni_associd); - malo_hal_setassocid(sc->malo_mh, - ni->ni_bssid, ni->ni_associd); - - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) - /* automatic rate adaption */ - malo_hal_set_rate(mh, ic->ic_curmode, 0); - else - /* fixed rate */ - malo_hal_set_rate(mh, ic->ic_curmode, - malo_fix2rate(ic->ic_fixed_rate)); - break; - default: - break; - } + ieee80211_chan2ieee(ic, ic->ic_curchan), + ni->ni_associd, mode, tp->ucastrate); - break; - default: - if_printf(ifp, "%s: can't handle state %s -> %s\n", - __func__, ieee80211_state_name[ic->ic_state], - ieee80211_state_name[nstate]); + malo_hal_setradio(mh, 1, + (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? + MHP_SHORT_PREAMBLE : MHP_LONG_PREAMBLE); + malo_hal_setassocid(sc->malo_mh, ni->ni_bssid, ni->ni_associd); + malo_hal_set_rate(mh, mode, + tp->ucastrate == IEEE80211_FIXED_RATE_NONE ? + 0 : malo_fix2rate(tp->ucastrate)); } - - /* - * Invoke the parent method to complete the work. - */ - error = sc->malo_newstate(ic, nstate, arg); - - return error; + return 0; } static int @@ -2038,33 +1934,13 @@ malo_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return 0; } -static int -malo_media_change(struct ifnet *ifp) -{ -#define IS_UP(ifp) \ - ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - int error; - - error = ieee80211_media_change(ifp); - if (error == ENETRESET) { - struct malo_softc *sc = ifp->if_softc; - - if (IS_UP(ifp)) - malo_init(sc); - error = 0; - } - return error; -#undef IS_UP -} - static void malo_bpfattach(struct malo_softc *sc) { struct ifnet *ifp = sc->malo_ifp; - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->malo_tx_th), - &sc->malo_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->malo_tx_th)); /* * Initialize constant fields. @@ -2206,9 +2082,9 @@ malo_rx_proc(void *arg, int npending) ((((const struct ieee80211_frame *)wh)->i_fc[1] & \ IEEE80211_FC1_DIR_MASK) == IEEE80211_FC1_DIR_DSTODS) struct malo_softc *sc = arg; - struct malo_rxbuf *bf; - struct ieee80211com *ic = &sc->malo_ic; struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct malo_rxbuf *bf; struct malo_rxdesc *ds; struct mbuf *m, *mnew; struct ieee80211_qosframe *wh; @@ -2232,8 +2108,7 @@ malo_rx_proc(void *arg, int npending) return; bf = sc->malo_rxnext; - for (ntodo = malo_rxquota; ntodo > 0 && (readptr != writeptr); - ntodo--) { + for (ntodo = malo_rxquota; ntodo > 0 && readptr != writeptr; ntodo--) { if (bf == NULL) { bf = STAILQ_FIRST(&sc->malo_rxbuf); break; @@ -2281,12 +2156,12 @@ malo_rx_proc(void *arg, int npending) * payload prior to constructing the header. */ m = bf->bf_m; - data = mtod(m, uint8_t *); + data = mtod(m, uint8_t *);; hdrlen = ieee80211_anyhdrsize(data + sizeof(uint16_t)); off = sizeof(uint16_t) + sizeof(struct ieee80211_frame_addr4); /* - * Calculate RSSI. XXX wrong + * Calculate RSSI. XXX wrong */ rssi = 2 * ((int) ds->snr - ds->nf); /* NB: .5 dBm */ if (rssi > 100) @@ -2307,7 +2182,6 @@ malo_rx_proc(void *arg, int npending) ifp->if_ierrors++; goto rx_next; } - /* * Attach the dma buffer to the mbuf; malo_rxbuf_init will * re-setup the rx descriptor using the replacement dma @@ -2340,8 +2214,8 @@ malo_rx_proc(void *arg, int npending) sc->malo_rx_th.wr_antsignal = rssi; sc->malo_rx_th.wr_antnoise = ds->nf; - bpf_mtap2(sc->malo_drvbpf, - &sc->malo_rx_th, sc->malo_rx_th_len, m); + bpf_mtap2(ifp->if_bpf, &sc->malo_rx_th, + sc->malo_rx_th_len, m); } #ifdef MALO_DEBUG if (IFF_DUMPPKTS_RECV(sc, wh)) { @@ -2353,10 +2227,12 @@ malo_rx_proc(void *arg, int npending) /* dispatch */ ni = ieee80211_find_rxnode(ic, - (const struct ieee80211_frame_min *) wh); - (void) ieee80211_input(ic, m, ni, rssi, ds->nf, 0/*XXX*/); - ieee80211_free_node(ni); - + (struct ieee80211_frame_min *)wh); + if (ni != NULL) { + (void) ieee80211_input(ni, m, rssi, ds->nf, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, ds->nf, 0); rx_next: /* NB: ignore ENOMEM so we process more descriptors */ (void) malo_rxbuf_init(sc, bf); @@ -2378,9 +2254,7 @@ malo_stop(struct ifnet *ifp, int disable) struct malo_softc *sc = ifp->if_softc; MALO_LOCK(sc); - malo_stop_locked(ifp, disable); - MALO_UNLOCK(sc); } @@ -2400,6 +2274,7 @@ int malo_detach(struct malo_softc *sc) { struct ifnet *ifp = sc->malo_ifp; + struct ieee80211com *ic = ifp->if_l2com; DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", __func__, ifp->if_flags); @@ -2427,7 +2302,7 @@ malo_detach(struct malo_softc *sc) * it last * Other than that, it's straightforward... */ - ieee80211_ifdetach(&sc->malo_ic); + ieee80211_ifdetach(ic); malo_dma_cleanup(sc); malo_tx_cleanup(sc); malo_hal_detach(sc->malo_mh); @@ -2441,7 +2316,6 @@ malo_detach(struct malo_softc *sc) void malo_shutdown(struct malo_softc *sc) { - malo_stop(sc->malo_ifp, 1); } @@ -2464,9 +2338,6 @@ malo_resume(struct malo_softc *sc) DPRINTF(sc, MALO_DEBUG_ANY, "%s: if_flags %x\n", __func__, ifp->if_flags); - if (ifp->if_flags & IFF_UP) { + if (ifp->if_flags & IFF_UP) malo_init(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - malo_start(ifp); - } } diff --git a/sys/dev/malo/if_malo.h b/sys/dev/malo/if_malo.h index 0cb5bc6..070649a 100644 --- a/sys/dev/malo/if_malo.h +++ b/sys/dev/malo/if_malo.h @@ -512,8 +512,14 @@ struct malo_txrec { struct ieee80211_frame_addr4 wh; } __packed; +struct malo_vap { + struct ieee80211vap malo_vap; + int (*malo_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define MALO_VAP(vap) ((struct malo_vap *)(vap)) + struct malo_softc { - struct ieee80211com malo_ic; /* IEEE 802.11 common */ device_t malo_dev; struct ifnet *malo_ifp; /* interface common */ struct mtx malo_mtx; /* master lock (recursive) */ @@ -527,8 +533,7 @@ struct malo_softc { unsigned int malo_invalid : 1,/* disable hardware accesses */ malo_recvsetup : 1, /* recv setup */ - malo_fixedrate : 1, /* use fixed tx rate */ - malo_fw_loaded : 1; /* fw loaded */ + malo_fixedrate: 1; /* use fixed tx rate */ struct malo_hal *malo_mh; /* h/w access layer */ struct malo_hal_hwspec malo_hwspecs; /* h/w capabilities */ @@ -546,9 +551,6 @@ struct malo_softc { struct malo_txq malo_txq[MALO_NUM_TX_QUEUES]; struct task malo_txtask; /* tx int processing */ - int (*malo_newstate)(struct ieee80211com *, - enum ieee80211_state, int); - struct bpf_if *malo_drvbpf; struct malo_tx_radiotap_header malo_tx_th; int malo_tx_th_len; diff --git a/sys/dev/ral/if_ral_pci.c b/sys/dev/ral/if_ral_pci.c index 2ceafe4..a36218b 100644 --- a/sys/dev/ral/if_ral_pci.c +++ b/sys/dev/ral/if_ral_pci.c @@ -50,16 +50,18 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include -#include #include #include MODULE_DEPEND(ral, pci, 1, 1, 1); +MODULE_DEPEND(ral, firmware, 1, 1, 1); MODULE_DEPEND(ral, wlan, 1, 1, 1); +MODULE_DEPEND(ral, wlan_amrr, 1, 1, 1); struct ral_pci_ident { uint16_t vendor; diff --git a/sys/dev/ral/if_ralrate.c b/sys/dev/ral/if_ralrate.c deleted file mode 100644 index b8922ba..0000000 --- a/sys/dev/ral/if_ralrate.c +++ /dev/null @@ -1,192 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: ieee80211_rssadapt.c,v 1.9 2005/02/26 22:45:09 perry Exp $ */ -/*- - * Copyright (c) 2003, 2004 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of David Young may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY David Young ``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 David - * Young 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. - */ - -#include -#include -#include -#include -#include - -#include -#include -#include -#include -#include -#include - -#include - -#include - -#ifdef interpolate -#undef interpolate -#endif -#define interpolate(parm, old, new) ((parm##_old * (old) + \ - (parm##_denom - parm##_old) * (new)) / \ - parm##_denom) - -static struct ral_rssadapt_expavgctl master_expavgctl = { - rc_decay_denom : 16, - rc_decay_old : 15, - rc_thresh_denom : 8, - rc_thresh_old : 4, - rc_avgrssi_denom : 8, - rc_avgrssi_old : 4 -}; - -int -ral_rssadapt_choose(struct ral_rssadapt *ra, struct ieee80211_rateset *rs, - struct ieee80211_frame *wh, u_int len, const char *dvname, int do_not_adapt) -{ - u_int16_t (*thrs)[IEEE80211_RATE_SIZE]; - int flags = 0, i, rateidx = 0, thridx, top; - - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_CTL) - flags |= IEEE80211_RATE_BASIC; - - for (i = 0, top = RAL_RSSADAPT_BKT0; - i < RAL_RSSADAPT_BKTS; - i++, top <<= RAL_RSSADAPT_BKTPOWER) { - thridx = i; - if (len <= top) - break; - } - - thrs = &ra->ra_rate_thresh[thridx]; - - i = rs->rs_nrates; - while (--i >= 0) { - rateidx = i; - if ((rs->rs_rates[i] & flags) != flags) - continue; - if (do_not_adapt) - break; - if ((*thrs)[i] < ra->ra_avg_rssi) - break; - } - - return rateidx; -} - -void -ral_rssadapt_updatestats(struct ral_rssadapt *ra) -{ - long interval; - - ra->ra_pktrate = - (ra->ra_pktrate + 10 * (ra->ra_nfail + ra->ra_nok)) / 2; - ra->ra_nfail = ra->ra_nok = 0; - - /* a node is eligible for its rate to be raised every 1/10 to 10 - * seconds, more eligible in proportion to recent packet rates. - */ - interval = MAX(100000, 10000000 / MAX(1, 10 * ra->ra_pktrate)); - ra->ra_raise_interval.tv_sec = interval / (1000 * 1000); - ra->ra_raise_interval.tv_usec = interval % (1000 * 1000); -} - -void -ral_rssadapt_input(struct ieee80211com *ic, struct ieee80211_node *ni, - struct ral_rssadapt *ra, int rssi) -{ - ra->ra_avg_rssi = interpolate(master_expavgctl.rc_avgrssi, - ra->ra_avg_rssi, (rssi << 8)); -} - -/* - * Adapt the data rate to suit the conditions. When a transmitted - * packet is dropped after RAL_RSSADAPT_RETRY_LIMIT retransmissions, - * raise the RSS threshold for transmitting packets of similar length at - * the same data rate. - */ -void -ral_rssadapt_lower_rate(struct ieee80211com *ic, struct ieee80211_node *ni, - struct ral_rssadapt *ra, struct ral_rssdesc *id) -{ - struct ieee80211_rateset *rs = &ni->ni_rates; - u_int16_t last_thr; - u_int i, thridx, top; - - ra->ra_nfail++; - - if (id->id_rateidx >= rs->rs_nrates) - return; - - for (i = 0, top = RAL_RSSADAPT_BKT0; - i < RAL_RSSADAPT_BKTS; - i++, top <<= RAL_RSSADAPT_BKTPOWER) { - thridx = i; - if (id->id_len <= top) - break; - } - - last_thr = ra->ra_rate_thresh[thridx][id->id_rateidx]; - ra->ra_rate_thresh[thridx][id->id_rateidx] = - interpolate(master_expavgctl.rc_thresh, last_thr, - (id->id_rssi << 8)); -} - -void -ral_rssadapt_raise_rate(struct ieee80211com *ic, struct ral_rssadapt *ra, - struct ral_rssdesc *id) -{ - u_int16_t (*thrs)[IEEE80211_RATE_SIZE], newthr, oldthr; - struct ieee80211_node *ni = id->id_node; - struct ieee80211_rateset *rs = &ni->ni_rates; - int i, rate, top; - - ra->ra_nok++; - - if (!ratecheck(&ra->ra_last_raise, &ra->ra_raise_interval)) - return; - - for (i = 0, top = RAL_RSSADAPT_BKT0; - i < RAL_RSSADAPT_BKTS; - i++, top <<= RAL_RSSADAPT_BKTPOWER) { - thrs = &ra->ra_rate_thresh[i]; - if (id->id_len <= top) - break; - } - - if (id->id_rateidx + 1 < rs->rs_nrates && - (*thrs)[id->id_rateidx + 1] > (*thrs)[id->id_rateidx]) { - rate = (rs->rs_rates[id->id_rateidx + 1] & IEEE80211_RATE_VAL); - - oldthr = (*thrs)[id->id_rateidx + 1]; - if ((*thrs)[id->id_rateidx] == 0) - newthr = ra->ra_avg_rssi; - else - newthr = (*thrs)[id->id_rateidx]; - (*thrs)[id->id_rateidx + 1] = - interpolate(master_expavgctl.rc_decay, oldthr, newthr); - } -} diff --git a/sys/dev/ral/if_ralrate.h b/sys/dev/ral/if_ralrate.h deleted file mode 100644 index 50eee44..0000000 --- a/sys/dev/ral/if_ralrate.h +++ /dev/null @@ -1,98 +0,0 @@ -/* $FreeBSD$ */ -/* $NetBSD: ieee80211_rssadapt.h,v 1.4 2005/02/26 22:45:09 perry Exp $ */ -/*- - * Copyright (c) 2003, 2004 David Young. All rights reserved. - * - * Redistribution and use in source and binary forms, with or - * without modification, are permitted provided that the following - * conditions are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above - * copyright notice, this list of conditions and the following - * disclaimer in the documentation and/or other materials provided - * with the distribution. - * 3. The name of David Young may not be used to endorse or promote - * products derived from this software without specific prior - * written permission. - * - * THIS SOFTWARE IS PROVIDED BY David Young ``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 David - * Young 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. - */ - -/* Data-rate adaptation loosely based on "Link Adaptation Strategy - * for IEEE 802.11 WLAN via Received Signal Strength Measurement" - * by Javier del Prado Pavon and Sunghyun Choi. - */ - -/* Buckets for frames 0-128 bytes long, 129-1024, 1025-maximum. */ -#define RAL_RSSADAPT_BKTS 3 -#define RAL_RSSADAPT_BKT0 128 -#define RAL_RSSADAPT_BKTPOWER 3 /* 2**_BKTPOWER */ - -#define ral_rssadapt_thresh_new \ - (ral_rssadapt_thresh_denom - ral_rssadapt_thresh_old) -#define ral_rssadapt_decay_new \ - (ral_rssadapt_decay_denom - ral_rssadapt_decay_old) -#define ral_rssadapt_avgrssi_new \ - (ral_rssadapt_avgrssi_denom - ral_rssadapt_avgrssi_old) - -struct ral_rssadapt_expavgctl { - /* RSS threshold decay. */ - u_int rc_decay_denom; - u_int rc_decay_old; - /* RSS threshold update. */ - u_int rc_thresh_denom; - u_int rc_thresh_old; - /* RSS average update. */ - u_int rc_avgrssi_denom; - u_int rc_avgrssi_old; -}; - -struct ral_rssadapt { - /* exponential average RSSI << 8 */ - u_int16_t ra_avg_rssi; - /* Tx failures in this update interval */ - u_int32_t ra_nfail; - /* Tx successes in this update interval */ - u_int32_t ra_nok; - /* exponential average packets/second */ - u_int32_t ra_pktrate; - /* RSSI threshold for each Tx rate */ - u_int16_t ra_rate_thresh[RAL_RSSADAPT_BKTS] - [IEEE80211_RATE_SIZE]; - struct timeval ra_last_raise; - struct timeval ra_raise_interval; -}; - -/* Properties of a Tx packet, for link adaptation. */ -struct ral_rssdesc { - u_int id_len; /* Tx packet length */ - u_int id_rateidx; /* index into ni->ni_rates */ - struct ieee80211_node *id_node; /* destination STA MAC */ - u_int8_t id_rssi; /* destination STA avg RSS @ - * Tx time - */ -}; - -void ral_rssadapt_updatestats(struct ral_rssadapt *); -void ral_rssadapt_input(struct ieee80211com *, struct ieee80211_node *, - struct ral_rssadapt *, int); -void ral_rssadapt_lower_rate(struct ieee80211com *, - struct ieee80211_node *, struct ral_rssadapt *, - struct ral_rssdesc *); -void ral_rssadapt_raise_rate(struct ieee80211com *, - struct ral_rssadapt *, struct ral_rssdesc *); -int ral_rssadapt_choose(struct ral_rssadapt *, - struct ieee80211_rateset *, struct ieee80211_frame *, u_int, - const char *, int); diff --git a/sys/dev/ral/rt2560.c b/sys/dev/ral/rt2560.c index 63f7de0..1536a35 100644 --- a/sys/dev/ral/rt2560.c +++ b/sys/dev/ral/rt2560.c @@ -52,8 +52,10 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include +#include #include #include @@ -61,7 +63,6 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include @@ -69,15 +70,26 @@ __FBSDID("$FreeBSD$"); ((rssi) > (RT2560_NOISE_FLOOR + (sc)->rssi_corr) ? \ ((rssi) - RT2560_NOISE_FLOOR - (sc)->rssi_corr) : 0) +#define RAL_DEBUG #ifdef RAL_DEBUG -#define DPRINTF(x) do { if (ral_debug > 0) printf x; } while (0) -#define DPRINTFN(n, x) do { if (ral_debug >= (n)) printf x; } while (0) -extern int ral_debug; +#define DPRINTF(sc, fmt, ...) do { \ + if (sc->sc_debug > 0) \ + printf(fmt, __VA_ARGS__); \ +} while (0) +#define DPRINTFN(sc, n, fmt, ...) do { \ + if (sc->sc_debug >= (n)) \ + printf(fmt, __VA_ARGS__); \ +} while (0) #else -#define DPRINTF(x) -#define DPRINTFN(n, x) +#define DPRINTF(sc, fmt, ...) +#define DPRINTFN(sc, n, fmt, ...) #endif +static struct ieee80211vap *rt2560_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void rt2560_vap_delete(struct ieee80211vap *); static void rt2560_dma_map_addr(void *, bus_dma_segment_t *, int, int); static int rt2560_alloc_tx_ring(struct rt2560_softc *, @@ -94,10 +106,8 @@ static void rt2560_free_rx_ring(struct rt2560_softc *, struct rt2560_rx_ring *); static struct ieee80211_node *rt2560_node_alloc( struct ieee80211_node_table *); -static int rt2560_media_change(struct ifnet *); -static void rt2560_iter_func(void *, struct ieee80211_node *); -static void rt2560_update_rssadapt(void *); -static int rt2560_newstate(struct ieee80211com *, +static void rt2560_newassoc(struct ieee80211_node *, int); +static int rt2560_newstate(struct ieee80211vap *, enum ieee80211_state, int); static uint16_t rt2560_eeprom_read(struct rt2560_softc *, uint8_t); static void rt2560_encryption_intr(struct rt2560_softc *); @@ -105,16 +115,12 @@ static void rt2560_tx_intr(struct rt2560_softc *); static void rt2560_prio_intr(struct rt2560_softc *); static void rt2560_decryption_intr(struct rt2560_softc *); static void rt2560_rx_intr(struct rt2560_softc *); -static void rt2560_beacon_update(struct ieee80211com *, int item); +static void rt2560_beacon_update(struct ieee80211vap *, int item); static void rt2560_beacon_expire(struct rt2560_softc *); static void rt2560_wakeup_expire(struct rt2560_softc *); -static uint8_t rt2560_rxrate(struct rt2560_rx_desc *); -static int rt2560_ack_rate(struct ieee80211com *, int); static void rt2560_scan_start(struct ieee80211com *); static void rt2560_scan_end(struct ieee80211com *); static void rt2560_set_channel(struct ieee80211com *); -static uint16_t rt2560_txtime(int, int, uint32_t); -static uint8_t rt2560_plcp_signal(int); static void rt2560_setup_tx_desc(struct rt2560_softc *, struct rt2560_tx_desc *, uint32_t, int, int, int, bus_addr_t); @@ -122,13 +128,11 @@ static int rt2560_tx_bcn(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); static int rt2560_tx_mgt(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); -static struct mbuf *rt2560_get_rts(struct rt2560_softc *, - struct ieee80211_frame *, uint16_t); static int rt2560_tx_data(struct rt2560_softc *, struct mbuf *, struct ieee80211_node *); +static void rt2560_start_locked(struct ifnet *); static void rt2560_start(struct ifnet *); static void rt2560_watchdog(void *); -static int rt2560_reset(struct ifnet *); static int rt2560_ioctl(struct ifnet *, u_long, caddr_t); static void rt2560_bbp_write(struct rt2560_softc *, uint8_t, uint8_t); @@ -148,13 +152,15 @@ static void rt2560_update_led(struct rt2560_softc *, int, int); static void rt2560_set_bssid(struct rt2560_softc *, const uint8_t *); static void rt2560_set_macaddr(struct rt2560_softc *, uint8_t *); static void rt2560_get_macaddr(struct rt2560_softc *, uint8_t *); -static void rt2560_update_promisc(struct rt2560_softc *); +static void rt2560_update_promisc(struct ifnet *); static const char *rt2560_get_rf(int); static void rt2560_read_config(struct rt2560_softc *); static int rt2560_bbp_init(struct rt2560_softc *); static void rt2560_set_txantenna(struct rt2560_softc *, int); static void rt2560_set_rxantenna(struct rt2560_softc *, int); +static void rt2560_init_locked(struct rt2560_softc *); static void rt2560_init(void *); +static void rt2560_stop_locked(struct rt2560_softc *); static int rt2560_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); @@ -192,9 +198,10 @@ int rt2560_attach(device_t dev, int id) { struct rt2560_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; struct ifnet *ifp; - int error, bands; + int error; + uint8_t bands; sc->sc_dev = dev; @@ -202,14 +209,10 @@ rt2560_attach(device_t dev, int id) MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); - callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE); /* retrieve RT2560 rev. no */ sc->asic_rev = RAL_READ(sc, RT2560_CSR0); - /* retrieve MAC address */ - rt2560_get_macaddr(sc, ic->ic_myaddr); - /* retrieve RF rev. no and various other things from EEPROM */ rt2560_read_config(sc); @@ -249,11 +252,15 @@ rt2560_attach(device_t dev, int id) goto fail5; } - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(sc->sc_dev, "can not if_alloc()\n"); goto fail6; } + ic = ifp->if_l2com; + + /* retrieve MAC address */ + rt2560_get_macaddr(sc, ic->ic_myaddr); ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); @@ -266,48 +273,47 @@ rt2560_attach(device_t dev, int id) IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; + ic->ic_opmode = IEEE80211_M_STA; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = - IEEE80211_C_IBSS | /* IBSS mode supported */ - IEEE80211_C_MONITOR | /* monitor mode supported */ - IEEE80211_C_HOSTAP | /* HostAp mode supported */ - IEEE80211_C_TXPMGT | /* tx power management */ - IEEE80211_C_SHPREAMBLE | /* short preamble supported */ - IEEE80211_C_SHSLOT | /* short slot time supported */ - IEEE80211_C_BGSCAN | /* bg scanning support */ - IEEE80211_C_WPA; /* 802.11i */ + IEEE80211_C_IBSS /* ibss, nee adhoc, mode */ + | IEEE80211_C_HOSTAP /* hostap mode */ + | IEEE80211_C_MONITOR /* monitor mode */ + | IEEE80211_C_AHDEMO /* adhoc demo mode */ + | IEEE80211_C_WDS /* 4-address traffic works */ + | IEEE80211_C_SHPREAMBLE /* short preamble supported */ + | IEEE80211_C_SHSLOT /* short slot time supported */ + | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ + | IEEE80211_C_BGSCAN /* capable of bg scanning */ +#ifdef notyet + | IEEE80211_C_TXFRAG /* handle tx frags */ +#endif + ; bands = 0; setbit(&bands, IEEE80211_MODE_11B); setbit(&bands, IEEE80211_MODE_11G); if (sc->rf_rev == RT2560_RF_5222) setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); + ic->ic_newassoc = rt2560_newassoc; + ic->ic_raw_xmit = rt2560_raw_xmit; + ic->ic_updateslot = rt2560_update_slot; + ic->ic_update_promisc = rt2560_update_promisc; + ic->ic_node_alloc = rt2560_node_alloc; ic->ic_scan_start = rt2560_scan_start; ic->ic_scan_end = rt2560_scan_end; ic->ic_set_channel = rt2560_set_channel; - ic->ic_node_alloc = rt2560_node_alloc; - ic->ic_updateslot = rt2560_update_slot; - ic->ic_reset = rt2560_reset; - /* enable s/w bmiss handling in sta mode */ - ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = rt2560_newstate; - ic->ic_raw_xmit = rt2560_raw_xmit; - ic->ic_update_beacon = rt2560_beacon_update; - ieee80211_media_init(ic, rt2560_media_change, ieee80211_media_status); + ic->ic_vap_create = rt2560_vap_create; + ic->ic_vap_delete = rt2560_vap_delete; - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); @@ -320,8 +326,11 @@ rt2560_attach(device_t dev, int id) /* * Add a few sysctl knobs. */ - sc->dwelltime = 200; - +#ifdef RAL_DEBUG + SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug msgs"); +#endif SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "txantenna", CTLFLAG_RW, &sc->tx_ant, 0, "tx antenna (0=auto)"); @@ -330,11 +339,6 @@ rt2560_attach(device_t dev, int id) SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "rxantenna", CTLFLAG_RW, &sc->rx_ant, 0, "rx antenna (0=auto)"); - SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell", - CTLFLAG_RW, &sc->dwelltime, 0, - "channel dwell time (ms) for AP/station scanning"); - if (bootverbose) ieee80211_announce(ic); @@ -354,11 +358,10 @@ int rt2560_detach(void *xsc) { struct rt2560_softc *sc = xsc; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; rt2560_stop(sc); - callout_stop(&sc->rssadapt_ch); bpfdetach(ifp); ieee80211_ifdetach(ic); @@ -376,17 +379,88 @@ rt2560_detach(void *xsc) return 0; } +static struct ieee80211vap * +rt2560_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ifnet *ifp = ic->ic_ifp; + struct rt2560_vap *rvp; + struct ieee80211vap *vap; + + switch (opmode) { + case IEEE80211_M_STA: + case IEEE80211_M_IBSS: + case IEEE80211_M_AHDEMO: + case IEEE80211_M_MONITOR: + case IEEE80211_M_HOSTAP: + if (!TAILQ_EMPTY(&ic->ic_vaps)) { + if_printf(ifp, "only 1 vap supported\n"); + return NULL; + } + if (opmode == IEEE80211_M_STA) + flags |= IEEE80211_CLONE_NOBEACONS; + break; + case IEEE80211_M_WDS: + if (TAILQ_EMPTY(&ic->ic_vaps) || + ic->ic_opmode != IEEE80211_M_HOSTAP) { + if_printf(ifp, "wds only supported in ap mode\n"); + return NULL; + } + /* + * Silently remove any request for a unique + * bssid; WDS vap's always share the local + * mac address. + */ + flags &= ~IEEE80211_CLONE_BSSID; + break; + default: + if_printf(ifp, "unknown opmode %d\n", opmode); + return NULL; + } + rvp = (struct rt2560_vap *) malloc(sizeof(struct rt2560_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; + vap = &rvp->ral_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + + /* override state transition machine */ + rvp->ral_newstate = vap->iv_newstate; + vap->iv_newstate = rt2560_newstate; + vap->iv_update_beacon = rt2560_beacon_update; + + ieee80211_amrr_init(&rvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 500 /* ms */); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + if (TAILQ_FIRST(&ic->ic_vaps) == vap) + ic->ic_opmode = opmode; + return vap; +} + +static void +rt2560_vap_delete(struct ieee80211vap *vap) +{ + struct rt2560_vap *rvp = RT2560_VAP(vap); + + ieee80211_amrr_cleanup(&rvp->amrr); + ieee80211_vap_detach(vap); + free(rvp, M_80211_VAP); +} + void rt2560_resume(void *xsc) { struct rt2560_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) { - ifp->if_init(ifp->if_softc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ifp->if_start(ifp); - } + if (ifp->if_flags & IFF_UP) + rt2560_init(sc); } static void @@ -702,117 +776,68 @@ rt2560_node_alloc(struct ieee80211_node_table *nt) return (rn != NULL) ? &rn->ni : NULL; } -static int -rt2560_media_change(struct ifnet *ifp) -{ - struct rt2560_softc *sc = ifp->if_softc; - int error; - - error = ieee80211_media_change(ifp); - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) - rt2560_init(sc); - } - return error; -} - -/* - * This function is called for each node present in the node station table. - */ static void -rt2560_iter_func(void *arg, struct ieee80211_node *ni) +rt2560_newassoc(struct ieee80211_node *ni, int isnew) { - struct rt2560_node *rn = (struct rt2560_node *)ni; + struct ieee80211vap *vap = ni->ni_vap; - ral_rssadapt_updatestats(&rn->rssadapt); -} - -/* - * This function is called periodically (every 100ms) in RUN state to update - * the rate adaptation statistics. - */ -static void -rt2560_update_rssadapt(void *arg) -{ - struct rt2560_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - - RAL_LOCK(sc); - - ieee80211_iterate_nodes(&ic->ic_sta, rt2560_iter_func, arg); - callout_reset(&sc->rssadapt_ch, hz / 10, rt2560_update_rssadapt, sc); - - RAL_UNLOCK(sc); + ieee80211_amrr_node_init(&RT2560_VAP(vap)->amrr, + &RT2560_NODE(ni)->amrr, ni); } static int -rt2560_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +rt2560_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { - struct rt2560_softc *sc = ic->ic_ifp->if_softc; - enum ieee80211_state ostate; - struct ieee80211_node *ni; - struct mbuf *m; - int error = 0; + struct rt2560_vap *rvp = RT2560_VAP(vap); + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; + int error; - ostate = ic->ic_state; + if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { + /* abort TSF synchronization */ + RAL_WRITE(sc, RT2560_CSR14, 0); - switch (nstate) { - case IEEE80211_S_INIT: - callout_stop(&sc->rssadapt_ch); + /* turn association led off */ + rt2560_update_led(sc, 0, 0); + } - if (ostate == IEEE80211_S_RUN) { - /* abort TSF synchronization */ - RAL_WRITE(sc, RT2560_CSR14, 0); + error = rvp->ral_newstate(vap, nstate, arg); - /* turn association led off */ - rt2560_update_led(sc, 0, 0); - } - break; - case IEEE80211_S_RUN: - ni = ic->ic_bss; + if (error == 0 && nstate == IEEE80211_S_RUN) { + struct ieee80211_node *ni = vap->iv_bss; + struct mbuf *m; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { + if (vap->iv_opmode != IEEE80211_M_MONITOR) { rt2560_update_plcp(sc); rt2560_set_basicrates(sc); rt2560_set_bssid(sc, ni->ni_bssid); } - if (ic->ic_opmode == IEEE80211_M_HOSTAP || - ic->ic_opmode == IEEE80211_M_IBSS) { - m = ieee80211_beacon_alloc(ni, &sc->sc_bo); + if (vap->iv_opmode == IEEE80211_M_HOSTAP || + vap->iv_opmode == IEEE80211_M_IBSS) { + m = ieee80211_beacon_alloc(ni, &rvp->ral_bo); if (m == NULL) { - device_printf(sc->sc_dev, - "could not allocate beacon\n"); - error = ENOBUFS; - break; + if_printf(ifp, "could not allocate beacon\n"); + return ENOBUFS; } - ieee80211_ref_node(ni); error = rt2560_tx_bcn(sc, m, ni); if (error != 0) - break; + return error; } /* turn assocation led on */ rt2560_update_led(sc, 1, 0); - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - callout_reset(&sc->rssadapt_ch, hz / 10, - rt2560_update_rssadapt, sc); - + if (vap->iv_opmode != IEEE80211_M_MONITOR) { + if (vap->iv_opmode == IEEE80211_M_STA) { + /* fake a join to init the tx rate */ + rt2560_newassoc(ni, 1); + } rt2560_enable_tsf_sync(sc); } - break; - case IEEE80211_S_SCAN: - case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - default: - break; } - - return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg); + return error; } /* @@ -912,8 +937,8 @@ rt2560_encryption_intr(struct rt2560_softc *sc) desc->flags |= htole32(RT2560_TX_VALID); desc->flags |= htole32(RT2560_TX_BUSY); - DPRINTFN(15, ("encryption done idx=%u\n", - sc->txq.next_encrypt)); + DPRINTFN(sc, 15, "encryption done idx=%u\n", + sc->txq.next_encrypt); sc->txq.next_encrypt = (sc->txq.next_encrypt + 1) % RT2560_TX_RING_COUNT; @@ -929,11 +954,13 @@ rt2560_encryption_intr(struct rt2560_softc *sc) static void rt2560_tx_intr(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct rt2560_node *rn; + struct mbuf *m; + uint32_t flags; + int retrycnt; bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, BUS_DMASYNC_POSTREAD); @@ -942,36 +969,43 @@ rt2560_tx_intr(struct rt2560_softc *sc) desc = &sc->txq.desc[sc->txq.next]; data = &sc->txq.data[sc->txq.next]; - if ((le32toh(desc->flags) & RT2560_TX_BUSY) || - (le32toh(desc->flags) & RT2560_TX_CIPHER_BUSY) || - !(le32toh(desc->flags) & RT2560_TX_VALID)) + flags = le32toh(desc->flags); + if ((flags & RT2560_TX_BUSY) || + (flags & RT2560_TX_CIPHER_BUSY) || + !(flags & RT2560_TX_VALID)) break; rn = (struct rt2560_node *)data->ni; + m = data->m; - switch (le32toh(desc->flags) & RT2560_TX_RESULT_MASK) { + switch (flags & RT2560_TX_RESULT_MASK) { case RT2560_TX_SUCCESS: - DPRINTFN(10, ("data frame sent successfully\n")); - if (data->id.id_node != NULL) { - ral_rssadapt_raise_rate(ic, &rn->rssadapt, - &data->id); - } + DPRINTFN(sc, 10, "%s\n", "data frame sent successfully"); + if (data->rix != IEEE80211_FIXED_RATE_NONE) + ieee80211_amrr_tx_complete(&rn->amrr, + IEEE80211_AMRR_SUCCESS, 0); ifp->if_opackets++; break; case RT2560_TX_SUCCESS_RETRY: - DPRINTFN(9, ("data frame sent after %u retries\n", - (le32toh(desc->flags) >> 5) & 0x7)); + retrycnt = RT2560_TX_RETRYCNT(flags); + + DPRINTFN(sc, 9, "data frame sent after %u retries\n", + retrycnt); + if (data->rix != IEEE80211_FIXED_RATE_NONE) + ieee80211_amrr_tx_complete(&rn->amrr, + IEEE80211_AMRR_SUCCESS, retrycnt); ifp->if_opackets++; break; case RT2560_TX_FAIL_RETRY: - DPRINTFN(9, ("sending data frame failed (too much " - "retries)\n")); - if (data->id.id_node != NULL) { - ral_rssadapt_lower_rate(ic, data->ni, - &rn->rssadapt, &data->id); - } + retrycnt = RT2560_TX_RETRYCNT(flags); + + DPRINTFN(sc, 9, "data frame failed after %d retries\n", + retrycnt); + if (data->rix != IEEE80211_FIXED_RATE_NONE) + ieee80211_amrr_tx_complete(&rn->amrr, + IEEE80211_AMRR_FAILURE, retrycnt); ifp->if_oerrors++; break; @@ -979,14 +1013,14 @@ rt2560_tx_intr(struct rt2560_softc *sc) case RT2560_TX_FAIL_OTHER: default: device_printf(sc->sc_dev, "sending data frame failed " - "0x%08x\n", le32toh(desc->flags)); + "0x%08x\n", flags); ifp->if_oerrors++; } bus_dmamap_sync(sc->txq.data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->txq.data_dmat, data->map); - m_freem(data->m); + m_freem(m); data->m = NULL; ieee80211_free_node(data->ni); data->ni = NULL; @@ -994,7 +1028,7 @@ rt2560_tx_intr(struct rt2560_softc *sc) /* descriptor is no longer valid */ desc->flags &= ~htole32(RT2560_TX_VALID); - DPRINTFN(15, ("tx done idx=%u\n", sc->txq.next)); + DPRINTFN(sc, 15, "tx done idx=%u\n", sc->txq.next); sc->txq.queued--; sc->txq.next = (sc->txq.next + 1) % RT2560_TX_RING_COUNT; @@ -1011,15 +1045,14 @@ rt2560_tx_intr(struct rt2560_softc *sc) if ((sc->sc_flags & (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2560_start(ifp); + rt2560_start_locked(ifp); } } static void rt2560_prio_intr(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_node *ni; @@ -1039,17 +1072,17 @@ rt2560_prio_intr(struct rt2560_softc *sc) switch (flags & RT2560_TX_RESULT_MASK) { case RT2560_TX_SUCCESS: - DPRINTFN(10, ("mgt frame sent successfully\n")); + DPRINTFN(sc, 10, "%s\n", "mgt frame sent successfully"); break; case RT2560_TX_SUCCESS_RETRY: - DPRINTFN(9, ("mgt frame sent after %u retries\n", - (flags >> 5) & 0x7)); + DPRINTFN(sc, 9, "mgt frame sent after %u retries\n", + (flags >> 5) & 0x7); break; case RT2560_TX_FAIL_RETRY: - DPRINTFN(9, ("sending mgt frame failed (too much " - "retries)\n")); + DPRINTFN(sc, 9, "%s\n", + "sending mgt frame failed (too much retries)"); break; case RT2560_TX_FAIL_INVALID: @@ -1072,7 +1105,7 @@ rt2560_prio_intr(struct rt2560_softc *sc) /* descriptor is no longer valid */ desc->flags &= ~htole32(RT2560_TX_VALID); - DPRINTFN(15, ("prio done idx=%u\n", sc->prioq.next)); + DPRINTFN(sc, 15, "prio done idx=%u\n", sc->prioq.next); sc->prioq.queued--; sc->prioq.next = (sc->prioq.next + 1) % RT2560_PRIO_RING_COUNT; @@ -1096,25 +1129,24 @@ rt2560_prio_intr(struct rt2560_softc *sc) if ((sc->sc_flags & (RT2560_F_DATA_OACTIVE | RT2560_F_PRIO_OACTIVE)) == 0) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2560_start(ifp); + rt2560_start_locked(ifp); } } /* * Some frames were processed by the hardware cipher engine and are ready for - * transmission to the IEEE802.11 layer. + * handoff to the IEEE802.11 layer. */ static void rt2560_decryption_intr(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2560_rx_desc *desc; struct rt2560_rx_data *data; bus_addr_t physaddr; struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct rt2560_node *rn; struct mbuf *mnew, *m; int hw, error; @@ -1193,7 +1225,7 @@ rt2560_decryption_intr(struct rt2560_softc *sc) m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2560_rx_radiotap_header *tap = &sc->sc_rxtap; uint32_t tsf_lo, tsf_hi; @@ -1204,13 +1236,12 @@ rt2560_decryption_intr(struct rt2560_softc *sc) tap->wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo); tap->wr_flags = 0; - tap->wr_rate = rt2560_rxrate(desc); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wr_rate = ieee80211_plcp2rate(desc->rate, + le32toh(desc->flags) & RT2560_RX_OFDM); tap->wr_antenna = sc->rx_ant; tap->wr_antsignal = RT2560_RSSI(sc, desc->rssi); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } sc->sc_flags |= RT2560_F_INPUT_RUNNING; @@ -1218,24 +1249,19 @@ rt2560_decryption_intr(struct rt2560_softc *sc) wh = mtod(m, struct ieee80211_frame *); ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); - - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, RT2560_RSSI(sc, desc->rssi), - RT2560_NOISE_FLOOR, 0); - - /* give rssi to the rate adatation algorithm */ - rn = (struct rt2560_node *)ni; - ral_rssadapt_input(ic, ni, &rn->rssadapt, - RT2560_RSSI(sc, desc->rssi)); - - /* node is no longer needed */ - ieee80211_free_node(ni); + if (ni != NULL) { + (void) ieee80211_input(ni, m, + RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, + RT2560_RSSI(sc, desc->rssi), RT2560_NOISE_FLOOR, 0); RAL_LOCK(sc); sc->sc_flags &= ~RT2560_F_INPUT_RUNNING; skip: desc->flags = htole32(RT2560_RX_BUSY); - DPRINTFN(15, ("decryption done idx=%u\n", sc->rxq.cur_decrypt)); + DPRINTFN(sc, 15, "decryption done idx=%u\n", sc->rxq.cur_decrypt); sc->rxq.cur_decrypt = (sc->rxq.cur_decrypt + 1) % RT2560_RX_RING_COUNT; @@ -1274,20 +1300,20 @@ rt2560_rx_intr(struct rt2560_softc *sc) * This should not happen since we did not request * to receive those frames when we filled RXCSR0. */ - DPRINTFN(5, ("PHY or CRC error flags 0x%08x\n", - le32toh(desc->flags))); + DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n", + le32toh(desc->flags)); data->drop = 1; } if (((le32toh(desc->flags) >> 16) & 0xfff) > MCLBYTES) { - DPRINTFN(5, ("bad length\n")); + DPRINTFN(sc, 5, "%s\n", "bad length"); data->drop = 1; } /* mark the frame for decryption */ desc->flags |= htole32(RT2560_RX_CIPHER_BUSY); - DPRINTFN(15, ("rx done idx=%u\n", sc->rxq.cur)); + DPRINTFN(sc, 15, "rx done idx=%u\n", sc->rxq.cur); sc->rxq.cur = (sc->rxq.cur + 1) % RT2560_RX_RING_COUNT; } @@ -1300,10 +1326,10 @@ rt2560_rx_intr(struct rt2560_softc *sc) } static void -rt2560_beacon_update(struct ieee80211com *ic, int item) +rt2560_beacon_update(struct ieee80211vap *vap, int item) { - struct rt2560_softc *sc = ic->ic_ifp->if_softc; - struct ieee80211_beacon_offsets *bo = &sc->sc_bo; + struct rt2560_vap *rvp = RT2560_VAP(vap); + struct ieee80211_beacon_offsets *bo = &rvp->ral_bo; setbit(bo->bo_flags, item); } @@ -1315,7 +1341,10 @@ rt2560_beacon_update(struct ieee80211com *ic, int item) static void rt2560_beacon_expire(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct rt2560_vap *rvp = RT2560_VAP(vap); struct rt2560_tx_data *data; if (ic->ic_opmode != IEEE80211_M_IBSS && @@ -1332,14 +1361,12 @@ rt2560_beacon_expire(struct rt2560_softc *sc) bus_dmamap_sync(sc->bcnq.data_dmat, data->map, BUS_DMASYNC_POSTWRITE); bus_dmamap_unload(sc->bcnq.data_dmat, data->map); - ieee80211_beacon_update(data->ni, &sc->sc_bo, data->m, 1); - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, data->m); + /* XXX 1 =>'s mcast frames which means all PS sta's will wakeup! */ + ieee80211_beacon_update(data->ni, &rvp->ral_bo, data->m, 1); rt2560_tx_bcn(sc, data->m, data->ni); - DPRINTFN(15, ("beacon expired\n")); + DPRINTFN(sc, 15, "%s", "beacon expired\n"); sc->bcnq.next = (sc->bcnq.next + 1) % RT2560_BEACON_RING_COUNT; } @@ -1348,7 +1375,7 @@ rt2560_beacon_expire(struct rt2560_softc *sc) static void rt2560_wakeup_expire(struct rt2560_softc *sc) { - DPRINTFN(2, ("wakeup expired\n")); + DPRINTFN(sc, 2, "%s", "wakeup expired\n"); } void @@ -1401,137 +1428,16 @@ rt2560_intr(void *arg) RAL_UNLOCK(sc); } -/* quickly determine if a given rate is CCK or OFDM */ -#define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) - -#define RAL_ACK_SIZE 14 /* 10 + 4(FCS) */ -#define RAL_CTS_SIZE 14 /* 10 + 4(FCS) */ - #define RAL_SIFS 10 /* us */ #define RT2560_TXRX_TURNAROUND 10 /* us */ -/* - * This function is only used by the Rx radiotap code. - */ -static uint8_t -rt2560_rxrate(struct rt2560_rx_desc *desc) -{ - if (le32toh(desc->flags) & RT2560_RX_OFDM) { - /* reverse function of rt2560_plcp_signal */ - switch (desc->rate) { - case 0xb: return 12; - case 0xf: return 18; - case 0xa: return 24; - case 0xe: return 36; - case 0x9: return 48; - case 0xd: return 72; - case 0x8: return 96; - case 0xc: return 108; - } - } else { - if (desc->rate == 10) - return 2; - if (desc->rate == 20) - return 4; - if (desc->rate == 55) - return 11; - if (desc->rate == 110) - return 22; - } - return 2; /* should not get there */ -} - -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -static int -rt2560_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - -/* - * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. - * The function automatically determines the operating mode depending on the - * given rate. `flags' indicates whether short preamble is in use or not. - */ -static uint16_t -rt2560_txtime(int len, int rate, uint32_t flags) -{ - uint16_t txtime; - - if (RAL_RATE_IS_OFDM(rate)) { - /* IEEE Std 802.11a-1999, pp. 37 */ - txtime = (8 + 4 * len + 3 + rate - 1) / rate; - txtime = 16 + 4 + 4 * txtime + 6; - } else { - /* IEEE Std 802.11b-1999, pp. 28 */ - txtime = (16 * len + rate - 1) / rate; - if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) - txtime += 72 + 24; - else - txtime += 144 + 48; - } - - return txtime; -} - -static uint8_t -rt2560_plcp_signal(int rate) -{ - switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* unsupported rates (should not get there) */ - default: return 0xff; - } -} - static void rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, uint32_t flags, int len, int rate, int encrypt, bus_addr_t physaddr) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int remainder; @@ -1545,11 +1451,11 @@ rt2560_setup_tx_desc(struct rt2560_softc *sc, struct rt2560_tx_desc *desc, RT2560_LOGCWMAX(8)); /* setup PLCP fields */ - desc->plcp_signal = rt2560_plcp_signal(rate); + desc->plcp_signal = ieee80211_rate2plcp(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; - if (RAL_RATE_IS_OFDM(rate)) { + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { desc->flags |= htole32(RT2560_TX_OFDM); plcp_length = len & 0xfff; @@ -1579,7 +1485,9 @@ static int rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; @@ -1588,7 +1496,8 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, desc = &sc->bcnq.desc[sc->bcnq.cur]; data = &sc->bcnq.data[sc->bcnq.cur]; - rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; + /* XXX maybe a separate beacon rate? */ + rate = vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)].mgmtrate; error = bus_dmamap_load_mbuf_sg(sc->bcnq.data_dmat, data->map, m0, segs, &nsegs, BUS_DMA_NOWAIT); @@ -1599,7 +1508,7 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1608,7 +1517,7 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; @@ -1617,8 +1526,8 @@ rt2560_tx_bcn(struct rt2560_softc *sc, struct mbuf *m0, rt2560_setup_tx_desc(sc, desc, RT2560_TX_IFS_NEWBACKOFF | RT2560_TX_TIMESTAMP, m0->m_pkthdr.len, rate, 0, segs->ds_addr); - DPRINTFN(10, ("sending beacon frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, sc->bcnq.cur, rate)); + DPRINTFN(sc, 10, "sending beacon frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, sc->bcnq.cur, rate); bus_dmamap_sync(sc->bcnq.data_dmat, data->map, BUS_DMASYNC_PREWRITE); bus_dmamap_sync(sc->bcnq.desc_dmat, sc->bcnq.desc_map, @@ -1633,7 +1542,9 @@ static int rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; struct ieee80211_frame *wh; @@ -1646,12 +1557,12 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, desc = &sc->prioq.desc[sc->prioq.cur]; data = &sc->prioq.data[sc->prioq.cur]; - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; + rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate; wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1667,7 +1578,7 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1676,19 +1587,21 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; + /* management frames are not taken into account for amrr */ + data->rix = IEEE80211_FIXED_RATE_NONE; wh = mtod(m0, struct ieee80211_frame *); if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2560_TX_ACK; - dur = rt2560_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) + - RAL_SIFS; + dur = ieee80211_ack_duration(sc->sc_rates, + rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); /* tell hardware to add timestamp for probe responses */ @@ -1706,8 +1619,8 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, bus_dmamap_sync(sc->prioq.desc_dmat, sc->prioq.desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(10, ("sending mgt frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, sc->prioq.cur, rate)); + DPRINTFN(sc, 10, "sending mgt frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, sc->prioq.cur, rate); /* kick prio */ sc->prioq.queued++; @@ -1718,10 +1631,80 @@ rt2560_tx_mgt(struct rt2560_softc *sc, struct mbuf *m0, } static int +rt2560_sendprot(struct rt2560_softc *sc, + const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) +{ + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_frame *wh; + struct rt2560_tx_desc *desc; + struct rt2560_tx_data *data; + struct mbuf *mprot; + int protrate, ackrate, pktlen, flags, isshort, error; + uint16_t dur; + bus_dma_segment_t segs[RT2560_MAX_SCATTER]; + int nsegs; + + KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, + ("protection %d", prot)); + + wh = mtod(m, const struct ieee80211_frame *); + pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + + protrate = ieee80211_ctl_rate(sc->sc_rates, rate); + ackrate = ieee80211_ack_rate(sc->sc_rates, rate); + + isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); + + ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags = RT2560_TX_MORE_FRAG; + if (prot == IEEE80211_PROT_RTSCTS) { + /* NB: CTS is the same size as an ACK */ + dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags |= RT2560_TX_ACK; + mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); + } else { + mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); + } + if (mprot == NULL) { + /* XXX stat + msg */ + return ENOBUFS; + } + + desc = &sc->txq.desc[sc->txq.cur_encrypt]; + data = &sc->txq.data[sc->txq.cur_encrypt]; + + error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, + mprot, segs, &nsegs, 0); + if (error != 0) { + device_printf(sc->sc_dev, + "could not map mbuf (error %d)\n", error); + m_freem(mprot); + return error; + } + + data->m = mprot; + data->ni = ieee80211_ref_node(ni); + /* ctl frames are not taken into account for amrr */ + data->rix = IEEE80211_FIXED_RATE_NONE; + + rt2560_setup_tx_desc(sc, desc, flags, mprot->m_pkthdr.len, protrate, 1, + segs->ds_addr); + + bus_dmamap_sync(sc->txq.data_dmat, data->map, + BUS_DMASYNC_PREWRITE); + + sc->txq.queued++; + sc->txq.cur_encrypt = (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT; + + return 0; +} + +static int rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; @@ -1734,10 +1717,26 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, rate = params->ibp_rate0 & IEEE80211_RATE_VAL; /* XXX validate */ if (rate == 0) { + /* XXX fall back to mcast/mgmt rate? */ m_freem(m0); return EINVAL; } + flags = 0; + if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) + flags |= RT2560_TX_ACK; + if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { + error = rt2560_sendprot(sc, m0, ni, + params->ibp_flags & IEEE80211_BPF_RTS ? + IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, + rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; + } + error = bus_dmamap_load_mbuf_sg(sc->prioq.data_dmat, data->map, m0, segs, &nsegs, 0); if (error != 0) { @@ -1747,7 +1746,7 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1756,16 +1755,12 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; - flags = 0; - if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) - flags |= RT2560_TX_ACK; - /* XXX need to setup descriptor ourself */ rt2560_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate, (params->ibp_flags & IEEE80211_BPF_CRYPTO) != 0, @@ -1775,8 +1770,8 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, bus_dmamap_sync(sc->prioq.desc_dmat, sc->prioq.desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(10, ("sending raw frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, sc->prioq.cur, rate)); + DPRINTFN(sc, 10, "sending raw frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, sc->prioq.cur, rate); /* kick prio */ sc->prioq.queued++; @@ -1786,70 +1781,40 @@ rt2560_tx_raw(struct rt2560_softc *sc, struct mbuf *m0, return 0; } -/* - * Build a RTS control frame. - */ -static struct mbuf * -rt2560_get_rts(struct rt2560_softc *sc, struct ieee80211_frame *wh, - uint16_t dur) -{ - struct ieee80211_frame_rts *rts; - struct mbuf *m; - - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_ic.ic_stats.is_tx_nobuf++; - device_printf(sc->sc_dev, "could not allocate RTS frame\n"); - return NULL; - } - - rts = mtod(m, struct ieee80211_frame_rts *); - - rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | - IEEE80211_FC0_SUBTYPE_RTS; - rts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)rts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1); - IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2); - - m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts); - - return m; -} - static int rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; struct rt2560_tx_desc *desc; struct rt2560_tx_data *data; - struct rt2560_node *rn; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; struct mbuf *mnew; bus_dma_segment_t segs[RT2560_MAX_SCATTER]; uint16_t dur; - uint32_t flags = 0; + uint32_t flags; int nsegs, rate, error; wh = mtod(m0, struct ieee80211_frame *); - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { - rate = ic->ic_fixed_rate; + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + rate = tp->mcastrate; + } else if (m0->m_flags & M_EAPOL) { + rate = tp->mgmtrate; + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; } else { - struct ieee80211_rateset *rs; - - rs = &ni->ni_rates; - rn = (struct rt2560_node *)ni; - ni->ni_txrate = ral_rssadapt_choose(&rn->rssadapt, rs, wh, - m0->m_pkthdr.len, NULL, 0); - rate = rs->rs_rates[ni->ni_txrate]; + (void) ieee80211_amrr_choose(ni, &RT2560_NODE(ni)->amrr); + rate = ni->ni_txrate; } - rate &= IEEE80211_RATE_VAL; if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1859,66 +1824,22 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } - /* - * IEEE Std 802.11-1999, pp 82: "A STA shall use an RTS/CTS exchange - * for directed frames only when the length of the MPDU is greater - * than the length threshold indicated by [...]" ic_rtsthreshold. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - m0->m_pkthdr.len > ic->ic_rtsthreshold) { - struct mbuf *m; - uint16_t dur; - int rtsrate, ackrate; - - rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - ackrate = rt2560_ack_rate(ic, rate); - - dur = rt2560_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) + - rt2560_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) + - rt2560_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) + - 3 * RAL_SIFS; - - m = rt2560_get_rts(sc, wh, dur); - - desc = &sc->txq.desc[sc->txq.cur_encrypt]; - data = &sc->txq.data[sc->txq.cur_encrypt]; - - error = bus_dmamap_load_mbuf_sg(sc->txq.data_dmat, data->map, - m, segs, &nsegs, 0); - if (error != 0) { - device_printf(sc->sc_dev, - "could not map mbuf (error %d)\n", error); - m_freem(m); - m_freem(m0); - return error; + flags = 0; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + int prot = IEEE80211_PROT_NONE; + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) + prot = IEEE80211_PROT_RTSCTS; + else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) + prot = ic->ic_protmode; + if (prot != IEEE80211_PROT_NONE) { + error = rt2560_sendprot(sc, m0, ni, prot, rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; } - - /* avoid multiple free() of the same node for each fragment */ - ieee80211_ref_node(ni); - - data->m = m; - data->ni = ni; - - /* RTS frames are not taken into account for rssadapt */ - data->id.id_node = NULL; - - rt2560_setup_tx_desc(sc, desc, RT2560_TX_ACK | - RT2560_TX_MORE_FRAG, m->m_pkthdr.len, rtsrate, 1, - segs->ds_addr); - - bus_dmamap_sync(sc->txq.data_dmat, data->map, - BUS_DMASYNC_PREWRITE); - - sc->txq.queued++; - sc->txq.cur_encrypt = - (sc->txq.cur_encrypt + 1) % RT2560_TX_RING_COUNT; - - /* - * IEEE Std 802.11-1999: when an RTS/CTS exchange is used, the - * asynchronous data frame shall be transmitted after the CTS - * frame and a SIFS period. - */ - flags |= RT2560_TX_LONG_RETRY | RT2560_TX_IFS_SIFS; } data = &sc->txq.data[sc->txq.cur_encrypt]; @@ -1955,35 +1876,32 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2560_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; /* remember link conditions for rate adaptation algorithm */ - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { - data->id.id_len = m0->m_pkthdr.len; - data->id.id_rateidx = ni->ni_txrate; - data->id.id_node = ni; - data->id.id_rssi = ni->ni_rssi; + if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { + data->rix = ni->ni_txrate; + /* XXX probably need last rssi value and not avg */ + data->rssi = ic->ic_node_getrssi(ni); } else - data->id.id_node = NULL; + data->rix = IEEE80211_FIXED_RATE_NONE; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2560_TX_ACK; - dur = rt2560_txtime(RAL_ACK_SIZE, rt2560_ack_rate(ic, rate), - ic->ic_flags) + RAL_SIFS; + dur = ieee80211_ack_duration(sc->sc_rates, + rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); } @@ -1994,8 +1912,8 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, bus_dmamap_sync(sc->txq.desc_dmat, sc->txq.desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(10, ("sending data frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, sc->txq.cur_encrypt, rate)); + DPRINTFN(sc, 10, "sending data frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, sc->txq.cur_encrypt, rate); /* kick encrypt */ sc->txq.queued++; @@ -2006,113 +1924,50 @@ rt2560_tx_data(struct rt2560_softc *sc, struct mbuf *m0, } static void -rt2560_start(struct ifnet *ifp) +rt2560_start_locked(struct ifnet *ifp) { struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct mbuf *m0; - struct ether_header *eh; + struct mbuf *m; struct ieee80211_node *ni; - RAL_LOCK(sc); - - /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { - RAL_UNLOCK(sc); - return; - } + RAL_LOCK_ASSERT(sc); for (;;) { - IF_POLL(&ic->ic_mgtq, m0); - if (m0 != NULL) { - if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_flags |= RT2560_F_PRIO_OACTIVE; - break; - } - IF_DEQUEUE(&ic->ic_mgtq, m0); - - ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (rt2560_tx_mgt(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - break; - } - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - sc->sc_flags |= RT2560_F_DATA_OACTIVE; - break; - } - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - if (m0->m_len < sizeof (struct ether_header) && - !(m0 = m_pullup(m0, sizeof (struct ether_header)))) - continue; - - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - if ((ni->ni_flags & IEEE80211_NODE_PWR_MGT) && - (m0->m_flags & M_PWR_SAV) == 0) { - /* - * Station in power save mode; pass the frame - * to the 802.11 layer and continue. We'll get - * the frame back when the time is right. - */ - ieee80211_pwrsave(ni, m0); - /* - * If we're in power save mode 'cuz of a bg - * scan cancel it so the traffic can flow. - * The packet we just queued will automatically - * get sent when we drop out of power save. - * XXX locking - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - ieee80211_free_node(ni); - continue; - } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + if (sc->txq.queued >= RT2560_TX_RING_COUNT - 1) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + sc->sc_flags |= RT2560_F_DATA_OACTIVE; + break; + } - BPF_MTAP(ifp, m0); + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; + } - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ieee80211_free_node(ni); - continue; - } - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (rt2560_tx_data(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } + if (rt2560_tx_data(sc, m, ni) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; } sc->sc_tx_timer = 5; - ic->ic_lastdata = ticks; } +} +static void +rt2560_start(struct ifnet *ifp) +{ + struct rt2560_softc *sc = ifp->if_softc; + + RAL_LOCK(sc); + rt2560_start_locked(ifp); RAL_UNLOCK(sc); } @@ -2122,81 +1977,60 @@ rt2560_watchdog(void *arg) struct rt2560_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; - if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) + RAL_LOCK_ASSERT(sc); + + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); + + if (sc->sc_invalid) /* card ejected */ return; rt2560_encryption_intr(sc); rt2560_tx_intr(sc); - if (sc->sc_tx_timer > 0) { - if (--sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); - rt2560_init(sc); - ifp->if_oerrors++; - /* watchdog timeout is set in rt2560_init() */ - return; - } + if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { + if_printf(ifp, "device timeout\n"); + rt2560_init_locked(sc); + ifp->if_oerrors++; + /* NB: callout is reset in rt2560_init() */ + return; } callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); } -/* - * This function allows for fast channel switching in monitor mode (used by - * net-mgmt/kismet). In IBSS mode, we must explicitly reset the interface to - * generate a new beacon frame. - */ -static int -rt2560_reset(struct ifnet *ifp) -{ - struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - - if (ic->ic_opmode != IEEE80211_M_MONITOR) - return ENETRESET; - - rt2560_set_chan(sc, ic->ic_curchan); - - return 0; -} - static int rt2560_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; - - + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; + RAL_LOCK(sc); switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - RAL_LOCK(sc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2560_update_promisc(sc); - else - rt2560_init(sc); - RAL_UNLOCK(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + rt2560_init_locked(sc); + startall = 1; + } else + rt2560_update_promisc(ifp); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2560_stop(sc); + rt2560_stop_locked(sc); } - break; - + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - rt2560_init(sc); - error = 0; + error = ether_ioctl(ifp, cmd, data); + break; } + RAL_UNLOCK(sc); - + if (startall) + ieee80211_start_all(ic); return error; } @@ -2219,7 +2053,7 @@ rt2560_bbp_write(struct rt2560_softc *sc, uint8_t reg, uint8_t val) tmp = RT2560_BBP_WRITE | RT2560_BBP_BUSY | reg << 8 | val; RAL_WRITE(sc, RT2560_BBPCSR, tmp); - DPRINTFN(15, ("BBP R%u <- 0x%02x\n", reg, val)); + DPRINTFN(sc, 15, "BBP R%u <- 0x%02x\n", reg, val); } static uint8_t @@ -2275,19 +2109,21 @@ rt2560_rf_write(struct rt2560_softc *sc, uint8_t reg, uint32_t val) /* remember last written value in sc */ sc->rf_regs[reg] = val; - DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff)); + DPRINTFN(sc, 15, "RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff); } static void rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint8_t power, tmp; u_int i, chan; chan = ieee80211_chan2ieee(ic, c); - if (chan == 0 || chan == IEEE80211_CHAN_ANY) - return; + KASSERT(chan != 0 && chan != IEEE80211_CHAN_ANY, ("chan 0x%x", chan)); + + sc->sc_rates = ieee80211_get_ratetable(c); if (IEEE80211_IS_CHAN_2GHZ(c)) power = min(sc->txpow[chan - 1], 31); @@ -2297,7 +2133,7 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) /* adjust txpower using ifconfig settings */ power -= (100 - ic->ic_txpowlimit) / 8; - DPRINTFN(2, ("setting channel to %u, txpower to %u\n", chan, power)); + DPRINTFN(sc, 2, "setting channel to %u, txpower to %u\n", chan, power); switch (sc->rf_rev) { case RT2560_RF_2522: @@ -2362,7 +2198,8 @@ rt2560_set_chan(struct rt2560_softc *sc, struct ieee80211_channel *c) printf("unknown ral rev=%d\n", sc->rf_rev); } - if (ic->ic_state != IEEE80211_S_SCAN) { + /* XXX */ + if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { /* set Japan filter bit for channel 14 */ tmp = rt2560_bbp_read(sc, 70); @@ -2385,6 +2222,11 @@ rt2560_set_channel(struct ieee80211com *ic) RAL_LOCK(sc); rt2560_set_chan(sc, ic->ic_curchan); + + sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq); + sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags); + sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq); + sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags); RAL_UNLOCK(sc); } @@ -2406,7 +2248,7 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc) tmp = sc->rf_regs[RAL_RF3] & ~RAL_RF3_AUTOTUNE; rt2560_rf_write(sc, RAL_RF3, tmp); - DPRINTFN(2, ("disabling RF autotune\n")); + DPRINTFN(sc, 2, "%s", "disabling RF autotune\n"); } #endif @@ -2417,20 +2259,22 @@ rt2560_disable_rf_tune(struct rt2560_softc *sc) static void rt2560_enable_tsf_sync(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload; uint32_t tmp; /* first, disable TSF synchronization */ RAL_WRITE(sc, RT2560_CSR14, 0); - tmp = 16 * ic->ic_bss->ni_intval; + tmp = 16 * vap->iv_bss->ni_intval; RAL_WRITE(sc, RT2560_CSR12, tmp); RAL_WRITE(sc, RT2560_CSR13, 0); logcwmin = 5; - preload = (ic->ic_opmode == IEEE80211_M_STA) ? 384 : 1024; + preload = (vap->iv_opmode == IEEE80211_M_STA) ? 384 : 1024; tmp = logcwmin << 16 | preload; RAL_WRITE(sc, RT2560_BCNOCSR, tmp); @@ -2443,13 +2287,14 @@ rt2560_enable_tsf_sync(struct rt2560_softc *sc) RT2560_ENABLE_BEACON_GENERATOR; RAL_WRITE(sc, RT2560_CSR14, tmp); - DPRINTF(("enabling TSF synchronization\n")); + DPRINTF(sc, "%s", "enabling TSF synchronization\n"); } static void rt2560_update_plcp(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; /* no short preamble for 1Mbps */ RAL_WRITE(sc, RT2560_PLCP1MCSR, 0x00700400); @@ -2466,8 +2311,8 @@ rt2560_update_plcp(struct rt2560_softc *sc) RAL_WRITE(sc, RT2560_PLCP11MCSR, 0x000b840b); } - DPRINTF(("updating PLCP for %s preamble\n", - (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long")); + DPRINTF(sc, "updating PLCP for %s preamble\n", + (ic->ic_flags & IEEE80211_F_SHPREAMBLE) ? "short" : "long"); } /* @@ -2478,7 +2323,7 @@ static void rt2560_update_slot(struct ifnet *ifp) { struct rt2560_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; uint8_t slottime; uint16_t tx_sifs, tx_pifs, tx_difs, eifs; uint32_t tmp; @@ -2521,13 +2366,14 @@ rt2560_update_slot(struct ifnet *ifp) tmp = eifs << 16 | tx_difs; RAL_WRITE(sc, RT2560_CSR19, tmp); - DPRINTF(("setting slottime to %uus\n", slottime)); + DPRINTF(sc, "setting slottime to %uus\n", slottime); } static void rt2560_set_basicrates(struct rt2560_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; /* update basic rate set */ if (ic->ic_curmode == IEEE80211_MODE_11B) { @@ -2563,7 +2409,7 @@ rt2560_set_bssid(struct rt2560_softc *sc, const uint8_t *bssid) tmp = bssid[4] | bssid[5] << 8; RAL_WRITE(sc, RT2560_CSR6, tmp); - DPRINTF(("setting BSSID to %6D\n", bssid, ":")); + DPRINTF(sc, "setting BSSID to %6D\n", bssid, ":"); } static void @@ -2577,7 +2423,7 @@ rt2560_set_macaddr(struct rt2560_softc *sc, uint8_t *addr) tmp = addr[4] | addr[5] << 8; RAL_WRITE(sc, RT2560_CSR4, tmp); - DPRINTF(("setting MAC address to %6D\n", addr, ":")); + DPRINTF(sc, "setting MAC address to %6D\n", addr, ":"); } static void @@ -2597,9 +2443,9 @@ rt2560_get_macaddr(struct rt2560_softc *sc, uint8_t *addr) } static void -rt2560_update_promisc(struct rt2560_softc *sc) +rt2560_update_promisc(struct ifnet *ifp) { - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct rt2560_softc *sc = ifp->if_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2560_RXCSR0); @@ -2610,8 +2456,8 @@ rt2560_update_promisc(struct rt2560_softc *sc) RAL_WRITE(sc, RT2560_RXCSR0, tmp); - DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? - "entering" : "leaving")); + DPRINTF(sc, "%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? + "entering" : "leaving"); } static const char * @@ -2669,8 +2515,8 @@ rt2560_read_config(struct rt2560_softc *sc) sc->rssi_corr = RT2560_DEFAULT_RSSI_CORR; else sc->rssi_corr = val & 0xff; - DPRINTF(("rssi correction %d, calibrate 0x%02x\n", - sc->rssi_corr, val)); + DPRINTF(sc, "rssi correction %d, calibrate 0x%02x\n", + sc->rssi_corr, val); } @@ -2690,10 +2536,11 @@ rt2560_scan_end(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct rt2560_softc *sc = ifp->if_softc; + struct ieee80211vap *vap = ic->ic_scan->ss_vap; rt2560_enable_tsf_sync(sc); /* XXX keep local copy */ - rt2560_set_bssid(sc, ic->ic_bss->ni_bssid); + rt2560_set_bssid(sc, vap->iv_bss->ni_bssid); } static int @@ -2779,20 +2626,18 @@ rt2560_set_rxantenna(struct rt2560_softc *sc, int antenna) } static void -rt2560_init(void *priv) +rt2560_init_locked(struct rt2560_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct rt2560_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; int i; + RAL_LOCK_ASSERT(sc); + rt2560_stop_locked(sc); - rt2560_stop(sc); - - RAL_LOCK(sc); /* setup tx rings */ tmp = RT2560_PRIO_RING_COUNT << 24 | RT2560_ATIM_RING_COUNT << 16 | @@ -2866,35 +2711,38 @@ rt2560_init(void *priv) ifp->if_drv_flags |= IFF_DRV_RUNNING; callout_reset(&sc->watchdog_ch, hz, rt2560_watchdog, sc); +#undef N +} - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); +static void +rt2560_init(void *priv) +{ + struct rt2560_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + RAL_LOCK(sc); + rt2560_init_locked(sc); RAL_UNLOCK(sc); -#undef N + + ieee80211_start_all(ic); } -void -rt2560_stop(void *arg) +static void +rt2560_stop_locked(struct rt2560_softc *sc) { - struct rt2560_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; volatile int *flags = &sc->sc_flags; - while (*flags & RT2560_F_INPUT_RUNNING) { - tsleep(sc, 0, "ralrunning", hz/10); - } + RAL_LOCK_ASSERT(sc); - RAL_LOCK(sc); + while (*flags & RT2560_F_INPUT_RUNNING) + msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10); callout_stop(&sc->watchdog_ch); + sc->sc_tx_timer = 0; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); /* abort Tx */ @@ -2917,9 +2765,16 @@ rt2560_stop(void *arg) rt2560_reset_tx_ring(sc, &sc->bcnq); rt2560_reset_rx_ring(sc, &sc->rxq); } - sc->sc_tx_timer = 0; sc->sc_flags &= ~(RT2560_F_PRIO_OACTIVE | RT2560_F_DATA_OACTIVE); +} +void +rt2560_stop(void *arg) +{ + struct rt2560_softc *sc = arg; + + RAL_LOCK(sc); + rt2560_stop_locked(sc); RAL_UNLOCK(sc); } @@ -2942,15 +2797,13 @@ rt2560_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, } if (sc->prioq.queued >= RT2560_PRIO_RING_COUNT) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; + sc->sc_flags |= RT2560_F_PRIO_OACTIVE; RAL_UNLOCK(sc); m_freem(m); ieee80211_free_node(ni); return ENOBUFS; /* XXX */ } - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m); - ifp->if_opackets++; if (params == NULL) { diff --git a/sys/dev/ral/rt2560reg.h b/sys/dev/ral/rt2560reg.h index bab455d..8e501b4 100644 --- a/sys/dev/ral/rt2560reg.h +++ b/sys/dev/ral/rt2560reg.h @@ -208,6 +208,8 @@ struct rt2560_tx_desc { #define RT2560_TX_CIPHER_TKIP (3 << 29) #define RT2560_TX_CIPHER_AES (4 << 29) +#define RT2560_TX_RETRYCNT(v) (((v) >> 5) & 0x7) + uint32_t physaddr; uint16_t wme; #define RT2560_LOGCWMAX(x) (((x) & 0xf) << 12) diff --git a/sys/dev/ral/rt2560var.h b/sys/dev/ral/rt2560var.h index 1f68311..0841444 100644 --- a/sys/dev/ral/rt2560var.h +++ b/sys/dev/ral/rt2560var.h @@ -55,7 +55,8 @@ struct rt2560_tx_data { bus_dmamap_t map; struct mbuf *m; struct ieee80211_node *ni; - struct ral_rssdesc id; + uint8_t rix; + int8_t rssi; }; struct rt2560_tx_ring { @@ -94,14 +95,22 @@ struct rt2560_rx_ring { struct rt2560_node { struct ieee80211_node ni; - struct ral_rssadapt rssadapt; + struct ieee80211_amrr_node amrr; }; +#define RT2560_NODE(ni) ((struct rt2560_node *)(ni)) + +struct rt2560_vap { + struct ieee80211vap ral_vap; + struct ieee80211_beacon_offsets ral_bo; + struct ieee80211_amrr amrr; + + int (*ral_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define RT2560_VAP(vap) ((struct rt2560_vap *)(vap)) struct rt2560_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; @@ -109,10 +118,12 @@ struct rt2560_softc { struct mtx sc_mtx; struct callout watchdog_ch; - struct callout rssadapt_ch; int sc_tx_timer; int sc_invalid; + int sc_debug; + + const struct ieee80211_rate_table *sc_rates; /* * The same in both up to here * ------------------------------------------------ @@ -128,8 +139,6 @@ struct rt2560_softc { struct rt2560_tx_ring bcnq; struct rt2560_rx_ring rxq; - struct ieee80211_beacon_offsets sc_bo; - uint32_t rf_regs[4]; uint8_t txpow[14]; @@ -144,22 +153,10 @@ struct rt2560_softc { int tx_ant; int nb_ant; - int dwelltime; - - struct bpf_if *sc_drvbpf; - - union { - struct rt2560_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct rt2560_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - union { - struct rt2560_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct rt2560_tx_radiotap_header sc_txtap; int sc_txtap_len; #define RT2560_F_INPUT_RUNNING 0x1 #define RT2560_F_PRIO_OACTIVE 0x2 @@ -173,5 +170,6 @@ void rt2560_stop(void *); void rt2560_resume(void *); void rt2560_intr(void *); -#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define RAL_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) diff --git a/sys/dev/ral/rt2661.c b/sys/dev/ral/rt2661.c index 025646d..c94dbe7 100644 --- a/sys/dev/ral/rt2661.c +++ b/sys/dev/ral/rt2661.c @@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -52,8 +53,10 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include +#include #include #include @@ -61,21 +64,29 @@ __FBSDID("$FreeBSD$"); #include #include -#include #include #include -#include +#define RAL_DEBUG #ifdef RAL_DEBUG -#define DPRINTF(x) do { if (ral_debug > 0) printf x; } while (0) -#define DPRINTFN(n, x) do { if (ral_debug >= (n)) printf x; } while (0) -int ral_debug = 0; -SYSCTL_INT(_debug, OID_AUTO, ral, CTLFLAG_RW, &ral_debug, 0, "ral debug level"); +#define DPRINTF(sc, fmt, ...) do { \ + if (sc->sc_debug > 0) \ + printf(fmt, __VA_ARGS__); \ +} while (0) +#define DPRINTFN(sc, n, fmt, ...) do { \ + if (sc->sc_debug >= (n)) \ + printf(fmt, __VA_ARGS__); \ +} while (0) #else -#define DPRINTF(x) -#define DPRINTFN(n, x) +#define DPRINTF(sc, fmt, ...) +#define DPRINTFN(sc, n, fmt, ...) #endif +static struct ieee80211vap *rt2661_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void rt2661_vap_delete(struct ieee80211vap *); static void rt2661_dma_map_addr(void *, bus_dma_segment_t *, int, int); static int rt2661_alloc_tx_ring(struct rt2661_softc *, @@ -92,8 +103,8 @@ static void rt2661_free_rx_ring(struct rt2661_softc *, struct rt2661_rx_ring *); static struct ieee80211_node *rt2661_node_alloc( struct ieee80211_node_table *); -static int rt2661_media_change(struct ifnet *); -static int rt2661_newstate(struct ieee80211com *, +static void rt2661_newassoc(struct ieee80211_node *, int); +static int rt2661_newstate(struct ieee80211vap *, enum ieee80211_state, int); static uint16_t rt2661_eeprom_read(struct rt2661_softc *, uint8_t); static void rt2661_rx_intr(struct rt2661_softc *); @@ -103,25 +114,21 @@ static void rt2661_tx_dma_intr(struct rt2661_softc *, static void rt2661_mcu_beacon_expire(struct rt2661_softc *); static void rt2661_mcu_wakeup(struct rt2661_softc *); static void rt2661_mcu_cmd_intr(struct rt2661_softc *); -static int rt2661_ack_rate(struct ieee80211com *, int); static void rt2661_scan_start(struct ieee80211com *); static void rt2661_scan_end(struct ieee80211com *); static void rt2661_set_channel(struct ieee80211com *); -static uint16_t rt2661_txtime(int, int, uint32_t); -static uint8_t rt2661_rxrate(struct rt2661_rx_desc *); -static uint8_t rt2661_plcp_signal(int); static void rt2661_setup_tx_desc(struct rt2661_softc *, struct rt2661_tx_desc *, uint32_t, uint16_t, int, int, const bus_dma_segment_t *, int, int); -static struct mbuf * rt2661_get_rts(struct rt2661_softc *, - struct ieee80211_frame *, uint16_t); static int rt2661_tx_data(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *, int); static int rt2661_tx_mgt(struct rt2661_softc *, struct mbuf *, struct ieee80211_node *); +static void rt2661_start_locked(struct ifnet *); static void rt2661_start(struct ifnet *); +static int rt2661_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); static void rt2661_watchdog(void *); -static int rt2661_reset(struct ifnet *); static int rt2661_ioctl(struct ifnet *, u_long, caddr_t); static void rt2661_bbp_write(struct rt2661_softc *, uint8_t, uint8_t); @@ -143,23 +150,25 @@ static void rt2661_set_bssid(struct rt2661_softc *, const uint8_t *); static void rt2661_set_macaddr(struct rt2661_softc *, const uint8_t *); -static void rt2661_update_promisc(struct rt2661_softc *); +static void rt2661_update_promisc(struct ifnet *); static int rt2661_wme_update(struct ieee80211com *) __unused; static void rt2661_update_slot(struct ifnet *); static const char *rt2661_get_rf(int); -static void rt2661_read_eeprom(struct rt2661_softc *); +static void rt2661_read_eeprom(struct rt2661_softc *, + struct ieee80211com *); static int rt2661_bbp_init(struct rt2661_softc *); +static void rt2661_init_locked(struct rt2661_softc *); static void rt2661_init(void *); -static void rt2661_stop(void *); static void rt2661_stop_locked(struct rt2661_softc *); -static int rt2661_load_microcode(struct rt2661_softc *, - const uint8_t *, int); +static void rt2661_stop(void *); +static int rt2661_load_microcode(struct rt2661_softc *); #ifdef notyet static void rt2661_rx_tune(struct rt2661_softc *); static void rt2661_radar_start(struct rt2661_softc *); static int rt2661_radar_stop(struct rt2661_softc *); #endif -static int rt2661_prepare_beacon(struct rt2661_softc *); +static int rt2661_prepare_beacon(struct rt2661_softc *, + struct ieee80211vap *); static void rt2661_enable_tsf_sync(struct rt2661_softc *); static int rt2661_get_rssi(struct rt2661_softc *, uint8_t); @@ -190,19 +199,26 @@ int rt2661_attach(device_t dev, int id) { struct rt2661_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; struct ifnet *ifp; uint32_t val; - const uint8_t *ucode = NULL; - int bands, error, ac, ntries, size = 0; + int error, ac, ntries; + uint8_t bands; + sc->sc_id = id; sc->sc_dev = dev; + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); + return ENOMEM; + } + ic = ifp->if_l2com; + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); callout_init_mtx(&sc->watchdog_ch, &sc->sc_mtx, 0); - callout_init(&sc->rssadapt_ch, CALLOUT_MPSAFE); /* wait for NIC to initialize */ for (ntries = 0; ntries < 1000; ntries++) { @@ -218,36 +234,12 @@ rt2661_attach(device_t dev, int id) } /* retrieve RF rev. no and various other things from EEPROM */ - rt2661_read_eeprom(sc); + rt2661_read_eeprom(sc, ic); device_printf(dev, "MAC/BBP RT%X, RF %s\n", val, rt2661_get_rf(sc->rf_rev)); /* - * Load 8051 microcode into NIC. - */ - switch (id) { - case 0x0301: - ucode = rt2561s_ucode; - size = sizeof rt2561s_ucode; - break; - case 0x0302: - ucode = rt2561_ucode; - size = sizeof rt2561_ucode; - break; - case 0x0401: - ucode = rt2661_ucode; - size = sizeof rt2661_ucode; - break; - } - - error = rt2661_load_microcode(sc, ucode, size); - if (error != 0) { - device_printf(sc->sc_dev, "could not load 8051 microcode\n"); - goto fail1; - } - - /* * Allocate Tx and Rx rings. */ for (ac = 0; ac < 4; ac++) { @@ -272,13 +264,6 @@ rt2661_attach(device_t dev, int id) goto fail3; } - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - device_printf(sc->sc_dev, "can not if_alloc()\n"); - error = ENOMEM; - goto fail4; - } - ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; @@ -290,50 +275,53 @@ rt2661_attach(device_t dev, int id) IFQ_SET_READY(&ifp->if_snd); ic->ic_ifp = ifp; + ic->ic_opmode = IEEE80211_M_STA; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = - IEEE80211_C_IBSS | /* IBSS mode supported */ - IEEE80211_C_MONITOR | /* monitor mode supported */ - IEEE80211_C_HOSTAP | /* HostAp mode supported */ - IEEE80211_C_TXPMGT | /* tx power management */ - IEEE80211_C_SHPREAMBLE | /* short preamble supported */ - IEEE80211_C_SHSLOT | /* short slot time supported */ + IEEE80211_C_IBSS /* ibss, nee adhoc, mode */ + | IEEE80211_C_HOSTAP /* hostap mode */ + | IEEE80211_C_MONITOR /* monitor mode */ + | IEEE80211_C_AHDEMO /* adhoc demo mode */ + | IEEE80211_C_WDS /* 4-address traffic works */ + | IEEE80211_C_SHPREAMBLE /* short preamble supported */ + | IEEE80211_C_SHSLOT /* short slot time supported */ + | IEEE80211_C_WPA /* capable of WPA1+WPA2 */ + | IEEE80211_C_BGSCAN /* capable of bg scanning */ #ifdef notyet - IEEE80211_C_WME | /* 802.11e */ + | IEEE80211_C_TXFRAG /* handle tx frags */ + | IEEE80211_C_WME /* 802.11e */ #endif - IEEE80211_C_BGSCAN | /* bg scanning support */ - IEEE80211_C_WPA; /* 802.11i */ + ; bands = 0; setbit(&bands, IEEE80211_MODE_11B); setbit(&bands, IEEE80211_MODE_11G); if (sc->rf_rev == RT2661_RF_5225 || sc->rf_rev == RT2661_RF_5325) setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); + ic->ic_newassoc = rt2661_newassoc; ic->ic_node_alloc = rt2661_node_alloc; -/* ic->ic_wme.wme_update = rt2661_wme_update;*/ +#if 0 + ic->ic_wme.wme_update = rt2661_wme_update; +#endif ic->ic_scan_start = rt2661_scan_start; ic->ic_scan_end = rt2661_scan_end; ic->ic_set_channel = rt2661_set_channel; ic->ic_updateslot = rt2661_update_slot; - ic->ic_reset = rt2661_reset; - /* enable s/w bmiss handling in sta mode */ - ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; + ic->ic_update_promisc = rt2661_update_promisc; + ic->ic_raw_xmit = rt2661_raw_xmit; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = rt2661_newstate; - ieee80211_media_init(ic, rt2661_media_change, ieee80211_media_status); + ic->ic_vap_create = rt2661_vap_create; + ic->ic_vap_delete = rt2661_vap_delete; + + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); @@ -343,27 +331,21 @@ rt2661_attach(device_t dev, int id) sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(RT2661_TX_RADIOTAP_PRESENT); - - /* - * Add a few sysctl knobs. - */ - sc->dwelltime = 200; - +#ifdef RAL_DEBUG SYSCTL_ADD_INT(device_get_sysctl_ctx(dev), - SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, "dwell", - CTLFLAG_RW, &sc->dwelltime, 0, - "channel dwell time (ms) for AP/station scanning"); - + SYSCTL_CHILDREN(device_get_sysctl_tree(dev)), OID_AUTO, + "debug", CTLFLAG_RW, &sc->sc_debug, 0, "debug msgs"); +#endif if (bootverbose) ieee80211_announce(ic); return 0; -fail4: rt2661_free_rx_ring(sc, &sc->rxq); fail3: rt2661_free_tx_ring(sc, &sc->mgtq); fail2: while (--ac >= 0) rt2661_free_tx_ring(sc, &sc->txq[ac]); fail1: mtx_destroy(&sc->sc_mtx); + if_free(ifp); return error; } @@ -371,14 +353,12 @@ int rt2661_detach(void *xsc) { struct rt2661_softc *sc = xsc; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); rt2661_stop_locked(sc); - callout_stop(&sc->watchdog_ch); RAL_UNLOCK(sc); - callout_stop(&sc->rssadapt_ch); bpfdetach(ifp); ieee80211_ifdetach(ic); @@ -397,6 +377,82 @@ rt2661_detach(void *xsc) return 0; } +static struct ieee80211vap * +rt2661_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ifnet *ifp = ic->ic_ifp; + struct rt2661_vap *rvp; + struct ieee80211vap *vap; + + switch (opmode) { + case IEEE80211_M_STA: + case IEEE80211_M_IBSS: + case IEEE80211_M_AHDEMO: + case IEEE80211_M_MONITOR: + case IEEE80211_M_HOSTAP: + if (!TAILQ_EMPTY(&ic->ic_vaps)) { + if_printf(ifp, "only 1 vap supported\n"); + return NULL; + } + if (opmode == IEEE80211_M_STA) + flags |= IEEE80211_CLONE_NOBEACONS; + break; + case IEEE80211_M_WDS: + if (TAILQ_EMPTY(&ic->ic_vaps) || + ic->ic_opmode != IEEE80211_M_HOSTAP) { + if_printf(ifp, "wds only supported in ap mode\n"); + return NULL; + } + /* + * Silently remove any request for a unique + * bssid; WDS vap's always share the local + * mac address. + */ + flags &= ~IEEE80211_CLONE_BSSID; + break; + default: + if_printf(ifp, "unknown opmode %d\n", opmode); + return NULL; + } + rvp = (struct rt2661_vap *) malloc(sizeof(struct rt2661_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; + vap = &rvp->ral_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + + /* override state transition machine */ + rvp->ral_newstate = vap->iv_newstate; + vap->iv_newstate = rt2661_newstate; +#if 0 + vap->iv_update_beacon = rt2661_beacon_update; +#endif + + ieee80211_amrr_init(&rvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 500 /* ms */); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + if (TAILQ_FIRST(&ic->ic_vaps) == vap) + ic->ic_opmode = opmode; + return vap; +} + +static void +rt2661_vap_delete(struct ieee80211vap *vap) +{ + struct rt2661_vap *rvp = RT2661_VAP(vap); + + ieee80211_amrr_cleanup(&rvp->amrr); + ieee80211_vap_detach(vap); + free(rvp, M_80211_VAP); +} + void rt2661_shutdown(void *xsc) { @@ -417,13 +473,10 @@ void rt2661_resume(void *xsc) { struct rt2661_softc *sc = xsc; - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; - if (ifp->if_flags & IFF_UP) { - ifp->if_init(ifp->if_softc); - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - ifp->if_start(ifp); - } + if (ifp->if_flags & IFF_UP) + rt2661_init(sc); } static void @@ -732,102 +785,58 @@ rt2661_node_alloc(struct ieee80211_node_table *nt) return (rn != NULL) ? &rn->ni : NULL; } -static int -rt2661_media_change(struct ifnet *ifp) -{ - struct rt2661_softc *sc = ifp->if_softc; - int error; - - error = ieee80211_media_change(ifp); - if (error != ENETRESET) - return error; - - if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - rt2661_init(sc); - - return 0; -} - -/* - * This function is called for each node present in the node station table. - */ -static void -rt2661_iter_func(void *arg, struct ieee80211_node *ni) -{ - struct rt2661_node *rn = (struct rt2661_node *)ni; - - ral_rssadapt_updatestats(&rn->rssadapt); -} - -/* - * This function is called periodically (every 100ms) in RUN state to update - * the rate adaptation statistics. - */ static void -rt2661_update_rssadapt(void *arg) +rt2661_newassoc(struct ieee80211_node *ni, int isnew) { - struct rt2661_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - - RAL_LOCK(sc); - - ieee80211_iterate_nodes(&ic->ic_sta, rt2661_iter_func, arg); - callout_reset(&sc->rssadapt_ch, hz / 10, rt2661_update_rssadapt, sc); + struct ieee80211vap *vap = ni->ni_vap; - RAL_UNLOCK(sc); + ieee80211_amrr_node_init(&RT2661_VAP(vap)->amrr, + &RT2661_NODE(ni)->amrr, ni); } static int -rt2661_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +rt2661_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct rt2661_vap *rvp = RT2661_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct rt2661_softc *sc = ic->ic_ifp->if_softc; - enum ieee80211_state ostate; - struct ieee80211_node *ni; - uint32_t tmp; - int error = 0; + int error; - ostate = ic->ic_state; + if (nstate == IEEE80211_S_INIT && vap->iv_state == IEEE80211_S_RUN) { + uint32_t tmp; - switch (nstate) { - case IEEE80211_S_INIT: - callout_stop(&sc->rssadapt_ch); + /* abort TSF synchronization */ + tmp = RAL_READ(sc, RT2661_TXRX_CSR9); + RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff); + } - if (ostate == IEEE80211_S_RUN) { - /* abort TSF synchronization */ - tmp = RAL_READ(sc, RT2661_TXRX_CSR9); - RAL_WRITE(sc, RT2661_TXRX_CSR9, tmp & ~0x00ffffff); - } - break; - case IEEE80211_S_RUN: - ni = ic->ic_bss; + error = rvp->ral_newstate(vap, nstate, arg); - if (ic->ic_opmode != IEEE80211_M_MONITOR) { + if (error == 0 && nstate == IEEE80211_S_RUN) { + struct ieee80211_node *ni = vap->iv_bss; + + if (vap->iv_opmode != IEEE80211_M_MONITOR) { rt2661_enable_mrr(sc); rt2661_set_txpreamble(sc); rt2661_set_basicrates(sc, &ni->ni_rates); rt2661_set_bssid(sc, ni->ni_bssid); } - if (ic->ic_opmode == IEEE80211_M_HOSTAP || - ic->ic_opmode == IEEE80211_M_IBSS) { - if ((error = rt2661_prepare_beacon(sc)) != 0) - break; + if (vap->iv_opmode == IEEE80211_M_HOSTAP || + vap->iv_opmode == IEEE80211_M_IBSS) { + error = rt2661_prepare_beacon(sc, vap); + if (error != 0) + return error; } - - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - callout_reset(&sc->rssadapt_ch, hz / 10, - rt2661_update_rssadapt, sc); + if (vap->iv_opmode != IEEE80211_M_MONITOR) { + if (vap->iv_opmode == IEEE80211_M_STA) { + /* fake a join to init the tx rate */ + rt2661_newassoc(ni, 1); + } rt2661_enable_tsf_sync(sc); } - break; - case IEEE80211_S_SCAN: - case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - default: - break; - } - - return (error != 0) ? error : sc->sc_newstate(ic, nstate, arg); + } + return error; } /* @@ -891,8 +900,7 @@ rt2661_eeprom_read(struct rt2661_softc *sc, uint8_t addr) static void rt2661_tx_intr(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct rt2661_tx_ring *txq; struct rt2661_tx_data *data; struct rt2661_node *rn; @@ -922,28 +930,28 @@ rt2661_tx_intr(struct rt2661_softc *sc) if (ni == NULL) continue; - rn = (struct rt2661_node *)ni; + rn = RT2661_NODE(ni); switch (RT2661_TX_RESULT(val)) { case RT2661_TX_SUCCESS: retrycnt = RT2661_TX_RETRYCNT(val); - DPRINTFN(10, ("data frame sent successfully after " - "%d retries\n", retrycnt)); - if (retrycnt == 0 && data->id.id_node != NULL) { - ral_rssadapt_raise_rate(ic, &rn->rssadapt, - &data->id); - } + DPRINTFN(sc, 10, "data frame sent successfully after " + "%d retries\n", retrycnt); + if (data->rix != IEEE80211_FIXED_RATE_NONE) + ieee80211_amrr_tx_complete(&rn->amrr, + IEEE80211_AMRR_SUCCESS, retrycnt); ifp->if_opackets++; break; case RT2661_TX_RETRY_FAIL: - DPRINTFN(9, ("sending data frame failed (too much " - "retries)\n")); - if (data->id.id_node != NULL) { - ral_rssadapt_lower_rate(ic, ni, - &rn->rssadapt, &data->id); - } + retrycnt = RT2661_TX_RETRYCNT(val); + + DPRINTFN(sc, 9, "%s\n", + "sending data frame failed (too much retries)"); + if (data->rix != IEEE80211_FIXED_RATE_NONE) + ieee80211_amrr_tx_complete(&rn->amrr, + IEEE80211_AMRR_FAILURE, retrycnt); ifp->if_oerrors++; break; @@ -954,7 +962,7 @@ rt2661_tx_intr(struct rt2661_softc *sc) ifp->if_oerrors++; } - DPRINTFN(15, ("tx done q=%d idx=%u\n", qid, txq->stat)); + DPRINTFN(sc, 15, "tx done q=%d idx=%u\n", qid, txq->stat); txq->queued--; if (++txq->stat >= txq->count) /* faster than % count */ @@ -969,7 +977,8 @@ rt2661_tx_intr(struct rt2661_softc *sc) sc->sc_tx_timer = 0; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - rt2661_start(ifp); + + rt2661_start_locked(ifp); } static void @@ -995,7 +1004,7 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq) /* descriptor is no longer valid */ desc->flags &= ~htole32(RT2661_TX_VALID); - DPRINTFN(15, ("tx dma done q=%p idx=%u\n", txq, txq->next)); + DPRINTFN(sc, 15, "tx dma done q=%p idx=%u\n", txq, txq->next); if (++txq->next >= txq->count) /* faster than % count */ txq->next = 0; @@ -1007,14 +1016,13 @@ rt2661_tx_dma_intr(struct rt2661_softc *sc, struct rt2661_tx_ring *txq) static void rt2661_rx_intr(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2661_rx_desc *desc; struct rt2661_rx_data *data; bus_addr_t physaddr; struct ieee80211_frame *wh; struct ieee80211_node *ni; - struct rt2661_node *rn; struct mbuf *mnew, *m; int error; @@ -1036,8 +1044,8 @@ rt2661_rx_intr(struct rt2661_softc *sc) * This should not happen since we did not request * to receive those frames when we filled TXRX_CSR0. */ - DPRINTFN(5, ("PHY or CRC error flags 0x%08x\n", - le32toh(desc->flags))); + DPRINTFN(sc, 5, "PHY or CRC error flags 0x%08x\n", + le32toh(desc->flags)); ifp->if_ierrors++; goto skip; } @@ -1098,7 +1106,7 @@ rt2661_rx_intr(struct rt2661_softc *sc) rssi = rt2661_get_rssi(sc, desc->rssi); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2661_rx_radiotap_header *tap = &sc->sc_rxtap; uint32_t tsf_lo, tsf_hi; @@ -1109,38 +1117,37 @@ rt2661_rx_intr(struct rt2661_softc *sc) tap->wr_tsf = htole64(((uint64_t)tsf_hi << 32) | tsf_lo); tap->wr_flags = 0; - tap->wr_rate = rt2661_rxrate(desc); - tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); + tap->wr_rate = ieee80211_plcp2rate(desc->rate, + le32toh(desc->flags) & RT2661_RX_OFDM); tap->wr_antsignal = rssi < 0 ? 0 : rssi; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } sc->sc_flags |= RAL_INPUT_RUNNING; RAL_UNLOCK(sc); wh = mtod(m, struct ieee80211_frame *); - ni = ieee80211_find_rxnode(ic, - (struct ieee80211_frame_min *)wh); - - /* Error happened during RSSI conversion. */ - if (rssi < 0) - rssi = ni->ni_rssi; /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, rssi, RT2661_NOISE_FLOOR, 0); + ni = ieee80211_find_rxnode(ic, + (struct ieee80211_frame_min *)wh); + if (ni != NULL) { + /* Error happened during RSSI conversion. */ + if (rssi < 0) + rssi = -30; /* XXX ignored by net80211 */ + + (void) ieee80211_input(ni, m, rssi, + RT2661_NOISE_FLOOR, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, + RT2661_NOISE_FLOOR, 0); - /* give rssi to the rate adatation algorithm */ - rn = (struct rt2661_node *)ni; RAL_LOCK(sc); sc->sc_flags &= ~RAL_INPUT_RUNNING; - ral_rssadapt_input(ic, ni, &rn->rssadapt, rssi); - - /* node is no longer needed */ - ieee80211_free_node(ni); skip: desc->flags |= htole32(RT2661_RX_BUSY); - DPRINTFN(15, ("rx intr idx=%u\n", sc->rxq.cur)); + DPRINTFN(sc, 15, "rx intr idx=%u\n", sc->rxq.cur); sc->rxq.cur = (sc->rxq.cur + 1) % RT2661_RX_RING_COUNT; } @@ -1238,137 +1245,13 @@ rt2661_intr(void *arg) RAL_UNLOCK(sc); } -/* quickly determine if a given rate is CCK or OFDM */ -#define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) - -#define RAL_ACK_SIZE 14 /* 10 + 4(FCS) */ -#define RAL_CTS_SIZE 14 /* 10 + 4(FCS) */ - -#define RAL_SIFS 10 /* us */ - -/* - * This function is only used by the Rx radiotap code. It returns the rate at - * which a given frame was received. - */ -static uint8_t -rt2661_rxrate(struct rt2661_rx_desc *desc) -{ - if (le32toh(desc->flags) & RT2661_RX_OFDM) { - /* reverse function of rt2661_plcp_signal */ - switch (desc->rate & 0xf) { - case 0xb: return 12; - case 0xf: return 18; - case 0xa: return 24; - case 0xe: return 36; - case 0x9: return 48; - case 0xd: return 72; - case 0x8: return 96; - case 0xc: return 108; - } - } else { - if (desc->rate == 10) - return 2; - if (desc->rate == 20) - return 4; - if (desc->rate == 55) - return 11; - if (desc->rate == 110) - return 22; - } - return 2; /* should not get there */ -} - -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -static int -rt2661_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - -/* - * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. - * The function automatically determines the operating mode depending on the - * given rate. `flags' indicates whether short preamble is in use or not. - */ -static uint16_t -rt2661_txtime(int len, int rate, uint32_t flags) -{ - uint16_t txtime; - - if (RAL_RATE_IS_OFDM(rate)) { - /* IEEE Std 802.11a-1999, pp. 37 */ - txtime = (8 + 4 * len + 3 + rate - 1) / rate; - txtime = 16 + 4 + 4 * txtime + 6; - } else { - /* IEEE Std 802.11b-1999, pp. 28 */ - txtime = (16 * len + rate - 1) / rate; - if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) - txtime += 72 + 24; - else - txtime += 144 + 48; - } - - return txtime; -} - -static uint8_t -rt2661_plcp_signal(int rate) -{ - switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* unsupported rates (should not get there) */ - default: return 0xff; - } -} - static void rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate, const bus_dma_segment_t *segs, int nsegs, int ac) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int i, remainder; @@ -1393,11 +1276,11 @@ rt2661_setup_tx_desc(struct rt2661_softc *sc, struct rt2661_tx_desc *desc, desc->qid = ac; /* setup PLCP fields */ - desc->plcp_signal = rt2661_plcp_signal(rate); + desc->plcp_signal = ieee80211_rate2plcp(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; - if (RAL_RATE_IS_OFDM(rate)) { + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { desc->flags |= htole32(RT2661_TX_OFDM); plcp_length = len & 0xfff; @@ -1428,7 +1311,9 @@ static int rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; struct ieee80211_frame *wh; @@ -1441,13 +1326,12 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, desc = &sc->mgtq.desc[sc->mgtq.cur]; data = &sc->mgtq.data[sc->mgtq.cur]; - /* send mgt frames at the lowest available rate */ - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; + rate = vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)].mgmtrate; wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1463,27 +1347,27 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, return error; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); - tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; + /* management frames are not taken into account for amrr */ + data->rix = IEEE80211_FIXED_RATE_NONE; wh = mtod(m0, struct ieee80211_frame *); if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2661_TX_NEED_ACK; - dur = rt2661_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) + - RAL_SIFS; + dur = ieee80211_ack_duration(sc->sc_rates, + rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); /* tell hardware to add timestamp in probe responses */ @@ -1500,8 +1384,8 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, bus_dmamap_sync(sc->mgtq.desc_dmat, sc->mgtq.desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(10, ("sending mgt frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, sc->mgtq.cur, rate)); + DPRINTFN(sc, 10, "sending mgt frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, sc->mgtq.cur, rate); /* kick mgt */ sc->mgtq.queued++; @@ -1511,67 +1395,108 @@ rt2661_tx_mgt(struct rt2661_softc *sc, struct mbuf *m0, return 0; } -/* - * Build a RTS control frame. - */ -static struct mbuf * -rt2661_get_rts(struct rt2661_softc *sc, struct ieee80211_frame *wh, - uint16_t dur) +static int +rt2661_sendprot(struct rt2661_softc *sc, int ac, + const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) { - struct ieee80211_frame_rts *rts; - struct mbuf *m; + struct ieee80211com *ic = ni->ni_ic; + struct rt2661_tx_ring *txq = &sc->txq[ac]; + const struct ieee80211_frame *wh; + struct rt2661_tx_desc *desc; + struct rt2661_tx_data *data; + struct mbuf *mprot; + int protrate, ackrate, pktlen, flags, isshort, error; + uint16_t dur; + bus_dma_segment_t segs[RT2661_MAX_SCATTER]; + int nsegs; - MGETHDR(m, M_DONTWAIT, MT_DATA); - if (m == NULL) { - sc->sc_ic.ic_stats.is_tx_nobuf++; - device_printf(sc->sc_dev, "could not allocate RTS frame\n"); - return NULL; + KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, + ("protection %d", prot)); + + wh = mtod(m, const struct ieee80211_frame *); + pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + + protrate = ieee80211_ctl_rate(sc->sc_rates, rate); + ackrate = ieee80211_ack_rate(sc->sc_rates, rate); + + isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); + + ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags = RT2661_TX_MORE_FRAG; + if (prot == IEEE80211_PROT_RTSCTS) { + /* NB: CTS is the same size as an ACK */ + dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags |= RT2661_TX_NEED_ACK; + mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); + } else { + mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); + } + if (mprot == NULL) { + /* XXX stat + msg */ + return ENOBUFS; + } + + data = &txq->data[txq->cur]; + desc = &txq->desc[txq->cur]; + + error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, mprot, segs, + &nsegs, 0); + if (error != 0) { + device_printf(sc->sc_dev, + "could not map mbuf (error %d)\n", error); + m_freem(mprot); + return error; } - rts = mtod(m, struct ieee80211_frame_rts *); + data->m = mprot; + data->ni = ieee80211_ref_node(ni); + /* ctl frames are not taken into account for amrr */ + data->rix = IEEE80211_FIXED_RATE_NONE; + + rt2661_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, + protrate, segs, 1, ac); - rts->i_fc[0] = IEEE80211_FC0_VERSION_0 | IEEE80211_FC0_TYPE_CTL | - IEEE80211_FC0_SUBTYPE_RTS; - rts->i_fc[1] = IEEE80211_FC1_DIR_NODS; - *(uint16_t *)rts->i_dur = htole16(dur); - IEEE80211_ADDR_COPY(rts->i_ra, wh->i_addr1); - IEEE80211_ADDR_COPY(rts->i_ta, wh->i_addr2); + bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_PREWRITE); + bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE); - m->m_pkthdr.len = m->m_len = sizeof (struct ieee80211_frame_rts); + txq->queued++; + txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT; - return m; + return 0; } static int rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rt2661_tx_ring *txq = &sc->txq[ac]; struct rt2661_tx_desc *desc; struct rt2661_tx_data *data; - struct rt2661_node *rn; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; const struct chanAccParams *cap; struct mbuf *mnew; bus_dma_segment_t segs[RT2661_MAX_SCATTER]; uint16_t dur; - uint32_t flags = 0; + uint32_t flags; int error, nsegs, rate, noack = 0; wh = mtod(m0, struct ieee80211_frame *); - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { - rate = ic->ic_fixed_rate; + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { + rate = tp->mcastrate; + } else if (m0->m_flags & M_EAPOL) { + rate = tp->mgmtrate; + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; } else { - struct ieee80211_rateset *rs; - - rs = &ni->ni_rates; - rn = (struct rt2661_node *)ni; - ni->ni_txrate = ral_rssadapt_choose(&rn->rssadapt, rs, - wh, m0->m_pkthdr.len, NULL, 0); - rate = rs->rs_rates[ni->ni_txrate]; + (void) ieee80211_amrr_choose(ni, &RT2661_NODE(ni)->amrr); + rate = ni->ni_txrate; } rate &= IEEE80211_RATE_VAL; @@ -1581,7 +1506,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, } if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1591,66 +1516,22 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } - /* - * IEEE Std 802.11-1999, pp 82: "A STA shall use an RTS/CTS exchange - * for directed frames only when the length of the MPDU is greater - * than the length threshold indicated by [...]" ic_rtsthreshold. - */ - if (!IEEE80211_IS_MULTICAST(wh->i_addr1) && - m0->m_pkthdr.len > ic->ic_rtsthreshold) { - struct mbuf *m; - uint16_t dur; - int rtsrate, ackrate; - - rtsrate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - ackrate = rt2661_ack_rate(ic, rate); - - dur = rt2661_txtime(m0->m_pkthdr.len + 4, rate, ic->ic_flags) + - rt2661_txtime(RAL_CTS_SIZE, rtsrate, ic->ic_flags) + - /* XXX: noack (QoS)? */ - rt2661_txtime(RAL_ACK_SIZE, ackrate, ic->ic_flags) + - 3 * RAL_SIFS; - - m = rt2661_get_rts(sc, wh, dur); - - desc = &txq->desc[txq->cur]; - data = &txq->data[txq->cur]; - - error = bus_dmamap_load_mbuf_sg(txq->data_dmat, data->map, m, - segs, &nsegs, 0); - if (error != 0) { - device_printf(sc->sc_dev, - "could not map mbuf (error %d)\n", error); - m_freem(m); - m_freem(m0); - return error; + flags = 0; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + int prot = IEEE80211_PROT_NONE; + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) + prot = IEEE80211_PROT_RTSCTS; + else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) + prot = ic->ic_protmode; + if (prot != IEEE80211_PROT_NONE) { + error = rt2661_sendprot(sc, ac, m0, ni, prot, rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2661_TX_LONG_RETRY | RT2661_TX_IFS; } - - /* avoid multiple free() of the same node for each fragment */ - ieee80211_ref_node(ni); - - data->m = m; - data->ni = ni; - - /* RTS frames are not taken into account for rssadapt */ - data->id.id_node = NULL; - - rt2661_setup_tx_desc(sc, desc, RT2661_TX_NEED_ACK | - RT2661_TX_MORE_FRAG, 0, m->m_pkthdr.len, rtsrate, segs, - nsegs, ac); - - bus_dmamap_sync(txq->data_dmat, data->map, - BUS_DMASYNC_PREWRITE); - - txq->queued++; - txq->cur = (txq->cur + 1) % RT2661_TX_RING_COUNT; - - /* - * IEEE Std 802.11-1999: when an RTS/CTS exchange is used, the - * asynchronous data frame shall be transmitted after the CTS - * frame and a SIFS period. - */ - flags |= RT2661_TX_LONG_RETRY | RT2661_TX_IFS; } data = &txq->data[txq->cur]; @@ -1687,7 +1568,7 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, wh = mtod(m0, struct ieee80211_frame *); } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rt2661_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1695,26 +1576,25 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; /* remember link conditions for rate adaptation algorithm */ - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { - data->id.id_len = m0->m_pkthdr.len; - data->id.id_rateidx = ni->ni_txrate; - data->id.id_node = ni; - data->id.id_rssi = ni->ni_rssi; + if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) { + data->rix = ni->ni_txrate; + /* XXX probably need last rssi value and not avg */ + data->rssi = ic->ic_node_getrssi(ni); } else - data->id.id_node = NULL; + data->rix = IEEE80211_FIXED_RATE_NONE; if (!noack && !IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2661_TX_NEED_ACK; - dur = rt2661_txtime(RAL_ACK_SIZE, rt2661_ack_rate(ic, rate), - ic->ic_flags) + RAL_SIFS; + dur = ieee80211_ack_duration(sc->sc_rates, + rate, ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); } @@ -1724,8 +1604,8 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, bus_dmamap_sync(txq->data_dmat, data->map, BUS_DMASYNC_PREWRITE); bus_dmamap_sync(txq->desc_dmat, txq->desc_map, BUS_DMASYNC_PREWRITE); - DPRINTFN(10, ("sending data frame len=%u idx=%u rate=%u\n", - m0->m_pkthdr.len, txq->cur, rate)); + DPRINTFN(sc, 10, "sending data frame len=%u idx=%u rate=%u\n", + m0->m_pkthdr.len, txq->cur, rate); /* kick Tx */ txq->queued++; @@ -1736,181 +1616,163 @@ rt2661_tx_data(struct rt2661_softc *sc, struct mbuf *m0, } static void -rt2661_start(struct ifnet *ifp) +rt2661_start_locked(struct ifnet *ifp) { struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct mbuf *m0; - struct ether_header *eh; + struct mbuf *m; struct ieee80211_node *ni; int ac; - RAL_LOCK(sc); + RAL_LOCK_ASSERT(sc); /* prevent management frames from being sent if we're not ready */ - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid) { - RAL_UNLOCK(sc); + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || sc->sc_invalid) return; - } for (;;) { - IF_POLL(&ic->ic_mgtq, m0); - if (m0 != NULL) { - if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IF_DEQUEUE(&ic->ic_mgtq, m0); - - ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; - if (rt2661_tx_mgt(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - break; - } - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; + ac = M_WME_GETAC(m); + if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) { + /* there is no place left in this ring */ + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; + } - if (m0->m_len < sizeof (struct ether_header) && - !(m0 = m_pullup(m0, sizeof (struct ether_header)))) - continue; + if (rt2661_tx_data(sc, m, ni, ac) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; + } - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - ifp->if_oerrors++; - continue; - } + sc->sc_tx_timer = 5; + } +} - /* classify mbuf so we can find which tx ring to use */ - if (ieee80211_classify(ic, m0, ni) != 0) { - m_freem(m0); - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } +static void +rt2661_start(struct ifnet *ifp) +{ + struct rt2661_softc *sc = ifp->if_softc; - /* no QoS encapsulation for EAPOL frames */ - ac = (eh->ether_type != htons(ETHERTYPE_PAE)) ? - M_WME_GETAC(m0) : WME_AC_BE; + RAL_LOCK(sc); + rt2661_start_locked(ifp); + RAL_UNLOCK(sc); +} - if (sc->txq[ac].queued >= RT2661_TX_RING_COUNT - 1) { - /* there is no place left in this ring */ - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - ieee80211_free_node(ni); - break; - } +static int +rt2661_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; + struct rt2661_softc *sc = ifp->if_softc; - BPF_MTAP(ifp, m0); + RAL_LOCK(sc); - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } + /* prevent management frames from being sent if we're not ready */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + RAL_UNLOCK(sc); + m_freem(m); + ieee80211_free_node(ni); + return ENETDOWN; + } + if (sc->mgtq.queued >= RT2661_MGT_RING_COUNT) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + RAL_UNLOCK(sc); + m_freem(m); + ieee80211_free_node(ni); + return ENOBUFS; /* XXX */ + } - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); + ifp->if_opackets++; - if (rt2661_tx_data(sc, m0, ni, ac) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } - } + /* + * Legacy path; interpret frame contents to decide + * precisely how to send the frame. + * XXX raw path + */ + if (rt2661_tx_mgt(sc, m, ni) != 0) + goto bad; + sc->sc_tx_timer = 5; - sc->sc_tx_timer = 5; - ic->ic_lastdata = ticks; - callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); - } + RAL_UNLOCK(sc); + return 0; +bad: + ifp->if_oerrors++; + ieee80211_free_node(ni); RAL_UNLOCK(sc); + return EIO; /* XXX */ } static void rt2661_watchdog(void *arg) { struct rt2661_softc *sc = (struct rt2661_softc *)arg; + struct ifnet *ifp = sc->sc_ifp; - if (sc->sc_tx_timer > 0 && !sc->sc_invalid) { - if (--sc->sc_tx_timer == 0) { - device_printf(sc->sc_dev, "device timeout\n"); - rt2661_init(sc); - sc->sc_ifp->if_oerrors++; - return; - } - callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); - } -} + RAL_LOCK_ASSERT(sc); -/* - * This function allows for fast channel switching in monitor mode (used by - * net-mgmt/kismet). In IBSS mode, we must explicitly reset the interface to - * generate a new beacon frame. - */ -static int -rt2661_reset(struct ifnet *ifp) -{ - struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - - if (ic->ic_opmode != IEEE80211_M_MONITOR) - return ENETRESET; + KASSERT(ifp->if_drv_flags & IFF_DRV_RUNNING, ("not running")); - rt2661_set_chan(sc, ic->ic_curchan); + if (sc->sc_invalid) /* card ejected */ + return; - return 0; + if (sc->sc_tx_timer > 0 && --sc->sc_tx_timer == 0) { + if_printf(ifp, "device timeout\n"); + rt2661_init_locked(sc); + ifp->if_oerrors++; + /* NB: callout is reset in rt2661_init() */ + return; + } + callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); } static int rt2661_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; + RAL_LOCK(sc); switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2661_update_promisc(sc); - else - rt2661_init(sc); + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + rt2661_init_locked(sc); + startall = 1; + } else + rt2661_update_promisc(ifp); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rt2661_stop(sc); + rt2661_stop_locked(sc); } break; - + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - rt2661_init(sc); - error = 0; + error = ether_ioctl(ifp, cmd, data); + break; } + RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } @@ -1933,7 +1795,7 @@ rt2661_bbp_write(struct rt2661_softc *sc, uint8_t reg, uint8_t val) tmp = RT2661_BBP_BUSY | (reg & 0x7f) << 8 | val; RAL_WRITE(sc, RT2661_PHY_CSR3, tmp); - DPRINTFN(15, ("BBP R%u <- 0x%02x\n", reg, val)); + DPRINTFN(sc, 15, "BBP R%u <- 0x%02x\n", reg, val); } static uint8_t @@ -1989,7 +1851,7 @@ rt2661_rf_write(struct rt2661_softc *sc, uint8_t reg, uint32_t val) /* remember last written value in sc */ sc->rf_regs[reg] = val; - DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff)); + DPRINTFN(sc, 15, "RF R[%u] <- 0x%05x\n", reg & 3, val & 0x1fffff); } static int @@ -2035,13 +1897,14 @@ rt2661_select_antenna(struct rt2661_softc *sc) static void rt2661_enable_mrr(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); tmp &= ~RT2661_MRR_CCK_FALLBACK; - if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) + if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) tmp |= RT2661_MRR_CCK_FALLBACK; tmp |= RT2661_MRR_ENABLED; @@ -2051,29 +1914,26 @@ rt2661_enable_mrr(struct rt2661_softc *sc) static void rt2661_set_txpreamble(struct rt2661_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR4); tmp &= ~RT2661_SHORT_PREAMBLE; - if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE) + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) tmp |= RT2661_SHORT_PREAMBLE; RAL_WRITE(sc, RT2661_TXRX_CSR4, tmp); } -/* - * Supported rates for 802.11g. XXX should use ic_sup_rates. - */ -static const struct ieee80211_rateset rt2661_rateset_11g = - { 12, { 2, 4, 11, 22, 12, 18, 24, 36, 48, 72, 96, 108 } }; - static void rt2661_set_basicrates(struct rt2661_softc *sc, const struct ieee80211_rateset *rs) { #define RV(r) ((r) & IEEE80211_RATE_VAL) - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t mask = 0; uint8_t rate; int i, j; @@ -2095,7 +1955,7 @@ rt2661_set_basicrates(struct rt2661_softc *sc, RAL_WRITE(sc, RT2661_TXRX_CSR5, mask); - DPRINTF(("Setting basic rate mask to 0x%x\n", mask)); + DPRINTF(sc, "Setting basic rate mask to 0x%x\n", mask); #undef RV } @@ -2148,15 +2008,17 @@ rt2661_select_band(struct rt2661_softc *sc, struct ieee80211_channel *c) static void rt2661_set_chan(struct rt2661_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2661_BBPR94_DEFAULT; int8_t power; u_int i, chan; chan = ieee80211_chan2ieee(ic, c); - if (chan == 0 || chan == IEEE80211_CHAN_ANY) - return; + KASSERT(chan != 0 && chan != IEEE80211_CHAN_ANY, ("chan 0x%x", chan)); + + sc->sc_rates = ieee80211_get_ratetable(c); /* select the appropriate RF settings based on what EEPROM says */ rfprog = (sc->rfprog == 0) ? rt2661_rf5225_1 : rt2661_rf5225_2; @@ -2244,9 +2106,9 @@ rt2661_set_macaddr(struct rt2661_softc *sc, const uint8_t *addr) } static void -rt2661_update_promisc(struct rt2661_softc *sc) +rt2661_update_promisc(struct ifnet *ifp) { - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct rt2661_softc *sc = ifp->if_softc; uint32_t tmp; tmp = RAL_READ(sc, RT2661_TXRX_CSR0); @@ -2257,8 +2119,8 @@ rt2661_update_promisc(struct rt2661_softc *sc) RAL_WRITE(sc, RT2661_TXRX_CSR0, tmp); - DPRINTF(("%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? - "entering" : "leaving")); + DPRINTF(sc, "%s promiscuous mode\n", (ifp->if_flags & IFF_PROMISC) ? + "entering" : "leaving"); } /* @@ -2311,7 +2173,7 @@ static void rt2661_update_slot(struct ifnet *ifp) { struct rt2661_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; uint8_t slottime; uint32_t tmp; @@ -2335,9 +2197,8 @@ rt2661_get_rf(int rev) } static void -rt2661_read_eeprom(struct rt2661_softc *sc) +rt2661_read_eeprom(struct rt2661_softc *sc, struct ieee80211com *ic) { - struct ieee80211com *ic = &sc->sc_ic; uint16_t val; int i; @@ -2362,14 +2223,14 @@ rt2661_read_eeprom(struct rt2661_softc *sc) sc->tx_ant = (val >> 2) & 0x3; sc->nb_ant = val & 0x3; - DPRINTF(("RF revision=%d\n", sc->rf_rev)); + DPRINTF(sc, "RF revision=%d\n", sc->rf_rev); val = rt2661_eeprom_read(sc, RT2661_EEPROM_CONFIG2); sc->ext_5ghz_lna = (val >> 6) & 0x1; sc->ext_2ghz_lna = (val >> 4) & 0x1; - DPRINTF(("External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", - sc->ext_2ghz_lna, sc->ext_5ghz_lna)); + DPRINTF(sc, "External 2GHz LNA=%d\nExternal 5GHz LNA=%d\n", + sc->ext_2ghz_lna, sc->ext_5ghz_lna); val = rt2661_eeprom_read(sc, RT2661_EEPROM_RSSI_2GHZ_OFFSET); if ((val & 0xff) != 0xff) @@ -2393,8 +2254,8 @@ rt2661_read_eeprom(struct rt2661_softc *sc) if (sc->ext_5ghz_lna) sc->rssi_5ghz_corr -= 14; - DPRINTF(("RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", - sc->rssi_2ghz_corr, sc->rssi_5ghz_corr)); + DPRINTF(sc, "RSSI 2GHz corr=%d\nRSSI 5GHz corr=%d\n", + sc->rssi_2ghz_corr, sc->rssi_5ghz_corr); val = rt2661_eeprom_read(sc, RT2661_EEPROM_FREQ_OFFSET); if ((val >> 8) != 0xff) @@ -2402,17 +2263,17 @@ rt2661_read_eeprom(struct rt2661_softc *sc) if ((val & 0xff) != 0xff) sc->rffreq = val & 0xff; - DPRINTF(("RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq)); + DPRINTF(sc, "RF prog=%d\nRF freq=%d\n", sc->rfprog, sc->rffreq); /* read Tx power for all a/b/g channels */ for (i = 0; i < 19; i++) { val = rt2661_eeprom_read(sc, RT2661_EEPROM_TXPOWER + i); sc->txpow[i * 2] = (int8_t)(val >> 8); /* signed */ - DPRINTF(("Channel=%d Tx power=%d\n", - rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2])); + DPRINTF(sc, "Channel=%d Tx power=%d\n", + rt2661_rf5225_1[i * 2].chan, sc->txpow[i * 2]); sc->txpow[i * 2 + 1] = (int8_t)(val & 0xff); /* signed */ - DPRINTF(("Channel=%d Tx power=%d\n", - rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1])); + DPRINTF(sc, "Channel=%d Tx power=%d\n", + rt2661_rf5225_1[i * 2 + 1].chan, sc->txpow[i * 2 + 1]); } /* read vendor-specific BBP values */ @@ -2422,8 +2283,8 @@ rt2661_read_eeprom(struct rt2661_softc *sc) continue; /* skip invalid entries */ sc->bbp_prom[i].reg = val >> 8; sc->bbp_prom[i].val = val & 0xff; - DPRINTF(("BBP R%d=%02x\n", sc->bbp_prom[i].reg, - sc->bbp_prom[i].val)); + DPRINTF(sc, "BBP R%d=%02x\n", sc->bbp_prom[i].reg, + sc->bbp_prom[i].val); } } @@ -2464,16 +2325,26 @@ rt2661_bbp_init(struct rt2661_softc *sc) } static void -rt2661_init(void *priv) +rt2661_init_locked(struct rt2661_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct rt2661_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp, sta[3]; - int i, ntries; + int i, error, ntries; - RAL_LOCK(sc); + RAL_LOCK_ASSERT(sc); + + if ((sc->sc_flags & RAL_FW_LOADED) == 0) { + error = rt2661_load_microcode(sc); + if (error != 0) { + if_printf(ifp, + "%s: could not load 8051 microcode, error %d\n", + __func__, error); + return; + } + sc->sc_flags |= RAL_FW_LOADED; + } rt2661_stop_locked(sc); @@ -2536,13 +2407,11 @@ rt2661_init(void *priv) if (ntries == 1000) { printf("timeout waiting for BBP/RF to wakeup\n"); rt2661_stop_locked(sc); - RAL_UNLOCK(sc); return; } if (rt2661_bbp_init(sc) != 0) { rt2661_stop_locked(sc); - RAL_UNLOCK(sc); return; } @@ -2582,49 +2451,44 @@ rt2661_init(void *priv) /* kick Rx */ RAL_WRITE(sc, RT2661_RX_CNTL_CSR, 1); - RAL_UNLOCK(sc); ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - - + callout_reset(&sc->watchdog_ch, hz, rt2661_watchdog, sc); #undef N } -void -rt2661_stop(void *priv) +static void +rt2661_init(void *priv) { struct rt2661_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; RAL_LOCK(sc); - rt2661_stop_locked(sc); + rt2661_init_locked(sc); RAL_UNLOCK(sc); + + ieee80211_start_all(ic); } void rt2661_stop_locked(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; volatile int *flags = &sc->sc_flags; - while (*flags & RAL_INPUT_RUNNING) { + while (*flags & RAL_INPUT_RUNNING) msleep(sc, &sc->sc_mtx, 0, "ralrunning", hz/10); - } + + callout_stop(&sc->watchdog_ch); + sc->sc_tx_timer = 0; if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - sc->sc_tx_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - + /* abort Tx (for all 5 Tx rings) */ RAL_WRITE(sc, RT2661_TX_CNTL_CSR, 0x1f << 16); @@ -2654,11 +2518,48 @@ rt2661_stop_locked(struct rt2661_softc *sc) } } +void +rt2661_stop(void *priv) +{ + struct rt2661_softc *sc = priv; + + RAL_LOCK(sc); + rt2661_stop_locked(sc); + RAL_UNLOCK(sc); +} + static int -rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode, int size) +rt2661_load_microcode(struct rt2661_softc *sc) { - int ntries; + struct ifnet *ifp = sc->sc_ifp; + const struct firmware *fp; + const char *imagename; + int ntries, error; + + RAL_LOCK_ASSERT(sc); + + switch (sc->sc_id) { + case 0x0301: imagename = "rt2561sfw"; break; + case 0x0302: imagename = "rt2561fw"; break; + case 0x0401: imagename = "rt2661fw"; break; + default: + if_printf(ifp, "%s: unexpected pci device id 0x%x, " + "don't know how to retrieve firmware\n", + __func__, sc->sc_id); + return EINVAL; + } + RAL_UNLOCK(sc); + fp = firmware_get(imagename); + RAL_LOCK(sc); + if (fp == NULL) { + if_printf(ifp, "%s: unable to retrieve firmware image %s\n", + __func__, imagename); + return EINVAL; + } + /* + * Load 8051 microcode into NIC. + */ /* reset 8051 */ RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET); @@ -2669,7 +2570,7 @@ rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode, int size) /* write 8051's microcode */ RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET | RT2661_MCU_SEL); - RAL_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, ucode, size); + RAL_WRITE_REGION_1(sc, RT2661_MCU_CODE_BASE, fp->data, fp->datasize); RAL_WRITE(sc, RT2661_MCU_CNTL_CSR, RT2661_MCU_RESET); /* kick 8051's ass */ @@ -2682,10 +2583,14 @@ rt2661_load_microcode(struct rt2661_softc *sc, const uint8_t *ucode, int size) DELAY(100); } if (ntries == 500) { - printf("timeout waiting for MCU to initialize\n"); - return EIO; - } - return 0; + if_printf(ifp, "%s: timeout waiting for MCU to initialize\n", + __func__); + error = EIO; + } else + error = 0; + + firmware_put(fp, FIRMWARE_UNLOAD); + return error; } #ifdef notyet @@ -2808,22 +2713,22 @@ rt2661_radar_stop(struct rt2661_softc *sc) #endif static int -rt2661_prepare_beacon(struct rt2661_softc *sc) +rt2661_prepare_beacon(struct rt2661_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = vap->iv_ic; struct ieee80211_beacon_offsets bo; struct rt2661_tx_desc desc; struct mbuf *m0; int rate; - m0 = ieee80211_beacon_alloc(ic->ic_bss, &bo); + m0 = ieee80211_beacon_alloc(vap->iv_bss, &bo); if (m0 == NULL) { device_printf(sc->sc_dev, "could not allocate beacon frame\n"); return ENOBUFS; } /* send beacons at the lowest available rate */ - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan) ? 12 : 2; + rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan) ? 12 : 2; rt2661_setup_tx_desc(sc, &desc, RT2661_TX_TIMESTAMP, RT2661_TX_HWSEQ, m0->m_pkthdr.len, rate, NULL, 0, RT2661_QID_MGT); @@ -2847,10 +2752,12 @@ rt2661_prepare_beacon(struct rt2661_softc *sc) static void rt2661_enable_tsf_sync(struct rt2661_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; - if (ic->ic_opmode != IEEE80211_M_STA) { + if (vap->iv_opmode != IEEE80211_M_STA) { /* * Change default 16ms TBTT adjustment to 8ms. * Must be done before enabling beacon generation. @@ -2861,10 +2768,10 @@ rt2661_enable_tsf_sync(struct rt2661_softc *sc) tmp = RAL_READ(sc, RT2661_TXRX_CSR9) & 0xff000000; /* set beacon interval (in 1/16ms unit) */ - tmp |= ic->ic_bss->ni_intval * 16; + tmp |= vap->iv_bss->ni_intval * 16; tmp |= RT2661_TSF_TICKING | RT2661_ENABLE_TBTT; - if (ic->ic_opmode == IEEE80211_M_STA) + if (vap->iv_opmode == IEEE80211_M_STA) tmp |= RT2661_TSF_MODE(1); else tmp |= RT2661_TSF_MODE(2) | RT2661_GENERATE_BEACON; @@ -2937,10 +2844,11 @@ rt2661_scan_end(struct ieee80211com *ic) { struct ifnet *ifp = ic->ic_ifp; struct rt2661_softc *sc = ifp->if_softc; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); rt2661_enable_tsf_sync(sc); /* XXX keep local copy */ - rt2661_set_bssid(sc, ic->ic_bss->ni_bssid); + rt2661_set_bssid(sc, vap->iv_bss->ni_bssid); } static void @@ -2951,6 +2859,11 @@ rt2661_set_channel(struct ieee80211com *ic) RAL_LOCK(sc); rt2661_set_chan(sc, ic->ic_curchan); + + sc->sc_txtap.wt_chan_freq = htole16(ic->ic_curchan->ic_freq); + sc->sc_txtap.wt_chan_flags = htole16(ic->ic_curchan->ic_flags); + sc->sc_rxtap.wr_chan_freq = htole16(ic->ic_curchan->ic_freq); + sc->sc_rxtap.wr_chan_flags = htole16(ic->ic_curchan->ic_flags); RAL_UNLOCK(sc); } diff --git a/sys/dev/ral/rt2661_ucode.h b/sys/dev/ral/rt2661_ucode.h deleted file mode 100644 index 556ac5f..0000000 --- a/sys/dev/ral/rt2661_ucode.h +++ /dev/null @@ -1,2268 +0,0 @@ -/* $FreeBSD$ */ -/* OpenBSD: microcode.h,v 1.1 2006/01/09 20:03:40 damien Exp */ - -/*- - * Copyright (c) 2005-2006, Ralink Technology, Corp. - * Paul Lin - * - * Permission to use, copy, modify, and distribute this software for any - * purpose with or without fee is hereby granted, provided that the above - * copyright notice and this permission notice appear in all copies. - * - * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES - * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR - * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES - * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN - * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF - * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. - */ - -/* - * This file contains the loadable 8051 microcodes for the Ralink RT2561, - * RT2561S and RT2661 chipsets. - */ - -static const uint8_t rt2561_ucode[] = { - 0x02, 0x1c, 0x12, 0x02, 0x13, 0xcb, 0xc2, 0x8c, 0x22, 0x22, 0x00, - 0x02, 0x16, 0x0f, 0xc2, 0xaf, 0xc2, 0x8d, 0x75, 0x8c, 0x94, 0x75, - 0x8a, 0x93, 0xd2, 0xaf, 0x22, 0x02, 0x18, 0xda, 0x12, 0x1b, 0xe8, - 0x40, 0x03, 0x02, 0x02, 0x1e, 0x90, 0x21, 0x02, 0xe0, 0xf5, 0x2d, - 0x90, 0x00, 0x03, 0xe0, 0x12, 0x08, 0x25, 0x00, 0xb0, 0x00, 0x00, - 0xce, 0x01, 0x00, 0x5e, 0x10, 0x00, 0x6f, 0x11, 0x00, 0xf2, 0x20, - 0x01, 0x4d, 0x21, 0x01, 0x70, 0x22, 0x01, 0x84, 0x30, 0x01, 0x8f, - 0x31, 0x01, 0xd5, 0x50, 0x01, 0x9f, 0x51, 0x01, 0xf2, 0x52, 0x02, - 0x06, 0x60, 0x00, 0x00, 0x02, 0x14, 0x90, 0x00, 0x0a, 0xe0, 0x20, - 0xe5, 0x03, 0x30, 0x07, 0x03, 0xd2, 0x08, 0x22, 0x12, 0x17, 0xa5, - 0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x11, 0xe5, 0x11, 0xc4, 0x33, - 0x54, 0xe0, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, - 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24, - 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x11, 0xf0, - 0xc4, 0x33, 0x54, 0xe0, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x21, - 0xf5, 0x83, 0xe5, 0x2d, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, - 0x12, 0x11, 0x31, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x31, 0x60, 0x05, - 0x12, 0x1b, 0x8a, 0x80, 0x03, 0x12, 0x1b, 0x3d, 0xe4, 0x90, 0x21, - 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, 0x22, 0x75, 0x31, 0xff, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, - 0x54, 0xfe, 0xf0, 0x54, 0x3e, 0xf0, 0xe4, 0x90, 0x00, 0x0b, 0xf0, - 0xf0, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, 0x22, - 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x04, 0x0e, 0x90, 0x34, - 0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x21, 0x14, 0x12, 0x08, 0x01, - 0x90, 0x34, 0xc0, 0x12, 0x08, 0x0d, 0x90, 0x21, 0x18, 0x12, 0x08, - 0x01, 0x90, 0x34, 0xc8, 0x12, 0x08, 0x0d, 0x90, 0x21, 0x1c, 0x12, - 0x08, 0x01, 0x90, 0x34, 0xc4, 0x12, 0x08, 0x0d, 0x90, 0x34, 0xcc, - 0x74, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x01, - 0xe0, 0x44, 0x01, 0xf0, 0x44, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, - 0x44, 0x10, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x1c, 0x62, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, - 0x01, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x54, 0xbf, 0xf0, 0x90, 0x00, - 0x0b, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, - 0x2d, 0x12, 0x1c, 0x62, 0x22, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, - 0x12, 0x04, 0x0e, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x1c, 0x62, 0x22, 0xd2, 0x05, 0x85, 0x2d, 0x23, 0xe4, 0x90, 0x21, - 0x03, 0xf0, 0x22, 0x12, 0x1a, 0x74, 0xc2, 0x00, 0xe4, 0x90, 0x21, - 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, 0x22, 0x85, 0x2d, 0x25, - 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xff, 0xf0, 0xe4, 0x90, 0x00, - 0x07, 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x00, - 0x08, 0xf0, 0x90, 0x21, 0x00, 0xe0, 0x90, 0x00, 0x09, 0xf0, 0x90, - 0x00, 0x07, 0x74, 0x71, 0xf0, 0xef, 0x44, 0x04, 0x90, 0x00, 0x0b, - 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, 0x90, 0x21, 0x00, 0xe0, - 0xff, 0x54, 0x1f, 0xf5, 0x30, 0xa3, 0xe0, 0xf5, 0x27, 0x8f, 0x26, - 0x12, 0x08, 0x90, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x1c, 0x62, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x2c, 0x12, 0x18, - 0x13, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0x62, - 0x22, 0x12, 0x19, 0x53, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, - 0x12, 0x1c, 0x62, 0x22, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, - 0x12, 0x1c, 0x62, 0x22, 0x8e, 0x15, 0x8f, 0x16, 0xca, 0xed, 0xca, - 0xc9, 0xeb, 0xc9, 0x30, 0x0a, 0x04, 0x7f, 0x4a, 0x80, 0x02, 0x7f, - 0x42, 0xcb, 0xef, 0xcb, 0xea, 0xc3, 0x94, 0x04, 0x50, 0x02, 0x80, - 0x01, 0xc3, 0x40, 0x04, 0xcb, 0x44, 0x20, 0xcb, 0x85, 0x16, 0x82, - 0x85, 0x15, 0x83, 0xeb, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x16, 0x82, - 0x85, 0x15, 0x83, 0xa3, 0xa3, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0x85, - 0x16, 0x82, 0x85, 0x15, 0x83, 0xa3, 0xa3, 0xa3, 0xf0, 0xe5, 0x16, - 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x0f, - 0xf0, 0xe5, 0x16, 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, - 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, - 0x15, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x24, 0x07, 0xf5, 0x82, - 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xea, 0x90, 0x1a, - 0x9c, 0x93, 0xfb, 0xea, 0x64, 0x01, 0x60, 0x08, 0xea, 0x64, 0x02, - 0x60, 0x03, 0xba, 0x03, 0x04, 0xcb, 0x44, 0x08, 0xcb, 0xe5, 0x16, - 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xeb, 0xf0, - 0xe5, 0x16, 0x24, 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, - 0x74, 0xff, 0xf0, 0xe5, 0x16, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35, - 0x15, 0xf5, 0x83, 0xe9, 0xf0, 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82, - 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x04, 0xf0, 0x25, 0x1a, 0xf5, - 0x1a, 0xe4, 0x35, 0x19, 0xf5, 0x19, 0xea, 0xc3, 0x94, 0x04, 0x40, - 0x03, 0x02, 0x03, 0xd6, 0xea, 0x60, 0x03, 0xba, 0x01, 0x1f, 0xea, - 0x24, 0x01, 0xfd, 0xe4, 0x33, 0xfc, 0xe5, 0x1a, 0xae, 0x19, 0x78, - 0x03, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x12, 0x07, - 0x96, 0x8e, 0x19, 0x8f, 0x1a, 0x02, 0x03, 0xb6, 0xea, 0x24, 0xff, - 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x07, - 0x84, 0xcc, 0xee, 0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, - 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48, - 0xfe, 0x12, 0x07, 0x96, 0x8c, 0x1b, 0x8d, 0x1c, 0xea, 0x24, 0xff, - 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x07, - 0x84, 0xcc, 0xee, 0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, - 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48, - 0xfe, 0x12, 0x07, 0x96, 0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1c, 0x45, - 0x1b, 0x60, 0x08, 0x05, 0x1a, 0xe5, 0x1a, 0x70, 0x02, 0x05, 0x19, - 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, - 0x03, 0x12, 0x07, 0x84, 0xd3, 0xe5, 0x1c, 0x9f, 0xe5, 0x1b, 0x9e, - 0x50, 0x18, 0xe5, 0x1c, 0x45, 0x1b, 0x60, 0x12, 0xba, 0x03, 0x0f, - 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, - 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, 0xe4, - 0x35, 0x15, 0xf5, 0x83, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0xff, 0xe5, - 0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, - 0xf0, 0x80, 0x2d, 0xe5, 0x1a, 0x54, 0x3f, 0xff, 0xe5, 0x16, 0x24, - 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0xe5, - 0x1a, 0xae, 0x19, 0x78, 0x06, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, - 0xf9, 0xff, 0xe5, 0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x15, - 0xf5, 0x83, 0xef, 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xe0, - 0x44, 0x01, 0xf0, 0x22, 0x8e, 0x12, 0x8f, 0x13, 0x8d, 0x14, 0xe5, - 0x14, 0xa2, 0xe1, 0x92, 0x09, 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, - 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe5, 0x34, 0x24, 0x1a, - 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfb, 0xa2, 0x09, - 0x92, 0x0a, 0x75, 0x19, 0x00, 0x75, 0x1a, 0x1a, 0x12, 0x02, 0x1f, - 0x30, 0x09, 0x04, 0x7f, 0xc8, 0x80, 0x02, 0x7f, 0xe8, 0xe5, 0x13, - 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, - 0xe5, 0x31, 0x60, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, 0x01, 0xe5, - 0x13, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, - 0xf0, 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, - 0x83, 0xe0, 0xff, 0x7d, 0x1a, 0x7c, 0x00, 0x12, 0x0e, 0x64, 0xe5, - 0x13, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, - 0xf0, 0xe5, 0x13, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, - 0x83, 0xee, 0xf0, 0xe5, 0x31, 0x60, 0x60, 0xe5, 0x13, 0x24, 0x1c, - 0xff, 0xe4, 0x35, 0x12, 0xfe, 0xe5, 0x34, 0x24, 0x12, 0xfd, 0xe4, - 0x35, 0x33, 0xfc, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, - 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, - 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, 0xe5, - 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, - 0x08, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, 0xe5, 0x34, - 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, - 0xe5, 0x13, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, - 0xef, 0xf0, 0x80, 0x3f, 0xe5, 0x13, 0x24, 0x1c, 0xff, 0xe4, 0x35, - 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, - 0x12, 0x14, 0xab, 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, - 0xfe, 0x7c, 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, - 0x14, 0xab, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, - 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, - 0xab, 0xe5, 0x13, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, - 0x83, 0xe4, 0xf0, 0xe5, 0x13, 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, - 0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82, - 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0xc3, 0x13, 0xff, 0xe5, - 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, - 0xf0, 0x30, 0x09, 0x41, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, - 0x35, 0x12, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x31, 0x60, 0x04, 0x7e, - 0x00, 0x80, 0x02, 0x7e, 0x10, 0xef, 0x4e, 0xf0, 0xe5, 0x31, 0x60, - 0x06, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x0f, 0xe5, 0x14, 0x30, 0xe0, - 0x06, 0x7e, 0x00, 0x7f, 0xff, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, - 0xe5, 0x13, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, - 0xef, 0xf0, 0x22, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, - 0x12, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x14, 0x30, 0xe0, - 0x0f, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, - 0x83, 0xe0, 0xff, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, - 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, - 0x34, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, - 0x30, 0xe7, 0x3b, 0xe5, 0x34, 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, - 0x33, 0xf5, 0x83, 0xe0, 0x65, 0x2b, 0x70, 0x03, 0x75, 0x2b, 0xff, - 0xe5, 0x34, 0x24, 0x1d, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, - 0xe0, 0xff, 0x12, 0x1c, 0x62, 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x18, - 0x7c, 0x8e, 0x33, 0x8f, 0x34, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, - 0xe0, 0x8e, 0x33, 0xf5, 0x34, 0xc3, 0x22, 0xd2, 0x0a, 0xe5, 0x34, - 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x70, - 0x3a, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, - 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, - 0xee, 0x9c, 0xfe, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, - 0xd3, 0x94, 0x00, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, - 0x07, 0x27, 0x80, 0xc6, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, - 0xfe, 0xa3, 0xe0, 0xc3, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x03, - 0x02, 0x07, 0x27, 0x12, 0x1c, 0x41, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0x9f, 0xee, 0x64, 0x80, - 0xf8, 0xec, 0x64, 0x80, 0x98, 0x40, 0x20, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, - 0xe0, 0xff, 0xed, 0x9f, 0xff, 0xec, 0x9e, 0xd0, 0x82, 0xd0, 0x83, - 0xf0, 0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xe5, 0x34, 0x24, 0x10, 0xf5, - 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, - 0xfd, 0xee, 0x94, 0x00, 0xfc, 0x12, 0x16, 0x5a, 0x50, 0x2c, 0x85, - 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, - 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, - 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, - 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x20, - 0x0a, 0x03, 0x02, 0x06, 0x37, 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x18, - 0x7c, 0x8e, 0x33, 0x8f, 0x34, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, - 0xa3, 0xe0, 0xd3, 0x94, 0x00, 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, - 0x0d, 0x7e, 0x22, 0x7f, 0x10, 0xad, 0x34, 0xac, 0x33, 0x12, 0x15, - 0x0e, 0x80, 0x1a, 0x12, 0x1b, 0xab, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0xee, 0x8f, 0xf0, 0x12, 0x07, 0xeb, 0x7e, 0x22, 0x7f, 0x30, - 0xad, 0x34, 0xac, 0x33, 0x12, 0x15, 0x0e, 0x90, 0x22, 0x2e, 0xe0, - 0xfe, 0xa3, 0xe0, 0xff, 0x65, 0x34, 0x70, 0x03, 0xee, 0x65, 0x33, - 0x70, 0x02, 0xd3, 0x22, 0x8e, 0x33, 0x8f, 0x34, 0xc3, 0x22, 0xef, - 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0, 0xa4, 0x28, 0xce, - 0x8d, 0xf0, 0xa4, 0x2e, 0xfe, 0x22, 0xbc, 0x00, 0x0b, 0xbe, 0x00, - 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 0xf0, 0x22, 0xe4, 0xcc, - 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee, 0x33, 0xfe, 0xec, - 0x33, 0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05, 0xfc, 0xee, 0x9d, - 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, 0xfd, 0x22, 0xed, 0xf8, - 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe, 0xad, 0xf0, 0x75, - 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd, 0x40, 0x07, 0x98, - 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, 0xc3, 0x98, 0xfd, 0x0f, 0xd5, - 0xf0, 0xea, 0x22, 0xc5, 0xf0, 0xf8, 0xa3, 0xe0, 0x28, 0xf0, 0xc5, - 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, 0x15, 0x83, 0xe0, - 0x38, 0xf0, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, - 0xa3, 0xe0, 0xff, 0x22, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xa3, 0xee, - 0xf0, 0xa3, 0xef, 0xf0, 0x22, 0xa4, 0x25, 0x82, 0xf5, 0x82, 0xe5, - 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xd0, 0x83, 0xd0, 0x82, 0xf8, - 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, 0x0d, 0xa3, 0xa3, - 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, 0x83, 0xe4, 0x73, - 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, 0xa3, 0x80, 0xdf, - 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0xe4, 0xff, 0x90, 0x30, 0x8c, - 0xe4, 0xf0, 0xef, 0x90, 0x1b, 0x51, 0x93, 0x44, 0x80, 0x90, 0x30, - 0x8d, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, - 0x8c, 0xe0, 0xfe, 0x74, 0x36, 0x2f, 0xf8, 0xc6, 0xee, 0xc6, 0xa3, - 0xe0, 0xfe, 0xef, 0x90, 0x1b, 0x51, 0x93, 0x44, 0x80, 0x6e, 0x60, - 0x01, 0x1f, 0x0f, 0xef, 0xc3, 0x94, 0x09, 0x40, 0xc8, 0x22, 0x00, - 0x00, 0x00, 0x00, 0xe5, 0x30, 0x12, 0x08, 0x25, 0x08, 0xb1, 0x00, - 0x09, 0x1f, 0x01, 0x09, 0x87, 0x02, 0x0a, 0x1b, 0x03, 0x0a, 0x6f, - 0x04, 0x0a, 0xb6, 0x05, 0x0b, 0x29, 0x06, 0x0b, 0x98, 0x07, 0x00, - 0x00, 0x0b, 0xd0, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, - 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34, 0x98, - 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, - 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6, 0x05, - 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d, 0xe5, - 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, - 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7, 0x05, - 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d, 0xe5, - 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, - 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, - 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, - 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34, 0x98, - 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, - 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, 0xe5, 0x27, 0x30, 0xe6, - 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, - 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x1f, 0x43, 0x12, 0x08, - 0x80, 0x1a, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, - 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, - 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12, - 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, - 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x43, 0x12, 0x01, - 0x43, 0x12, 0x04, 0xe5, 0x26, 0x30, 0xe5, 0x5c, 0x90, 0x34, 0x98, - 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, 0xe5, - 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, - 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x30, - 0x43, 0x12, 0x08, 0x80, 0x2b, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, - 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, - 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0xe5, 0x27, - 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0x4f, - 0xf0, 0xe4, 0xf5, 0x2c, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x80, - 0x15, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x27, 0xf4, - 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0x4f, 0xf0, - 0x90, 0x30, 0x35, 0xe0, 0xf5, 0x12, 0x53, 0x12, 0xe0, 0xe5, 0x12, - 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, - 0xf5, 0x12, 0xe5, 0x26, 0x30, 0xe5, 0x3c, 0x90, 0x34, 0x98, 0xe0, - 0x44, 0x01, 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, - 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, - 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0xe5, 0x26, 0x54, 0xc0, - 0x60, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x80, 0x06, 0x53, - 0x12, 0xfe, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, - 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0xc2, 0x01, - 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x27, - 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, - 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, - 0x12, 0xf7, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x08, 0x53, 0x12, 0xfe, - 0x53, 0x12, 0xfb, 0x80, 0x06, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, - 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x30, 0x3a, 0xe5, - 0x12, 0xf0, 0x22, 0x20, 0x02, 0x13, 0x12, 0x1c, 0x1e, 0xaf, 0x29, - 0x7e, 0x00, 0x12, 0x1c, 0x74, 0xaf, 0x35, 0x7e, 0x00, 0x12, 0x1c, - 0x7b, 0xd2, 0x02, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, - 0x20, 0xe5, 0x0d, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x34, 0x98, - 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, - 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x2c, 0xc2, 0x01, 0x12, 0x00, - 0x06, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, - 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, - 0x80, 0x03, 0x43, 0x12, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, - 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x30, 0x01, 0x03, 0x02, - 0x0b, 0xd0, 0x12, 0x15, 0xc0, 0xd2, 0x01, 0x22, 0xc2, 0x01, 0x12, - 0x00, 0x06, 0xe5, 0x26, 0x20, 0xe5, 0x09, 0x90, 0x34, 0x98, 0xe0, - 0x54, 0xfe, 0xf0, 0x80, 0x55, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, - 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6, 0x05, - 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d, 0xe5, - 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, - 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7, 0x05, - 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d, 0xe5, - 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, - 0xf7, 0x43, 0x12, 0x01, 0x53, 0x12, 0xfb, 0x90, 0x30, 0x3a, 0xe5, - 0x12, 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x22, 0xe5, 0x26, - 0x30, 0xe5, 0x2c, 0x20, 0x03, 0x21, 0xd2, 0x03, 0x12, 0x1c, 0x1e, - 0x75, 0x35, 0x06, 0x75, 0x29, 0x09, 0xaf, 0x29, 0x7e, 0x00, 0x12, - 0x1c, 0x74, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x53, 0x12, 0xfe, - 0x43, 0x12, 0x04, 0xe5, 0x12, 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x44, - 0x01, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, - 0xe5, 0x31, 0x64, 0x01, 0x70, 0x41, 0x12, 0x1a, 0xd4, 0x40, 0x03, - 0x02, 0x0d, 0x4f, 0x12, 0x1b, 0x65, 0x50, 0x20, 0x7e, 0x2b, 0x7f, - 0x80, 0x7d, 0x03, 0x12, 0x04, 0x0e, 0x7f, 0x01, 0x12, 0x19, 0x78, - 0x40, 0x09, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f, 0x22, - 0x12, 0x0d, 0x50, 0x75, 0x2f, 0x01, 0x22, 0x7f, 0x01, 0x12, 0x19, - 0x78, 0x50, 0x04, 0x75, 0x2f, 0x02, 0x22, 0xd2, 0x09, 0x12, 0x0f, - 0xee, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x1a, 0x1d, 0x50, 0x51, 0x12, - 0x1b, 0xcb, 0x90, 0x30, 0xf4, 0xe0, 0xf5, 0x2a, 0x7e, 0x30, 0x7f, - 0xec, 0xa3, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, 0x19, 0x2b, 0xe4, 0xff, - 0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0a, 0x74, 0x02, 0xf0, 0x90, - 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xff, 0xf0, 0xfd, 0x90, 0x01, 0x05, - 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x44, 0x20, 0xf0, 0xed, - 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0, 0x90, 0x34, 0xcc, 0xe0, 0x44, - 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, - 0xf0, 0xd2, 0x04, 0x12, 0x1a, 0x3a, 0x50, 0x43, 0x12, 0x1a, 0x57, - 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x30, 0x7d, 0xec, 0x75, 0x1b, 0x11, - 0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, 0x30, 0xf5, 0xe0, 0x75, 0xf0, - 0x20, 0xa4, 0xff, 0xae, 0xf0, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b, - 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, 0x90, 0x00, 0x04, 0xf0, - 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0x00, 0x0a, 0x74, - 0x40, 0xf0, 0x4d, 0x90, 0x00, 0x0b, 0xf0, 0xc2, 0x04, 0x12, 0x1a, - 0xfe, 0x50, 0x38, 0x12, 0x1a, 0x57, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, - 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab, - 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, - 0xff, 0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, - 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, - 0xdf, 0xf0, 0xc2, 0x04, 0x12, 0x1b, 0x28, 0x50, 0x25, 0x12, 0x1a, - 0x57, 0x7f, 0x02, 0x12, 0x19, 0x78, 0x90, 0x01, 0x04, 0xe0, 0x54, - 0x7f, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xe4, - 0x90, 0x00, 0x04, 0xf0, 0xef, 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0, - 0xc2, 0x04, 0x12, 0x1a, 0xd4, 0x50, 0x2d, 0x12, 0x1a, 0x57, 0x7e, - 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, - 0x06, 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, - 0x00, 0x0a, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0x90, - 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xc2, 0x04, 0x22, 0x90, 0x34, - 0xcd, 0xe0, 0xf9, 0x20, 0xe3, 0xf8, 0xe5, 0x2b, 0xf4, 0x60, 0x66, - 0x90, 0x34, 0xc0, 0x12, 0x08, 0x01, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, 0x82, - 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, - 0x0d, 0x90, 0x34, 0xc8, 0x12, 0x08, 0x01, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, - 0x82, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, - 0x08, 0x0d, 0x90, 0x34, 0xd0, 0x12, 0x08, 0x01, 0x85, 0x34, 0x82, - 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, - 0xe5, 0x82, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, - 0x12, 0x08, 0x0d, 0xe5, 0x34, 0x24, 0xf0, 0xff, 0xe5, 0x33, 0x34, - 0xde, 0xfe, 0xef, 0x78, 0x05, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, - 0xf9, 0xf5, 0x2b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, - 0x20, 0x12, 0x08, 0x19, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, - 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, 0x01, 0x90, 0x34, 0xc0, 0x12, - 0x08, 0x0d, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, - 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, 0x82, 0x24, 0x08, 0xf5, 0x82, - 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, 0x01, 0x90, 0x34, 0xc8, - 0x12, 0x08, 0x0d, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, - 0x20, 0xe5, 0x2b, 0x12, 0x08, 0x19, 0xe5, 0x82, 0x24, 0x0c, 0xf5, - 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x08, 0x01, 0x90, 0x34, - 0xc4, 0x12, 0x08, 0x0d, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, - 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0, 0xe9, 0x44, 0x04, 0x90, - 0x34, 0xcd, 0xf0, 0x90, 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, - 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x8f, - 0x15, 0x8c, 0x16, 0x8d, 0x17, 0xe5, 0x15, 0xc3, 0x94, 0x04, 0x50, - 0x56, 0xe5, 0x15, 0x94, 0x00, 0x40, 0x06, 0x7a, 0x00, 0x7b, 0x60, - 0x80, 0x04, 0x7a, 0x00, 0x7b, 0xc0, 0xe5, 0x17, 0xc4, 0xf8, 0x54, - 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48, 0xfe, - 0xe5, 0x15, 0x90, 0x1a, 0x8e, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x07, - 0x96, 0xef, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xc4, 0xf8, - 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48, - 0xfe, 0xe5, 0x15, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x07, 0x96, 0xed, - 0x4c, 0x60, 0x63, 0x0b, 0xbb, 0x00, 0x01, 0x0a, 0x80, 0x5c, 0x7a, - 0x00, 0x7b, 0x1a, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, 0xc3, 0x33, - 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, 0x3e, 0xfe, - 0xe5, 0x15, 0x90, 0x1a, 0x8e, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x07, - 0x96, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, - 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, - 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, - 0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1a, 0x8e, 0x93, 0xfd, 0x7c, 0x00, - 0x12, 0x07, 0x96, 0xed, 0x4c, 0x60, 0x07, 0x74, 0x04, 0x2b, 0xfb, - 0xe4, 0x3a, 0xfa, 0xcf, 0xeb, 0xcf, 0xce, 0xea, 0xce, 0x22, 0xe5, - 0x2e, 0x14, 0x60, 0x1d, 0x14, 0x60, 0x3d, 0x14, 0x60, 0x5d, 0x14, - 0x70, 0x03, 0x02, 0x0f, 0xd7, 0x24, 0x04, 0x60, 0x03, 0x02, 0x0f, - 0xed, 0x20, 0x0d, 0x03, 0x02, 0x0f, 0xed, 0x75, 0x2e, 0x01, 0x22, - 0x90, 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x03, 0x44, 0x20, 0xf0, - 0xe5, 0x40, 0x45, 0x3f, 0x60, 0x03, 0x02, 0x0f, 0xed, 0x75, 0x2e, - 0x02, 0x12, 0x19, 0x9b, 0x12, 0x1b, 0x78, 0xaf, 0x28, 0x12, 0x1a, - 0xa8, 0x22, 0x90, 0x01, 0x03, 0xe0, 0xff, 0x30, 0xe7, 0x76, 0xef, - 0x44, 0x80, 0x90, 0x01, 0x03, 0xf0, 0x12, 0x08, 0x51, 0x12, 0x19, - 0xde, 0x12, 0x1b, 0xbb, 0x75, 0x2e, 0x03, 0xaf, 0x22, 0x7e, 0x00, - 0x12, 0x1c, 0x2a, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, 0x21, 0x12, - 0x14, 0x41, 0x12, 0x1b, 0x78, 0x12, 0x19, 0xbe, 0x12, 0x1b, 0xbb, - 0x12, 0x1c, 0x04, 0x30, 0x0d, 0x0b, 0x75, 0x2e, 0x01, 0xaf, 0x32, - 0x7e, 0x00, 0x12, 0x1c, 0x2a, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, - 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x2c, 0x44, 0x20, 0xf0, 0x12, - 0x14, 0x41, 0x12, 0x1b, 0x78, 0x12, 0x19, 0xbe, 0x12, 0x1b, 0xbb, - 0x12, 0x1c, 0x04, 0x75, 0x2e, 0x04, 0x22, 0xe5, 0x40, 0x45, 0x3f, - 0x70, 0x10, 0x30, 0x0d, 0x0a, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0xfe, - 0x12, 0x1c, 0x2a, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, 0x00, 0x04, - 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x30, 0x09, 0x32, 0xe5, - 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, - 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, - 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, - 0xc3, 0x22, 0x12, 0x05, 0xed, 0x50, 0xf3, 0x90, 0x00, 0x0a, 0xe0, - 0x20, 0xe5, 0x03, 0x30, 0x07, 0x41, 0xe5, 0x34, 0x45, 0x33, 0x70, - 0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, - 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, - 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, - 0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x12, 0x05, - 0xed, 0x50, 0xf3, 0x80, 0xb5, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x16, 0xea, 0xd3, 0x22, 0x12, - 0x1a, 0xfe, 0x40, 0x05, 0x12, 0x1a, 0xd4, 0x50, 0x44, 0x7e, 0x30, - 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, - 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, - 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b, - 0xe0, 0x54, 0xbf, 0xf0, 0x54, 0x7f, 0xff, 0xf0, 0xe4, 0x90, 0x30, - 0xe9, 0xf0, 0xef, 0x54, 0xfd, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90, - 0x00, 0x04, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f, - 0x12, 0x1b, 0x13, 0x50, 0x48, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, - 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, - 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff, - 0xfe, 0x12, 0x1c, 0x36, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, - 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xff, 0x12, 0x19, - 0x78, 0x50, 0x04, 0x75, 0x2f, 0x07, 0x22, 0x90, 0x01, 0x04, 0xe0, - 0x54, 0x7f, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f, - 0x22, 0xc2, 0xaf, 0xe4, 0xf5, 0x2f, 0xf5, 0x88, 0x75, 0xa8, 0x0f, - 0x75, 0x89, 0x11, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x0f, 0x75, - 0x31, 0xff, 0x75, 0x2b, 0xff, 0x90, 0x22, 0x2e, 0xf0, 0xa3, 0xf0, - 0x90, 0x22, 0x4e, 0xf0, 0xa3, 0xf0, 0xc2, 0x05, 0xc2, 0x08, 0xc2, - 0x00, 0xc2, 0x07, 0xc2, 0x04, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, - 0x90, 0x00, 0x0b, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x03, 0x74, 0xff, - 0xf0, 0xe4, 0x90, 0x01, 0x04, 0xf0, 0x90, 0x01, 0x05, 0x74, 0xff, - 0xf0, 0xe4, 0x90, 0x01, 0x06, 0xf0, 0x90, 0x00, 0x04, 0xf0, 0x90, - 0x30, 0xe8, 0x74, 0x10, 0xf0, 0x90, 0x01, 0x07, 0xf0, 0x90, 0x01, - 0x08, 0x04, 0xf0, 0x90, 0x01, 0x09, 0x74, 0x48, 0xf0, 0x90, 0x01, - 0x0a, 0x74, 0x7f, 0xf0, 0x90, 0x01, 0x02, 0x74, 0x1f, 0xf0, 0x90, - 0x01, 0x00, 0x74, 0x14, 0xf0, 0x90, 0x01, 0x01, 0x74, 0x20, 0xf0, - 0x90, 0x00, 0x00, 0xe0, 0x44, 0x80, 0xf0, 0x75, 0x49, 0x00, 0x75, - 0x4a, 0x01, 0xc2, 0x01, 0xd2, 0xaf, 0x22, 0x12, 0x1a, 0xd4, 0x50, - 0x2d, 0x12, 0x18, 0x48, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, - 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, - 0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, - 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, - 0x2f, 0x22, 0x12, 0x1b, 0x28, 0x50, 0x50, 0x12, 0x18, 0x48, 0x90, - 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, - 0x90, 0x01, 0x03, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x44, - 0x80, 0xf0, 0x7f, 0x02, 0x12, 0x19, 0x78, 0x50, 0x04, 0x75, 0x2f, - 0x05, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x82, 0x75, - 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab, 0x90, 0x00, 0x04, 0x74, - 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x0f, 0xee, - 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5, 0x2f, 0x22, - 0x90, 0x30, 0x30, 0x74, 0x02, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, - 0xd0, 0x90, 0x30, 0x30, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x12, 0x15, - 0x12, 0x70, 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xeb, - 0xe5, 0x12, 0x45, 0x11, 0x70, 0x12, 0x12, 0x1a, 0x74, 0x90, 0x21, - 0x00, 0xe0, 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, - 0xc3, 0x22, 0xe4, 0x90, 0x34, 0x58, 0xf0, 0x90, 0x34, 0x32, 0x74, - 0x1f, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90, 0x34, 0x81, - 0xe0, 0x64, 0x03, 0x60, 0x0e, 0xe5, 0x12, 0x15, 0x12, 0x70, 0x02, - 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xea, 0xe5, 0x12, 0x45, - 0x11, 0x70, 0x12, 0x12, 0x1a, 0x74, 0x90, 0x21, 0x00, 0xe0, 0x60, - 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, 0x22, 0x90, - 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe4, 0x90, 0x00, 0x01, 0xf0, - 0xd3, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x10, 0x12, 0x1c, 0x57, - 0x50, 0x26, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x10, 0xfd, 0x80, - 0x03, 0x43, 0x10, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x10, - 0xf7, 0x80, 0x03, 0x43, 0x10, 0x08, 0x53, 0x10, 0xfe, 0x43, 0x10, - 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0x12, 0x1c, 0x4c, 0x50, - 0x48, 0x90, 0x01, 0x03, 0xe0, 0xf5, 0x10, 0x54, 0x1c, 0x60, 0x3e, - 0xe5, 0x10, 0x54, 0xe3, 0xf0, 0xa3, 0xe0, 0xf5, 0x10, 0xf0, 0xe5, - 0x27, 0x30, 0xe6, 0x05, 0x43, 0x10, 0x02, 0x80, 0x03, 0x53, 0x10, - 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x10, 0x08, 0x80, 0x03, - 0x53, 0x10, 0xf7, 0x53, 0x10, 0xfe, 0x43, 0x10, 0x04, 0x90, 0x30, - 0x3a, 0xe5, 0x10, 0xf0, 0xaf, 0x29, 0x7e, 0x00, 0x12, 0x1c, 0x74, - 0xaf, 0x35, 0x7e, 0x00, 0x12, 0x1c, 0x7b, 0x22, 0x12, 0x1a, 0xbf, - 0x50, 0x72, 0x12, 0x1c, 0x41, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0xe0, 0xfc, 0xa3, 0xe0, 0xc3, 0x9f, 0xf5, 0x12, 0xec, 0x9e, 0xf5, - 0x11, 0xd3, 0xe5, 0x12, 0x94, 0x00, 0xe5, 0x11, 0x64, 0x80, 0x94, - 0x80, 0x40, 0x06, 0xae, 0x11, 0xaf, 0x12, 0x80, 0x04, 0x7e, 0x00, - 0x7f, 0x00, 0x8e, 0x11, 0x8f, 0x12, 0xe5, 0x34, 0x24, 0x10, 0xf5, - 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xc3, 0x95, 0x12, 0xf5, - 0x12, 0xe4, 0x95, 0x11, 0xf5, 0x11, 0xc3, 0x64, 0x80, 0x94, 0x80, - 0x50, 0x05, 0xe4, 0xf5, 0x11, 0xf5, 0x12, 0xe5, 0x34, 0x24, 0x12, - 0xff, 0xe4, 0x35, 0x33, 0xfe, 0xad, 0x12, 0x7b, 0x01, 0x12, 0x19, - 0x2b, 0x90, 0x01, 0x05, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, - 0x44, 0x20, 0xf0, 0x75, 0x2f, 0x03, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, - 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, - 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, - 0xe5, 0x2f, 0x25, 0xe0, 0x24, 0x9b, 0xf5, 0x82, 0xe4, 0x34, 0x1b, - 0xf5, 0x83, 0xe4, 0x93, 0xfe, 0x74, 0x01, 0x93, 0xca, 0xee, 0xca, - 0xf9, 0x12, 0x08, 0x4b, 0x12, 0x1b, 0xf6, 0x50, 0x02, 0xd2, 0x07, - 0x12, 0x17, 0x2c, 0x12, 0x00, 0x1e, 0x12, 0x1a, 0xe9, 0x50, 0x05, - 0xaf, 0x25, 0x12, 0x1c, 0x62, 0x30, 0x05, 0x1b, 0xe5, 0x2f, 0x70, - 0x17, 0x20, 0x04, 0x14, 0x12, 0x12, 0x4e, 0x92, 0x00, 0xc2, 0x05, - 0xd2, 0x0b, 0xa2, 0x00, 0xe4, 0x33, 0xf5, 0x14, 0xaf, 0x23, 0x12, - 0x16, 0xa2, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, - 0xf0, 0xd0, 0xe0, 0x32, 0x90, 0x29, 0xa0, 0xe0, 0x70, 0x63, 0x90, - 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc2, 0xf0, 0xa3, 0x74, 0x01, - 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, - 0xa0, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc5, 0xf0, - 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, - 0xff, 0x90, 0x29, 0xa1, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, - 0x74, 0xc4, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, - 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa2, 0xf0, 0x90, 0x30, 0x8c, - 0xe4, 0xf0, 0xa3, 0x74, 0xc3, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, - 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0x90, 0x29, 0xa3, 0xf0, 0x22, - 0x8e, 0x16, 0x8f, 0x17, 0x8c, 0x18, 0x8d, 0x19, 0xe4, 0xff, 0xef, - 0xc3, 0x9b, 0x50, 0x53, 0xe5, 0x1b, 0x30, 0xe0, 0x12, 0xef, 0x7c, - 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, 0x83, - 0xe0, 0xf5, 0x1c, 0x80, 0x1f, 0xe5, 0x1b, 0x30, 0xe1, 0x13, 0xef, - 0x7c, 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, - 0x83, 0xe4, 0x93, 0xf5, 0x1c, 0x80, 0x07, 0xe5, 0x19, 0x2f, 0xf8, - 0xe6, 0xf5, 0x1c, 0xe5, 0x1b, 0x30, 0xe4, 0x0f, 0xe5, 0x17, 0x2f, - 0xf5, 0x82, 0xe4, 0x35, 0x16, 0xf5, 0x83, 0xe5, 0x1c, 0xf0, 0x80, - 0x06, 0xe5, 0x17, 0x2f, 0xf8, 0xa6, 0x1c, 0x0f, 0x80, 0xa8, 0x22, - 0x8c, 0x13, 0x8d, 0x14, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, - 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0x4c, 0x60, 0x41, 0xef, 0x24, - 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, - 0xf5, 0x82, 0x8c, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x85, 0x14, - 0x82, 0x85, 0x13, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xd3, 0xed, - 0x9b, 0xea, 0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, 0x40, 0x13, - 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, - 0xa3, 0xe0, 0xce, 0xec, 0xce, 0xff, 0x80, 0xaf, 0xad, 0x14, 0xac, - 0x13, 0x12, 0x18, 0xaf, 0x22, 0x12, 0x1a, 0xbf, 0x50, 0x4f, 0xe5, - 0x34, 0x24, 0x12, 0xff, 0xe4, 0x35, 0x33, 0xfe, 0xe5, 0x34, 0x24, - 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe4, - 0xfb, 0x12, 0x19, 0x2b, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, - 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x7e, 0x00, 0x12, 0x1c, 0x36, - 0x90, 0x00, 0x0a, 0x74, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, - 0x40, 0xff, 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x80, 0xf0, 0x4f, 0x90, - 0x00, 0x0b, 0xf0, 0x90, 0x30, 0xe9, 0x74, 0x01, 0xf0, 0x75, 0x2f, - 0x06, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xff, 0xe5, 0x27, 0x30, 0xe6, - 0x12, 0x30, 0x0c, 0x06, 0xef, 0x54, 0xf5, 0xfe, 0x80, 0x04, 0xef, - 0x44, 0x0a, 0xfe, 0xcf, 0xee, 0xcf, 0x80, 0x10, 0x30, 0x0c, 0x06, - 0xef, 0x44, 0x0a, 0xfe, 0x80, 0x04, 0xef, 0x54, 0xf5, 0xfe, 0xcf, - 0xee, 0xcf, 0xcf, 0x54, 0xfe, 0xcf, 0xcf, 0x44, 0x04, 0xcf, 0x90, - 0x30, 0x3a, 0xef, 0xf0, 0x30, 0x0c, 0x09, 0x7f, 0x08, 0x7e, 0x00, - 0x12, 0x1c, 0x74, 0x80, 0x07, 0x7f, 0x22, 0x7e, 0x01, 0x12, 0x1c, - 0x74, 0xb2, 0x0c, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, - 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, 0xc2, 0x8c, 0xc2, - 0x8d, 0xd3, 0xe5, 0x4a, 0x94, 0x00, 0xe5, 0x49, 0x94, 0x00, 0x40, - 0x08, 0xe5, 0x4a, 0x15, 0x4a, 0x70, 0x02, 0x15, 0x49, 0xd3, 0xe5, - 0x4c, 0x94, 0x00, 0xe5, 0x4b, 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4c, - 0x15, 0x4c, 0x70, 0x02, 0x15, 0x4b, 0x12, 0x00, 0x0e, 0xd2, 0x8c, - 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, - 0xe0, 0x32, 0xc3, 0xef, 0x94, 0x04, 0xee, 0x64, 0x80, 0x94, 0x80, - 0x40, 0x0c, 0xd3, 0xed, 0x94, 0x04, 0xec, 0x64, 0x80, 0x94, 0x80, - 0x50, 0x01, 0x22, 0xc3, 0xef, 0x94, 0xfc, 0xee, 0x64, 0x80, 0x94, - 0x7f, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0xfc, 0xec, 0x64, 0x80, 0x94, - 0x7f, 0x50, 0x01, 0x22, 0xd3, 0xef, 0x94, 0x04, 0xee, 0x64, 0x80, - 0x94, 0x80, 0x50, 0x0d, 0xc3, 0xed, 0x94, 0xfc, 0xec, 0x64, 0x80, - 0x94, 0x7f, 0x40, 0x02, 0xd3, 0x22, 0xc3, 0x22, 0xe4, 0xfe, 0xef, - 0xf4, 0x60, 0x41, 0x74, 0x04, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, - 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x23, 0x74, 0x04, 0x2e, 0xf5, 0x82, - 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x0b, 0x0d, 0x74, - 0x08, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x14, - 0xf0, 0x90, 0x00, 0x02, 0x74, 0x01, 0xf0, 0x22, 0xbe, 0x03, 0x0a, - 0x90, 0x00, 0x02, 0x74, 0x01, 0xf0, 0xe4, 0xfe, 0x80, 0xc2, 0x0e, - 0x80, 0xbf, 0x22, 0x8e, 0x13, 0x8f, 0x14, 0x12, 0x1c, 0x41, 0xc3, - 0xef, 0x95, 0x14, 0xff, 0xee, 0x95, 0x13, 0xcd, 0xef, 0xcd, 0xfc, - 0xd3, 0xed, 0x94, 0x00, 0xec, 0x64, 0x80, 0x94, 0x80, 0x40, 0x05, - 0xce, 0xec, 0xce, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x01, 0xcc, 0xee, - 0xcc, 0xec, 0x90, 0x00, 0x05, 0xf0, 0x90, 0x00, 0x06, 0xef, 0xf0, - 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, - 0x02, 0xf0, 0x22, 0x30, 0x07, 0x3c, 0xe5, 0x2f, 0x70, 0x38, 0xc2, - 0x07, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x11, 0xf5, - 0x12, 0x90, 0x22, 0x4e, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x90, 0x22, - 0x2e, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x90, 0x22, 0x4e, 0xe5, 0x11, - 0xf0, 0xa3, 0xe5, 0x12, 0xf0, 0x8e, 0x33, 0x8f, 0x34, 0x30, 0x08, - 0x05, 0x12, 0x17, 0xa5, 0xc2, 0x08, 0xc2, 0x09, 0x12, 0x0f, 0xee, - 0x22, 0x7f, 0x80, 0x7e, 0x29, 0xe4, 0xfd, 0xfc, 0x8f, 0x82, 0x8e, - 0x83, 0xe0, 0xfb, 0x74, 0x45, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, 0x74, - 0x04, 0x2f, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfb, 0x74, - 0x41, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x08, 0x2f, 0xff, 0xe4, - 0x3e, 0xfe, 0x0d, 0xbd, 0x00, 0x01, 0x0c, 0xed, 0x64, 0x04, 0x4c, - 0x70, 0xcf, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xc4, 0x33, 0x54, 0xe0, - 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xab, 0x82, 0xfa, 0x12, - 0x1b, 0xab, 0x8b, 0x82, 0x8a, 0x83, 0xee, 0x8f, 0xf0, 0x12, 0x07, - 0xeb, 0x7e, 0x22, 0x7f, 0x30, 0xcd, 0xeb, 0xcd, 0xcc, 0xea, 0xcc, - 0x12, 0x15, 0x0e, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x1c, 0x62, 0x22, 0x90, 0x00, 0x00, 0x74, 0x0e, 0xf0, 0x00, 0x00, - 0x00, 0xe4, 0xf0, 0x12, 0x11, 0x31, 0x12, 0x1c, 0x88, 0x90, 0x34, - 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x30, 0xb4, 0x05, 0x0a, 0x12, - 0x1c, 0x4c, 0x50, 0x0d, 0x12, 0x15, 0xc0, 0x80, 0x08, 0xe5, 0x30, - 0xb4, 0x07, 0x03, 0x12, 0x12, 0xd4, 0x12, 0x0f, 0x2a, 0x80, 0xe4, - 0x80, 0xfe, 0x22, 0xe4, 0xff, 0xe5, 0x30, 0x24, 0xfe, 0x70, 0x2c, - 0xe4, 0xfe, 0xee, 0xc3, 0x95, 0x2c, 0x50, 0x12, 0x74, 0x01, 0xc8, - 0xee, 0xc8, 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xcf, 0x4f, - 0xcf, 0x0e, 0x80, 0xe8, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0xfe, - 0xe5, 0x27, 0x54, 0x1f, 0x6f, 0xf4, 0xce, 0x4e, 0xce, 0xee, 0xf0, - 0x22, 0x90, 0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, - 0xe0, 0x54, 0xfe, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x20, 0xe3, 0xf9, - 0x90, 0x01, 0x11, 0xe0, 0x54, 0x22, 0xff, 0xbf, 0x22, 0x03, 0xd3, - 0x80, 0x01, 0xc3, 0x50, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, - 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0xef, 0x24, - 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, - 0xfb, 0xca, 0xec, 0xca, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, - 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x24, 0x1e, 0xf5, 0x82, - 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xce, 0xea, - 0xce, 0xcf, 0xeb, 0xcf, 0x22, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, - 0x3e, 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xed, 0x24, 0x1e, - 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xea, 0xf0, 0xa3, 0xeb, 0xf0, - 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, - 0xa3, 0xed, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc2, 0xaf, 0xc2, - 0x8e, 0xc2, 0x8f, 0xd3, 0xe5, 0x40, 0x94, 0x00, 0xe5, 0x3f, 0x94, - 0x00, 0x40, 0x0d, 0xe5, 0x40, 0x15, 0x40, 0x70, 0x02, 0x15, 0x3f, - 0x12, 0x1c, 0x6b, 0xd2, 0x8e, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0xe0, - 0x32, 0x12, 0x1a, 0xbf, 0x50, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, - 0x1c, 0x7d, 0x82, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x14, 0xab, - 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, - 0x09, 0x12, 0x0f, 0xee, 0xe4, 0xf5, 0x2f, 0x22, 0x8e, 0x13, 0x8f, - 0x14, 0x8d, 0x15, 0xeb, 0x60, 0x09, 0x14, 0x70, 0x1b, 0xaf, 0x15, - 0x12, 0x19, 0xfe, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0xac, 0x13, 0xad, - 0x14, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x14, 0xab, 0xaf, 0x15, - 0x12, 0x19, 0xfe, 0x22, 0x12, 0x17, 0x6c, 0x90, 0x21, 0x01, 0xe0, - 0xf5, 0x28, 0x74, 0x41, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x32, 0x74, - 0x45, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x22, 0x90, 0x21, 0x00, 0xe0, - 0x60, 0x03, 0xd2, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0xcd, 0xef, 0xcd, - 0x90, 0x01, 0x02, 0xe0, 0x30, 0xe7, 0x02, 0xc3, 0x22, 0x7e, 0x2a, - 0x7f, 0x00, 0x12, 0x04, 0x0e, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, - 0xf0, 0x90, 0x01, 0x02, 0xe0, 0x44, 0x80, 0xf0, 0xd3, 0x22, 0x90, - 0x34, 0x30, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x1f, 0xf0, 0xa3, - 0xe4, 0xf0, 0x90, 0x01, 0x10, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, - 0xf6, 0x90, 0x01, 0x12, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, 0xf6, - 0x22, 0xe4, 0xff, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x90, 0x30, 0x8c, - 0xf0, 0xef, 0x90, 0x1b, 0x51, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, - 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, - 0xe4, 0xff, 0xef, 0x90, 0x1b, 0x5b, 0x93, 0x90, 0x30, 0x8c, 0xf0, - 0xef, 0x90, 0x1b, 0x51, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74, - 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, 0xe4, - 0x90, 0x00, 0x05, 0xf0, 0xef, 0x60, 0x02, 0x80, 0x02, 0x7f, 0x01, - 0x90, 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, - 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x90, 0x30, 0xf0, - 0xe0, 0xf5, 0x2a, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, - 0x30, 0xf2, 0xe0, 0x60, 0x08, 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, - 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, - 0x00, 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x70, - 0x08, 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, - 0x90, 0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, - 0x54, 0xfe, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, - 0x01, 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0x90, 0x00, 0x01, 0x74, - 0x0e, 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x34, - 0x58, 0x74, 0x01, 0xf0, 0x90, 0x30, 0x30, 0x74, 0x04, 0xf0, 0x22, - 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c, 0x90, 0xc8, 0x00, 0x01, 0x02, 0x03, 0x0b, 0x0f, 0x0a, 0x0e, - 0x09, 0x0d, 0x08, 0x0c, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0x3f, 0x4f, 0xf0, 0x90, 0x01, 0x02, - 0xe0, 0x44, 0x80, 0xf0, 0x22, 0x90, 0x01, 0x03, 0xe0, 0x30, 0xe7, - 0x0c, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, - 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe1, 0x0c, - 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xd3, - 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe2, 0x0c, 0x74, - 0x04, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xf0, 0xd3, 0x22, - 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe6, 0x0c, 0x74, 0x40, - 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xd3, 0x22, 0xc3, - 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe7, 0x0c, 0x74, 0x80, 0xf0, - 0x90, 0x00, 0x0b, 0xe0, 0x54, 0x7f, 0xf0, 0xd3, 0x22, 0xc3, 0x22, - 0x90, 0x01, 0x05, 0xe0, 0x30, 0xe5, 0x0c, 0x74, 0x20, 0xf0, 0x90, - 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0xe4, - 0xf5, 0x31, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x22, 0x2e, - 0x74, 0x21, 0xf0, 0xa3, 0x74, 0x10, 0xf0, 0x22, 0x52, 0x53, 0x54, - 0x12, 0x15, 0x16, 0x10, 0x11, 0x40, 0x00, 0x20, 0x00, 0x40, 0xff, - 0x3f, 0x3f, 0xbd, 0x28, 0x21, 0x00, 0xe5, 0x34, 0x24, 0x11, 0xf5, - 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe6, 0x02, 0xd3, - 0x22, 0xc3, 0x22, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, 0x74, - 0xb0, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x22, 0x75, - 0x31, 0x01, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b, - 0xe0, 0x44, 0x20, 0xf0, 0x22, 0x0b, 0xd1, 0x13, 0x53, 0x15, 0x6b, - 0x11, 0xc6, 0x00, 0x09, 0x19, 0x03, 0x10, 0x95, 0x1b, 0xda, 0x90, - 0x30, 0x64, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0x25, 0xe0, 0xff, - 0xee, 0x33, 0xfe, 0x22, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, - 0x74, 0xb0, 0xf0, 0xa3, 0xe4, 0xf0, 0xa3, 0xf0, 0x22, 0x90, 0x01, - 0x00, 0xe0, 0x44, 0x08, 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, - 0xf0, 0x22, 0x12, 0x1a, 0xbf, 0x50, 0x08, 0xd2, 0x09, 0x12, 0x0f, - 0xee, 0xe4, 0xf5, 0x2f, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe0, - 0x05, 0x74, 0x01, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, - 0xe0, 0x30, 0xe5, 0x05, 0x74, 0x20, 0xf0, 0xd3, 0x22, 0xc3, 0x22, - 0x90, 0x34, 0x30, 0x74, 0x1f, 0xf0, 0xa3, 0xe4, 0xf0, 0xa3, 0xf0, - 0xa3, 0xf0, 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, - 0x4c, 0x02, 0x17, 0xdc, 0xc2, 0xaf, 0xc2, 0x8c, 0xc2, 0x8d, 0x12, - 0x00, 0x0e, 0xd2, 0xaf, 0x22, 0xc2, 0x8e, 0x8e, 0x3f, 0x8f, 0x40, - 0x12, 0x1c, 0x6b, 0xd2, 0x8e, 0x22, 0x90, 0x30, 0x3c, 0xef, 0xf0, - 0xee, 0x44, 0x80, 0xa3, 0xf0, 0x22, 0x90, 0x30, 0x78, 0xe0, 0xfd, - 0xa3, 0xe0, 0xfe, 0xed, 0xff, 0x22, 0xe5, 0x4a, 0x45, 0x49, 0x70, - 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0xe5, 0x4c, 0x45, 0x4b, 0x70, - 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, 0xc2, 0x0b, 0xe4, 0xf5, 0x14, - 0x12, 0x16, 0xa2, 0x22, 0xc2, 0x8f, 0x75, 0x8d, 0xf5, 0x75, 0x8b, - 0x41, 0x22, 0x8e, 0x49, 0x8f, 0x4a, 0xd2, 0x8c, 0x22, 0x8e, 0x4b, - 0x8f, 0x4c, 0xd2, 0x8c, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0xc2, 0x0d, 0xe4, 0xf5, 0x2e, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xac, 0x30 -}; - -static const uint8_t rt2561s_ucode[] = { - 0x02, 0x1c, 0x2d, 0x02, 0x07, 0xdf, 0xc2, 0x8c, 0x22, 0x22, 0x00, - 0x02, 0x19, 0x43, 0xc2, 0xaf, 0xc2, 0x8d, 0x75, 0x8c, 0x94, 0x75, - 0x8a, 0x93, 0xd2, 0xaf, 0x22, 0x02, 0x1a, 0x9c, 0x12, 0x08, 0xdf, - 0x40, 0x03, 0x02, 0x02, 0x1e, 0x90, 0x21, 0x02, 0xe0, 0xf5, 0x2d, - 0x90, 0x00, 0x03, 0xe0, 0x12, 0x04, 0x3f, 0x00, 0xb0, 0x00, 0x00, - 0xce, 0x01, 0x00, 0x5e, 0x10, 0x00, 0x6f, 0x11, 0x00, 0xf2, 0x20, - 0x01, 0x4d, 0x21, 0x01, 0x70, 0x22, 0x01, 0x84, 0x30, 0x01, 0x8f, - 0x31, 0x01, 0xd5, 0x50, 0x01, 0x9f, 0x51, 0x01, 0xf2, 0x52, 0x02, - 0x06, 0x60, 0x00, 0x00, 0x02, 0x14, 0x90, 0x00, 0x0a, 0xe0, 0x20, - 0xe5, 0x03, 0x30, 0x07, 0x03, 0xd2, 0x08, 0x22, 0x12, 0x14, 0x2b, - 0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x11, 0xe5, 0x11, 0xc4, 0x33, - 0x54, 0xe0, 0x24, 0x21, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, - 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24, - 0x2c, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x11, 0xf0, - 0xc4, 0x33, 0x54, 0xe0, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x21, - 0xf5, 0x83, 0xe5, 0x2d, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, - 0x12, 0x05, 0xcb, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x31, 0x60, 0x05, - 0x12, 0x1b, 0xe0, 0x80, 0x03, 0x12, 0x1b, 0xa6, 0xe4, 0x90, 0x21, - 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, 0x22, 0x75, 0x31, 0xff, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, - 0x54, 0xfe, 0xf0, 0x54, 0x3e, 0xf0, 0xe4, 0x90, 0x00, 0x0b, 0xf0, - 0xf0, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, 0x22, - 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0xfb, 0x90, 0x34, - 0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x21, 0x14, 0x12, 0x04, 0x1b, - 0x90, 0x34, 0xc0, 0x12, 0x04, 0x27, 0x90, 0x21, 0x18, 0x12, 0x04, - 0x1b, 0x90, 0x34, 0xc8, 0x12, 0x04, 0x27, 0x90, 0x21, 0x1c, 0x12, - 0x04, 0x1b, 0x90, 0x34, 0xc4, 0x12, 0x04, 0x27, 0x90, 0x34, 0xcc, - 0x74, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x01, - 0xe0, 0x44, 0x01, 0xf0, 0x44, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, - 0x44, 0x10, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x10, 0xe8, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, - 0x01, 0x01, 0xe0, 0x54, 0xfe, 0xf0, 0x54, 0xbf, 0xf0, 0x90, 0x00, - 0x0b, 0xe0, 0x54, 0xef, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, - 0x2d, 0x12, 0x10, 0xe8, 0x22, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, - 0x12, 0x0a, 0xfb, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x10, 0xe8, 0x22, 0xd2, 0x05, 0x85, 0x2d, 0x23, 0xe4, 0x90, 0x21, - 0x03, 0xf0, 0x22, 0x12, 0x13, 0xae, 0xc2, 0x00, 0xe4, 0x90, 0x21, - 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, 0x22, 0x85, 0x2d, 0x25, - 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xff, 0xf0, 0xe4, 0x90, 0x00, - 0x07, 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x00, - 0x08, 0xf0, 0x90, 0x21, 0x00, 0xe0, 0x90, 0x00, 0x09, 0xf0, 0x90, - 0x00, 0x07, 0x74, 0x71, 0xf0, 0xef, 0x44, 0x04, 0x90, 0x00, 0x0b, - 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, 0x90, 0x21, 0x00, 0xe0, - 0xff, 0x54, 0x1f, 0xf5, 0x30, 0xa3, 0xe0, 0xf5, 0x27, 0x8f, 0x26, - 0x12, 0x14, 0x62, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, - 0x10, 0xe8, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x2c, 0x12, 0x17, - 0xa3, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x10, 0xe8, - 0x22, 0x12, 0x1a, 0xed, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, - 0x12, 0x10, 0xe8, 0x22, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, - 0x12, 0x10, 0xe8, 0x22, 0xe5, 0x31, 0x64, 0x01, 0x70, 0x41, 0x12, - 0x08, 0xed, 0x40, 0x03, 0x02, 0x03, 0x9d, 0x12, 0x0e, 0x34, 0x50, - 0x20, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0xfb, 0x7f, - 0x01, 0x12, 0x0a, 0xd8, 0x40, 0x09, 0xd2, 0x09, 0x12, 0x0e, 0x47, - 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x09, 0x64, 0x75, 0x2f, 0x01, 0x22, - 0x7f, 0x01, 0x12, 0x0a, 0xd8, 0x50, 0x04, 0x75, 0x2f, 0x02, 0x22, - 0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x08, - 0x90, 0x50, 0x51, 0x12, 0x0a, 0xac, 0x90, 0x30, 0xf4, 0xe0, 0xf5, - 0x2a, 0x7e, 0x30, 0x7f, 0xec, 0xa3, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, - 0x0d, 0xa0, 0xe4, 0xff, 0xfe, 0x12, 0x0e, 0x29, 0x90, 0x00, 0x0a, - 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xff, 0xf0, - 0xfd, 0x90, 0x01, 0x05, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, - 0x44, 0x20, 0xf0, 0xed, 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0, 0x90, - 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, - 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xd2, 0x04, 0x12, 0x08, 0xad, 0x50, - 0x43, 0x12, 0x0a, 0xbb, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x30, 0x7d, - 0xec, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, 0x30, - 0xf5, 0xe0, 0x75, 0xf0, 0x20, 0xa4, 0xff, 0xae, 0xf0, 0x12, 0x0e, - 0x29, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, 0xe4, - 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, - 0x90, 0x00, 0x0a, 0x74, 0x40, 0xf0, 0x4d, 0x90, 0x00, 0x0b, 0xf0, - 0xc2, 0x04, 0x12, 0x09, 0x25, 0x50, 0x38, 0x12, 0x0a, 0xbb, 0x7e, - 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, - 0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, - 0x00, 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x0e, 0x29, 0x90, 0x00, - 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, - 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0x04, 0x12, 0x09, 0x4f, - 0x50, 0x25, 0x12, 0x0a, 0xbb, 0x7f, 0x02, 0x12, 0x0a, 0xd8, 0x90, - 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, - 0xfd, 0xff, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xef, 0x54, 0xbf, - 0x90, 0x00, 0x0b, 0xf0, 0xc2, 0x04, 0x12, 0x08, 0xed, 0x50, 0x2d, - 0x12, 0x0a, 0xbb, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, - 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, - 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x90, 0x01, 0x06, 0xe0, - 0x54, 0xdf, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xc2, - 0x04, 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, 0xf0, - 0xa4, 0x28, 0xce, 0x8d, 0xf0, 0xa4, 0x2e, 0xfe, 0x22, 0xbc, 0x00, - 0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, 0xf0, - 0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xee, - 0x33, 0xfe, 0xec, 0x33, 0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40, 0x05, - 0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, 0xfd, - 0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, 0xfe, - 0xad, 0xf0, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, 0xfd, - 0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, 0xc3, 0x98, - 0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xc5, 0xf0, 0xf8, 0xa3, 0xe0, - 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, 0x02, - 0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, - 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x22, 0xec, 0xf0, 0xa3, 0xed, - 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22, 0xa4, 0x25, 0x82, - 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xd0, 0x83, - 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, 0x70, - 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, 0x88, - 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, 0xa3, - 0xa3, 0x80, 0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0xe5, 0x2e, - 0x14, 0x60, 0x1d, 0x14, 0x60, 0x3d, 0x14, 0x60, 0x5d, 0x14, 0x70, - 0x03, 0x02, 0x05, 0x18, 0x24, 0x04, 0x60, 0x03, 0x02, 0x05, 0x2e, - 0x20, 0x0d, 0x03, 0x02, 0x05, 0x2e, 0x75, 0x2e, 0x01, 0x22, 0x90, - 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x03, 0x44, 0x20, 0xf0, 0xe5, - 0x40, 0x45, 0x3f, 0x60, 0x03, 0x02, 0x05, 0x2e, 0x75, 0x2e, 0x02, - 0x12, 0x1b, 0x12, 0x12, 0x1b, 0xce, 0xaf, 0x28, 0x12, 0x1b, 0x8f, - 0x22, 0x90, 0x01, 0x03, 0xe0, 0xff, 0x30, 0xe7, 0x76, 0xef, 0x44, - 0x80, 0x90, 0x01, 0x03, 0xf0, 0x12, 0x08, 0x55, 0x12, 0x1b, 0x55, - 0x12, 0x1c, 0x01, 0x75, 0x2e, 0x03, 0xaf, 0x22, 0x7e, 0x00, 0x12, - 0x1c, 0x45, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, 0x21, 0x12, 0x17, - 0xd8, 0x12, 0x1b, 0xce, 0x12, 0x1b, 0x35, 0x12, 0x1c, 0x01, 0x12, - 0x1c, 0x1f, 0x30, 0x0d, 0x0b, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0x7e, - 0x00, 0x12, 0x1c, 0x45, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, 0x00, - 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x2c, 0x44, 0x20, 0xf0, 0x12, 0x17, - 0xd8, 0x12, 0x1b, 0xce, 0x12, 0x1b, 0x35, 0x12, 0x1c, 0x01, 0x12, - 0x1c, 0x1f, 0x75, 0x2e, 0x04, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, - 0x10, 0x30, 0x0d, 0x0a, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0xfe, 0x12, - 0x1c, 0x45, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x12, 0x09, 0x25, 0x40, - 0x05, 0x12, 0x08, 0xed, 0x50, 0x44, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, - 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, - 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, - 0xff, 0xfe, 0x12, 0x0e, 0x29, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, - 0xf0, 0x54, 0x7f, 0xff, 0xf0, 0xe4, 0x90, 0x30, 0xe9, 0xf0, 0xef, - 0x54, 0xfd, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, - 0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x12, 0x09, 0x3a, - 0x50, 0x48, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, - 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, - 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x0e, - 0x29, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0x54, 0xfd, 0xf0, - 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xff, 0x12, 0x0a, 0xd8, 0x50, 0x04, - 0x75, 0x2f, 0x07, 0x22, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, - 0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0xc2, 0xaf, - 0xe4, 0xf5, 0x2f, 0xf5, 0x88, 0x75, 0xa8, 0x0f, 0x75, 0x89, 0x11, - 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, 0x0f, 0x75, 0x31, 0xff, 0x75, - 0x2b, 0xff, 0x90, 0x22, 0x2e, 0xf0, 0xa3, 0xf0, 0x90, 0x22, 0x4e, - 0xf0, 0xa3, 0xf0, 0xc2, 0x05, 0xc2, 0x08, 0xc2, 0x00, 0xc2, 0x07, - 0xc2, 0x04, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b, - 0x74, 0x01, 0xf0, 0x90, 0x01, 0x03, 0x74, 0xff, 0xf0, 0xe4, 0x90, - 0x01, 0x04, 0xf0, 0x90, 0x01, 0x05, 0x74, 0xff, 0xf0, 0xe4, 0x90, - 0x01, 0x06, 0xf0, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x30, 0xe8, 0x74, - 0x10, 0xf0, 0x90, 0x01, 0x07, 0xf0, 0x90, 0x01, 0x08, 0x04, 0xf0, - 0x90, 0x01, 0x09, 0x74, 0x48, 0xf0, 0x90, 0x01, 0x0a, 0x74, 0x7f, - 0xf0, 0x90, 0x01, 0x02, 0x74, 0x1f, 0xf0, 0x90, 0x01, 0x00, 0x74, - 0x14, 0xf0, 0x90, 0x01, 0x01, 0x74, 0x20, 0xf0, 0x90, 0x00, 0x00, - 0xe0, 0x44, 0x80, 0xf0, 0x75, 0x49, 0x00, 0x75, 0x4a, 0x01, 0xc2, - 0x01, 0xd2, 0xaf, 0x22, 0x12, 0x08, 0xed, 0x50, 0x2d, 0x12, 0x0a, - 0x78, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0x7e, 0x30, 0x7f, - 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, - 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, - 0xf0, 0xd2, 0x09, 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x12, - 0x09, 0x4f, 0x50, 0x50, 0x12, 0x0a, 0x78, 0x90, 0x00, 0x0b, 0xe0, - 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x03, - 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, 0xf0, 0x7f, - 0x02, 0x12, 0x0a, 0xd8, 0x50, 0x04, 0x75, 0x2f, 0x05, 0x22, 0x7e, - 0x30, 0x7f, 0xe0, 0x7c, 0x1c, 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, - 0x06, 0x12, 0x13, 0xc8, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, - 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x0e, 0x47, 0x90, 0x01, 0x04, - 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5, 0x2f, 0x22, 0x90, 0x30, 0x3a, - 0xe0, 0xf5, 0x10, 0x12, 0x1c, 0x5c, 0x50, 0x26, 0xe5, 0x27, 0x30, - 0xe6, 0x05, 0x53, 0x10, 0xfd, 0x80, 0x03, 0x43, 0x10, 0x02, 0xe5, - 0x27, 0x30, 0xe7, 0x05, 0x53, 0x10, 0xf7, 0x80, 0x03, 0x43, 0x10, - 0x08, 0x53, 0x10, 0xfe, 0x43, 0x10, 0x04, 0x90, 0x30, 0x3a, 0xe5, - 0x10, 0xf0, 0x12, 0x1c, 0x51, 0x50, 0x48, 0x90, 0x01, 0x03, 0xe0, - 0xf5, 0x10, 0x54, 0x1c, 0x60, 0x3e, 0xe5, 0x10, 0x54, 0xe3, 0xf0, - 0xa3, 0xe0, 0xf5, 0x10, 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, - 0x10, 0x02, 0x80, 0x03, 0x53, 0x10, 0xfd, 0xe5, 0x27, 0x30, 0xe7, - 0x05, 0x43, 0x10, 0x08, 0x80, 0x03, 0x53, 0x10, 0xf7, 0x53, 0x10, - 0xfe, 0x43, 0x10, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0xaf, - 0x29, 0x7e, 0x00, 0x12, 0x1c, 0x70, 0xaf, 0x35, 0x7e, 0x00, 0x12, - 0x1c, 0x77, 0x22, 0x12, 0x08, 0xca, 0x50, 0x72, 0x12, 0x10, 0xcd, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xc3, - 0x9f, 0xf5, 0x12, 0xec, 0x9e, 0xf5, 0x11, 0xd3, 0xe5, 0x12, 0x94, - 0x00, 0xe5, 0x11, 0x64, 0x80, 0x94, 0x80, 0x40, 0x06, 0xae, 0x11, - 0xaf, 0x12, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x8e, 0x11, 0x8f, - 0x12, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, - 0x83, 0xe0, 0xc3, 0x95, 0x12, 0xf5, 0x12, 0xe4, 0x95, 0x11, 0xf5, - 0x11, 0xc3, 0x64, 0x80, 0x94, 0x80, 0x50, 0x05, 0xe4, 0xf5, 0x11, - 0xf5, 0x12, 0xe5, 0x34, 0x24, 0x12, 0xff, 0xe4, 0x35, 0x33, 0xfe, - 0xad, 0x12, 0x7b, 0x01, 0x12, 0x0d, 0xa0, 0x90, 0x01, 0x05, 0x74, - 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x44, 0x20, 0xf0, 0x75, 0x2f, - 0x03, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, - 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, 0x90, 0x22, 0x2e, 0xe0, 0xfe, - 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, 0xe5, 0x2f, 0x25, 0xe0, 0x24, - 0xf1, 0xf5, 0x82, 0xe4, 0x34, 0x1b, 0xf5, 0x83, 0xe4, 0x93, 0xfe, - 0x74, 0x01, 0x93, 0xca, 0xee, 0xca, 0xf9, 0x12, 0x04, 0x65, 0x12, - 0x09, 0x17, 0x50, 0x02, 0xd2, 0x07, 0x12, 0x19, 0x8e, 0x12, 0x00, - 0x1e, 0x12, 0x09, 0x02, 0x50, 0x05, 0xaf, 0x25, 0x12, 0x10, 0xe8, - 0x30, 0x05, 0x1b, 0xe5, 0x2f, 0x70, 0x17, 0x20, 0x04, 0x14, 0x12, - 0x13, 0x28, 0x92, 0x00, 0xc2, 0x05, 0xd2, 0x0b, 0xa2, 0x00, 0xe4, - 0x33, 0xf5, 0x14, 0xaf, 0x23, 0x12, 0x10, 0xf1, 0xd2, 0xaf, 0xd0, - 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xe4, - 0xff, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xef, 0x90, 0x1b, 0xba, 0x93, - 0x44, 0x80, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, - 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xfe, 0x74, 0x36, 0x2f, 0xf8, - 0xc6, 0xee, 0xc6, 0xa3, 0xe0, 0xfe, 0xef, 0x90, 0x1b, 0xba, 0x93, - 0x44, 0x80, 0x6e, 0x60, 0x01, 0x1f, 0x0f, 0xef, 0xc3, 0x94, 0x09, - 0x40, 0xc8, 0x22, 0x90, 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, 0x00, - 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x60, 0x08, - 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, - 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe4, - 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x70, 0x08, 0x90, 0x00, 0x0a, 0x74, - 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x01, 0x03, 0xe0, 0x30, - 0xe7, 0x0c, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, - 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe0, - 0x05, 0x74, 0x01, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, - 0xe0, 0x30, 0xe1, 0x0c, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, - 0x54, 0xfd, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, - 0x30, 0xe2, 0x0c, 0x74, 0x04, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, - 0xfb, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, - 0xe5, 0x05, 0x74, 0x20, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, - 0x0a, 0xe0, 0x30, 0xe6, 0x0c, 0x74, 0x40, 0xf0, 0x90, 0x00, 0x0b, - 0xe0, 0x54, 0xbf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, - 0xe0, 0x30, 0xe7, 0x0c, 0x74, 0x80, 0xf0, 0x90, 0x00, 0x0b, 0xe0, - 0x54, 0x7f, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x01, 0x05, 0xe0, - 0x30, 0xe5, 0x0c, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, - 0xdf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x34, 0xcd, 0xe0, 0xf9, - 0x20, 0xe3, 0xf8, 0xe5, 0x2b, 0xf4, 0x60, 0x66, 0x90, 0x34, 0xc0, - 0x12, 0x04, 0x1b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, - 0x20, 0xe5, 0x2b, 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, 0x04, 0xf5, - 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x04, 0x27, 0x90, 0x34, - 0xc8, 0x12, 0x04, 0x1b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, - 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, 0x08, - 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x04, 0x27, 0x90, - 0x34, 0xd0, 0x12, 0x04, 0x1b, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, - 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x04, 0x27, - 0xe5, 0x34, 0x24, 0xf0, 0xff, 0xe5, 0x33, 0x34, 0xde, 0xfe, 0xef, - 0x78, 0x05, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x2b, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0x12, 0x04, - 0x33, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, - 0x83, 0x12, 0x04, 0x1b, 0x90, 0x34, 0xc0, 0x12, 0x04, 0x27, 0x85, - 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, - 0x04, 0x33, 0xe5, 0x82, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83, - 0xf5, 0x83, 0x12, 0x04, 0x1b, 0x90, 0x34, 0xc8, 0x12, 0x04, 0x27, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, - 0x12, 0x04, 0x33, 0xe5, 0x82, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, - 0x83, 0xf5, 0x83, 0x12, 0x04, 0x1b, 0x90, 0x34, 0xc4, 0x12, 0x04, - 0x27, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0x90, 0x01, 0x00, - 0xe0, 0x44, 0x08, 0xf0, 0xe9, 0x44, 0x04, 0x90, 0x34, 0xcd, 0xf0, - 0x90, 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, - 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x90, 0x34, 0xce, 0xe0, - 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54, 0xfe, 0xf0, 0x90, - 0x34, 0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x01, 0x11, 0xe0, 0x54, - 0x22, 0xff, 0xbf, 0x22, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x50, 0xf0, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, - 0x54, 0xbf, 0xf0, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0, - 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0x22, 0x90, 0x34, 0xce, - 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54, 0xfe, 0xf0, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, - 0x54, 0xbf, 0xf0, 0x22, 0xcd, 0xef, 0xcd, 0x90, 0x01, 0x02, 0xe0, - 0x30, 0xe7, 0x02, 0xc3, 0x22, 0x7e, 0x2a, 0x7f, 0x00, 0x12, 0x0a, - 0xfb, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, 0xf0, 0x90, 0x01, 0x02, - 0xe0, 0x44, 0x80, 0xf0, 0xd3, 0x22, 0x8e, 0x12, 0x8f, 0x13, 0x8d, - 0x14, 0xe5, 0x14, 0xa2, 0xe1, 0x92, 0x09, 0xe5, 0x34, 0x24, 0x19, - 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe5, 0x34, - 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfb, - 0xa2, 0x09, 0x92, 0x0a, 0x75, 0x19, 0x00, 0x75, 0x1a, 0x1a, 0x12, - 0x11, 0x39, 0x30, 0x09, 0x04, 0x7f, 0xc8, 0x80, 0x02, 0x7f, 0xe8, - 0xe5, 0x13, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, - 0xef, 0xf0, 0xe5, 0x31, 0x60, 0x04, 0x7f, 0x02, 0x80, 0x02, 0x7f, - 0x01, 0xe5, 0x13, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, - 0x83, 0xef, 0xf0, 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, - 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x7d, 0x1a, 0x7c, 0x00, 0x12, 0x0c, - 0xda, 0xe5, 0x13, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, - 0x83, 0xef, 0xf0, 0xe5, 0x13, 0x24, 0x1b, 0xf5, 0x82, 0xe4, 0x35, - 0x12, 0xf5, 0x83, 0xee, 0xf0, 0xe5, 0x31, 0x60, 0x60, 0xe5, 0x13, - 0x24, 0x1c, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0xe5, 0x34, 0x24, 0x12, - 0xfd, 0xe4, 0x35, 0x33, 0xfc, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, - 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, 0xfe, - 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x13, - 0xc8, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, - 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x13, 0xc8, - 0xe5, 0x34, 0x24, 0x18, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, - 0xe0, 0xff, 0xe5, 0x13, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x35, 0x12, - 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x3f, 0xe5, 0x13, 0x24, 0x1c, 0xff, - 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, - 0x7b, 0x06, 0x12, 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x22, 0xff, 0xe4, - 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b, - 0x06, 0x12, 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, 0x35, - 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, - 0x12, 0x13, 0xc8, 0xe5, 0x13, 0x24, 0x2e, 0xf5, 0x82, 0xe4, 0x35, - 0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x13, 0x24, 0x2f, 0xf5, 0x82, - 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x34, 0x24, 0x11, - 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0xc3, 0x13, - 0xff, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, - 0x83, 0xef, 0xf0, 0x30, 0x09, 0x41, 0xe5, 0x13, 0x24, 0x30, 0xf5, - 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x31, 0x60, - 0x04, 0x7e, 0x00, 0x80, 0x02, 0x7e, 0x10, 0xef, 0x4e, 0xf0, 0xe5, - 0x31, 0x60, 0x06, 0x7e, 0x00, 0x7f, 0x00, 0x80, 0x0f, 0xe5, 0x14, - 0x30, 0xe0, 0x06, 0x7e, 0x00, 0x7f, 0xff, 0x80, 0x04, 0x7e, 0x00, - 0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12, - 0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, - 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, 0x44, 0x40, 0xf0, 0xe5, 0x14, - 0x30, 0xe0, 0x0f, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, - 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x80, 0x02, 0x7f, 0x00, 0xe5, 0x13, - 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, - 0x22, 0x8f, 0x15, 0x8c, 0x16, 0x8d, 0x17, 0xe5, 0x15, 0xc3, 0x94, - 0x04, 0x50, 0x56, 0xe5, 0x15, 0x94, 0x00, 0x40, 0x06, 0x7a, 0x00, - 0x7b, 0x60, 0x80, 0x04, 0x7a, 0x00, 0x7b, 0xc0, 0xe5, 0x17, 0xc4, - 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, - 0x48, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x75, 0x93, 0xfd, 0x7c, 0x00, - 0x12, 0x03, 0xb0, 0xef, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, - 0xc4, 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, - 0xf0, 0x48, 0xfe, 0xe5, 0x15, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x03, - 0xb0, 0xed, 0x4c, 0x60, 0x63, 0x0b, 0xbb, 0x00, 0x01, 0x0a, 0x80, - 0x5c, 0x7a, 0x00, 0x7b, 0x1a, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, - 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, - 0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x75, 0x93, 0xfd, 0x7c, 0x00, - 0x12, 0x03, 0xb0, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, - 0xd8, 0xf9, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xae, 0x16, - 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, - 0xff, 0xe4, 0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x75, 0x93, 0xfd, - 0x7c, 0x00, 0x12, 0x03, 0xb0, 0xed, 0x4c, 0x60, 0x07, 0x74, 0x04, - 0x2b, 0xfb, 0xe4, 0x3a, 0xfa, 0xcf, 0xeb, 0xcf, 0xce, 0xea, 0xce, - 0x22, 0x8e, 0x13, 0x8f, 0x14, 0x8d, 0x15, 0xeb, 0x60, 0x09, 0x14, - 0x70, 0x1b, 0xaf, 0x15, 0x12, 0x0e, 0x0a, 0x22, 0x7e, 0x30, 0x7f, - 0xe0, 0xac, 0x13, 0xad, 0x14, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, - 0x13, 0xc8, 0xaf, 0x15, 0x12, 0x0e, 0x0a, 0x22, 0x8e, 0x13, 0x8f, - 0x14, 0x12, 0x10, 0xcd, 0xc3, 0xef, 0x95, 0x14, 0xff, 0xee, 0x95, - 0x13, 0xcd, 0xef, 0xcd, 0xfc, 0xd3, 0xed, 0x94, 0x00, 0xec, 0x64, - 0x80, 0x94, 0x80, 0x40, 0x05, 0xce, 0xec, 0xce, 0x80, 0x04, 0x7e, - 0x00, 0x7f, 0x01, 0xcc, 0xee, 0xcc, 0xec, 0x90, 0x00, 0x05, 0xf0, - 0x90, 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, - 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0xe4, 0x90, 0x00, - 0x05, 0xf0, 0xef, 0x60, 0x02, 0x80, 0x02, 0x7f, 0x01, 0x90, 0x00, - 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, 0x90, 0x00, - 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x90, 0x30, 0x3c, 0xef, 0xf0, - 0xee, 0x44, 0x80, 0xa3, 0xf0, 0x22, 0xe5, 0x34, 0x24, 0x11, 0xf5, - 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe6, 0x02, 0xd3, - 0x22, 0xc3, 0x22, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, - 0x0a, 0xf0, 0x30, 0x09, 0x32, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, - 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, - 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, - 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, - 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x12, 0x0e, 0xee, - 0x50, 0xf3, 0x90, 0x00, 0x0a, 0xe0, 0x20, 0xe5, 0x03, 0x30, 0x07, - 0x41, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x85, 0x34, - 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, - 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, - 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, - 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x34, 0x45, 0x33, - 0x70, 0x02, 0xc3, 0x22, 0x12, 0x0e, 0xee, 0x50, 0xf3, 0x80, 0xb5, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, - 0x12, 0x0d, 0xc8, 0xd3, 0x22, 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82, - 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe7, 0x3b, 0xe5, 0x34, - 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x65, - 0x2b, 0x70, 0x03, 0x75, 0x2b, 0xff, 0xe5, 0x34, 0x24, 0x1d, 0xf5, - 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x10, 0xe8, - 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x1a, 0x3e, 0x8e, 0x33, 0x8f, 0x34, - 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, - 0xc3, 0x22, 0xd2, 0x0a, 0xe5, 0x34, 0x24, 0x1b, 0xf5, 0x82, 0xe4, - 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x70, 0x3a, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, - 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xfe, 0xd0, 0x82, - 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xd3, 0x94, 0x00, 0xee, 0x64, - 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x10, 0x28, 0x80, 0xc6, 0x85, - 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0xee, - 0x64, 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x10, 0x28, 0x12, 0x10, - 0xcd, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, - 0xfd, 0xc3, 0x9f, 0xee, 0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, - 0x40, 0x20, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, - 0x82, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xed, 0x9f, 0xff, - 0xec, 0x9e, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xc2, - 0x0a, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, - 0xff, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, - 0x83, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xfd, 0xee, 0x94, 0x00, 0xfc, - 0x12, 0x10, 0x85, 0x50, 0x2c, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, - 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, - 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, - 0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x20, 0x0a, 0x03, 0x02, 0x0f, 0x38, - 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x1a, 0x3e, 0x8e, 0x33, 0x8f, 0x34, - 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xd3, 0x94, 0x00, - 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0d, 0x7e, 0x22, 0x7f, 0x10, - 0xad, 0x34, 0xac, 0x33, 0x12, 0x18, 0x42, 0x80, 0x1a, 0x12, 0x10, - 0xd8, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xee, 0x8f, 0xf0, 0x12, - 0x04, 0x05, 0x7e, 0x22, 0x7f, 0x30, 0xad, 0x34, 0xac, 0x33, 0x12, - 0x18, 0x42, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x65, - 0x34, 0x70, 0x03, 0xee, 0x65, 0x33, 0x70, 0x02, 0xd3, 0x22, 0x8e, - 0x33, 0x8f, 0x34, 0xc3, 0x22, 0xc3, 0xef, 0x94, 0x04, 0xee, 0x64, - 0x80, 0x94, 0x80, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0x04, 0xec, 0x64, - 0x80, 0x94, 0x80, 0x50, 0x01, 0x22, 0xc3, 0xef, 0x94, 0xfc, 0xee, - 0x64, 0x80, 0x94, 0x7f, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0xfc, 0xec, - 0x64, 0x80, 0x94, 0x7f, 0x50, 0x01, 0x22, 0xd3, 0xef, 0x94, 0x04, - 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x0d, 0xc3, 0xed, 0x94, 0xfc, - 0xec, 0x64, 0x80, 0x94, 0x7f, 0x40, 0x02, 0xd3, 0x22, 0xc3, 0x22, - 0x90, 0x30, 0x78, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0xff, 0x22, - 0x90, 0x30, 0x64, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0x25, 0xe0, - 0xff, 0xee, 0x33, 0xfe, 0x22, 0xc2, 0x0b, 0xe4, 0xf5, 0x14, 0x12, - 0x10, 0xf1, 0x22, 0xe4, 0xfe, 0xef, 0xf4, 0x60, 0x41, 0x74, 0x04, - 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe0, 0xb4, 0xff, - 0x23, 0x74, 0x04, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, - 0xef, 0xf0, 0x30, 0x0b, 0x0d, 0x74, 0x08, 0x2e, 0xf5, 0x82, 0xe4, - 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x14, 0xf0, 0x90, 0x00, 0x02, 0x74, - 0x01, 0xf0, 0x22, 0xbe, 0x03, 0x0a, 0x90, 0x00, 0x02, 0x74, 0x01, - 0xf0, 0xe4, 0xfe, 0x80, 0xc2, 0x0e, 0x80, 0xbf, 0x22, 0x8e, 0x15, - 0x8f, 0x16, 0xca, 0xed, 0xca, 0xc9, 0xeb, 0xc9, 0x30, 0x0a, 0x04, - 0x7f, 0x4a, 0x80, 0x02, 0x7f, 0x42, 0xcb, 0xef, 0xcb, 0xea, 0xc3, - 0x94, 0x04, 0x50, 0x02, 0x80, 0x01, 0xc3, 0x40, 0x04, 0xcb, 0x44, - 0x20, 0xcb, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xeb, 0xf0, 0xa3, - 0xe4, 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xa3, 0xa3, 0xe5, - 0x1a, 0xf0, 0xe5, 0x19, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xa3, - 0xa3, 0xa3, 0xf0, 0xe5, 0x16, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, - 0x15, 0xf5, 0x83, 0x74, 0x0f, 0xf0, 0xe5, 0x16, 0x24, 0x05, 0xf5, - 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x16, 0x24, - 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, - 0x16, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, - 0x10, 0xf0, 0xea, 0x90, 0x1b, 0x83, 0x93, 0xfb, 0xea, 0x64, 0x01, - 0x60, 0x08, 0xea, 0x64, 0x02, 0x60, 0x03, 0xba, 0x03, 0x04, 0xcb, - 0x44, 0x08, 0xcb, 0xe5, 0x16, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, - 0x15, 0xf5, 0x83, 0xeb, 0xf0, 0xe5, 0x16, 0x24, 0x15, 0xf5, 0x82, - 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0xff, 0xf0, 0xe5, 0x16, 0x24, - 0x16, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe9, 0xf0, 0xe5, - 0x16, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, - 0x04, 0xf0, 0x25, 0x1a, 0xf5, 0x1a, 0xe4, 0x35, 0x19, 0xf5, 0x19, - 0xea, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x02, 0x12, 0xf0, 0xea, 0x60, - 0x03, 0xba, 0x01, 0x1f, 0xea, 0x24, 0x01, 0xfd, 0xe4, 0x33, 0xfc, - 0xe5, 0x1a, 0xae, 0x19, 0x78, 0x03, 0xc3, 0x33, 0xce, 0x33, 0xce, - 0xd8, 0xf9, 0xff, 0x12, 0x03, 0xb0, 0x8e, 0x19, 0x8f, 0x1a, 0x02, - 0x12, 0xd0, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, - 0x00, 0x7f, 0x0b, 0x12, 0x03, 0x9e, 0xcc, 0xee, 0xcc, 0xcd, 0xef, - 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, - 0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x03, 0xb0, 0x8c, 0x1b, - 0x8d, 0x1c, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, - 0x00, 0x7f, 0x0b, 0x12, 0x03, 0x9e, 0xcc, 0xee, 0xcc, 0xcd, 0xef, - 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, - 0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x03, 0xb0, 0x8e, 0x19, - 0x8f, 0x1a, 0xe5, 0x1c, 0x45, 0x1b, 0x60, 0x08, 0x05, 0x1a, 0xe5, - 0x1a, 0x70, 0x02, 0x05, 0x19, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, - 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x03, 0x12, 0x03, 0x9e, 0xd3, 0xe5, - 0x1c, 0x9f, 0xe5, 0x1b, 0x9e, 0x50, 0x18, 0xe5, 0x1c, 0x45, 0x1b, - 0x60, 0x12, 0xba, 0x03, 0x0f, 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82, - 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe0, 0x44, 0x80, 0xf0, 0xe5, 0x16, - 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe5, 0x1a, - 0xf0, 0xe5, 0x19, 0xff, 0xe5, 0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, - 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x2d, 0xe5, 0x1a, 0x54, - 0x3f, 0xff, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, - 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x1a, 0xae, 0x19, 0x78, 0x06, 0xce, - 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe5, 0x16, 0x24, 0x0b, - 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0x85, 0x16, - 0x82, 0x85, 0x15, 0x83, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x90, 0x30, - 0x30, 0x74, 0x02, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90, - 0x30, 0x30, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, 0x12, 0x15, 0x12, 0x70, - 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xeb, 0xe5, 0x12, - 0x45, 0x11, 0x70, 0x12, 0x12, 0x13, 0xae, 0x90, 0x21, 0x00, 0xe0, - 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, 0x22, - 0xe4, 0x90, 0x34, 0x58, 0xf0, 0x90, 0x34, 0x32, 0x74, 0x1f, 0xf0, - 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90, 0x34, 0x81, 0xe0, 0x64, - 0x03, 0x60, 0x0e, 0xe5, 0x12, 0x15, 0x12, 0x70, 0x02, 0x15, 0x11, - 0xe5, 0x12, 0x45, 0x11, 0x70, 0xea, 0xe5, 0x12, 0x45, 0x11, 0x70, - 0x12, 0x12, 0x13, 0xae, 0x90, 0x21, 0x00, 0xe0, 0x60, 0x07, 0x90, - 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, 0x22, 0x90, 0x34, 0x98, - 0xe0, 0x44, 0x04, 0xf0, 0xe4, 0x90, 0x00, 0x01, 0xf0, 0xd3, 0x22, - 0x90, 0x00, 0x01, 0x74, 0x0e, 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x54, - 0xfb, 0xf0, 0x90, 0x34, 0x58, 0x74, 0x01, 0xf0, 0x90, 0x30, 0x30, - 0x74, 0x04, 0xf0, 0x22, 0x8e, 0x16, 0x8f, 0x17, 0x8c, 0x18, 0x8d, - 0x19, 0xe4, 0xff, 0xef, 0xc3, 0x9b, 0x50, 0x53, 0xe5, 0x1b, 0x30, - 0xe0, 0x12, 0xef, 0x7c, 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, 0x18, - 0x8d, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x1c, 0x80, 0x1f, 0xe5, 0x1b, - 0x30, 0xe1, 0x13, 0xef, 0x7c, 0x00, 0x25, 0x19, 0xfd, 0xec, 0x35, - 0x18, 0x8d, 0x82, 0xf5, 0x83, 0xe4, 0x93, 0xf5, 0x1c, 0x80, 0x07, - 0xe5, 0x19, 0x2f, 0xf8, 0xe6, 0xf5, 0x1c, 0xe5, 0x1b, 0x30, 0xe4, - 0x0f, 0xe5, 0x17, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x16, 0xf5, 0x83, - 0xe5, 0x1c, 0xf0, 0x80, 0x06, 0xe5, 0x17, 0x2f, 0xf8, 0xa6, 0x1c, - 0x0f, 0x80, 0xa8, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xc4, 0x33, 0x54, - 0xe0, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xab, 0x82, 0xfa, - 0x12, 0x10, 0xd8, 0x8b, 0x82, 0x8a, 0x83, 0xee, 0x8f, 0xf0, 0x12, - 0x04, 0x05, 0x7e, 0x22, 0x7f, 0x30, 0xcd, 0xeb, 0xcd, 0xcc, 0xea, - 0xcc, 0x12, 0x18, 0x42, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, - 0x12, 0x10, 0xe8, 0x22, 0xe5, 0x30, 0x12, 0x04, 0x3f, 0x14, 0x83, - 0x00, 0x14, 0xf1, 0x01, 0x15, 0x59, 0x02, 0x15, 0xed, 0x03, 0x16, - 0x41, 0x04, 0x16, 0x88, 0x05, 0x16, 0xfb, 0x06, 0x17, 0x6a, 0x07, - 0x00, 0x00, 0x17, 0xa2, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, - 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34, - 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, - 0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6, - 0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d, - 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, - 0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7, - 0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d, - 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, - 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, - 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, - 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x08, 0x90, 0x34, - 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, - 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, 0xe5, 0x27, 0x30, - 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, - 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x1f, 0x43, 0x12, - 0x08, 0x80, 0x1a, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, - 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, - 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, - 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, - 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x43, 0x12, - 0x01, 0x43, 0x12, 0x04, 0xe5, 0x26, 0x30, 0xe5, 0x5c, 0x90, 0x34, - 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x1c, - 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, - 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, - 0x30, 0x43, 0x12, 0x08, 0x80, 0x2b, 0xe5, 0x27, 0x30, 0xe6, 0x05, - 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, - 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0xe5, - 0x27, 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, - 0x4f, 0xf0, 0xe4, 0xf5, 0x2c, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, - 0x80, 0x15, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0xe5, 0x27, - 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0x4f, - 0xf0, 0x90, 0x30, 0x35, 0xe0, 0xf5, 0x12, 0x53, 0x12, 0xe0, 0xe5, - 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, - 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x30, 0xe5, 0x3c, 0x90, 0x34, 0x98, - 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, - 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, - 0x53, 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0xe5, 0x26, 0x54, - 0xc0, 0x60, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x80, 0x06, - 0x53, 0x12, 0xfe, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, - 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0xc2, - 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, - 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, - 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, - 0x53, 0x12, 0xf7, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x08, 0x53, 0x12, - 0xfe, 0x53, 0x12, 0xfb, 0x80, 0x06, 0x43, 0x12, 0x01, 0x43, 0x12, - 0x04, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0x90, 0x30, 0x3a, - 0xe5, 0x12, 0xf0, 0x22, 0x20, 0x02, 0x13, 0x12, 0x1c, 0x39, 0xaf, - 0x29, 0x7e, 0x00, 0x12, 0x1c, 0x70, 0xaf, 0x35, 0x7e, 0x00, 0x12, - 0x1c, 0x77, 0xd2, 0x02, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, - 0x26, 0x20, 0xe5, 0x0d, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x34, - 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, - 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x2c, 0xc2, 0x01, 0x12, - 0x00, 0x06, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, - 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, - 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0x43, 0x12, 0x01, 0x43, 0x12, - 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x30, 0x01, 0x03, - 0x02, 0x17, 0xa2, 0x12, 0x18, 0xf4, 0xd2, 0x01, 0x22, 0xc2, 0x01, - 0x12, 0x00, 0x06, 0xe5, 0x26, 0x20, 0xe5, 0x09, 0x90, 0x34, 0x98, - 0xe0, 0x54, 0xfe, 0xf0, 0x80, 0x55, 0x90, 0x34, 0x98, 0xe0, 0x44, - 0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, 0xe5, 0x27, 0x30, 0xe6, - 0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, 0x12, 0x02, 0x80, 0x0d, - 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, - 0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, 0xe5, 0x27, 0x30, 0xe7, - 0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, 0x12, 0x08, 0x80, 0x0d, - 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, - 0x12, 0xf7, 0x43, 0x12, 0x01, 0x53, 0x12, 0xfb, 0x90, 0x30, 0x3a, - 0xe5, 0x12, 0xf0, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x22, 0xe5, - 0x26, 0x30, 0xe5, 0x2c, 0x20, 0x03, 0x21, 0xd2, 0x03, 0x12, 0x1c, - 0x39, 0x75, 0x35, 0x06, 0x75, 0x29, 0x09, 0xaf, 0x29, 0x7e, 0x00, - 0x12, 0x1c, 0x70, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0x53, 0x12, - 0xfe, 0x43, 0x12, 0x04, 0xe5, 0x12, 0xf0, 0x90, 0x34, 0x98, 0xe0, - 0x44, 0x01, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, - 0x22, 0xe4, 0xff, 0xe5, 0x30, 0x24, 0xfe, 0x70, 0x2c, 0xe4, 0xfe, - 0xee, 0xc3, 0x95, 0x2c, 0x50, 0x12, 0x74, 0x01, 0xc8, 0xee, 0xc8, - 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xcf, 0x4f, 0xcf, 0x0e, - 0x80, 0xe8, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0xfe, 0xe5, 0x27, - 0x54, 0x1f, 0x6f, 0xf4, 0xce, 0x4e, 0xce, 0xee, 0xf0, 0x22, 0x90, - 0x29, 0xa0, 0xe0, 0x70, 0x63, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, - 0x74, 0xc2, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, - 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa0, 0xf0, 0x90, 0x30, 0x8c, - 0xe4, 0xf0, 0xa3, 0x74, 0xc5, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, - 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa1, 0xf0, - 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc4, 0xf0, 0xa3, 0x74, - 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, - 0x29, 0xa2, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc3, - 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, - 0xe0, 0x90, 0x29, 0xa3, 0xf0, 0x22, 0x8c, 0x13, 0x8d, 0x14, 0xef, - 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, - 0xe0, 0x4c, 0x60, 0x41, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, - 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83, 0xe0, - 0xfc, 0xa3, 0xe0, 0xfd, 0x85, 0x14, 0x82, 0x85, 0x13, 0x83, 0xe0, - 0xfa, 0xa3, 0xe0, 0xfb, 0xd3, 0xed, 0x9b, 0xea, 0x64, 0x80, 0xf8, - 0xec, 0x64, 0x80, 0x98, 0x40, 0x13, 0xef, 0x24, 0x1e, 0xf5, 0x82, - 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xce, 0xec, 0xce, - 0xff, 0x80, 0xaf, 0xad, 0x14, 0xac, 0x13, 0x12, 0x1a, 0x71, 0x22, - 0x12, 0x08, 0xca, 0x50, 0x4f, 0xe5, 0x34, 0x24, 0x12, 0xff, 0xe4, - 0x35, 0x33, 0xfe, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, - 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, 0x0d, 0xa0, 0xe5, - 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, - 0xff, 0x7e, 0x00, 0x12, 0x0e, 0x29, 0x90, 0x00, 0x0a, 0x74, 0x40, - 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x40, 0xff, 0xf0, 0x90, 0x00, - 0x0a, 0x74, 0x80, 0xf0, 0x4f, 0x90, 0x00, 0x0b, 0xf0, 0x90, 0x30, - 0xe9, 0x74, 0x01, 0xf0, 0x75, 0x2f, 0x06, 0x22, 0x90, 0x30, 0x3a, - 0xe0, 0xff, 0xe5, 0x27, 0x30, 0xe6, 0x12, 0x30, 0x0c, 0x06, 0xef, - 0x54, 0xf5, 0xfe, 0x80, 0x04, 0xef, 0x44, 0x0a, 0xfe, 0xcf, 0xee, - 0xcf, 0x80, 0x10, 0x30, 0x0c, 0x06, 0xef, 0x44, 0x0a, 0xfe, 0x80, - 0x04, 0xef, 0x54, 0xf5, 0xfe, 0xcf, 0xee, 0xcf, 0xcf, 0x54, 0xfe, - 0xcf, 0xcf, 0x44, 0x04, 0xcf, 0x90, 0x30, 0x3a, 0xef, 0xf0, 0x30, - 0x0c, 0x09, 0x7f, 0x08, 0x7e, 0x00, 0x12, 0x1c, 0x70, 0x80, 0x07, - 0x7f, 0x22, 0x7e, 0x01, 0x12, 0x1c, 0x70, 0xb2, 0x0c, 0x22, 0xc0, - 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, - 0x08, 0xc2, 0xaf, 0xc2, 0x8c, 0xc2, 0x8d, 0xd3, 0xe5, 0x4a, 0x94, - 0x00, 0xe5, 0x49, 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4a, 0x15, 0x4a, - 0x70, 0x02, 0x15, 0x49, 0xd3, 0xe5, 0x4c, 0x94, 0x00, 0xe5, 0x4b, - 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4c, 0x15, 0x4c, 0x70, 0x02, 0x15, - 0x4b, 0x12, 0x00, 0x0e, 0xd2, 0x8c, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, - 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0x30, 0x07, 0x3c, - 0xe5, 0x2f, 0x70, 0x38, 0xc2, 0x07, 0x90, 0x22, 0x2e, 0xe0, 0xfe, - 0xa3, 0xe0, 0x8e, 0x11, 0xf5, 0x12, 0x90, 0x22, 0x4e, 0xe0, 0xfe, - 0xa3, 0xe0, 0xff, 0x90, 0x22, 0x2e, 0xee, 0xf0, 0xa3, 0xef, 0xf0, - 0x90, 0x22, 0x4e, 0xe5, 0x11, 0xf0, 0xa3, 0xe5, 0x12, 0xf0, 0x8e, - 0x33, 0x8f, 0x34, 0x30, 0x08, 0x05, 0x12, 0x14, 0x2b, 0xc2, 0x08, - 0xc2, 0x09, 0x12, 0x0e, 0x47, 0x22, 0x7f, 0x80, 0x7e, 0x29, 0xe4, - 0xfd, 0xfc, 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfb, 0x74, 0x45, 0x2d, - 0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x04, 0x2f, 0xf5, 0x82, 0xe4, 0x3e, - 0xf5, 0x83, 0xe0, 0xfb, 0x74, 0x41, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, - 0x74, 0x08, 0x2f, 0xff, 0xe4, 0x3e, 0xfe, 0x0d, 0xbd, 0x00, 0x01, - 0x0c, 0xed, 0x64, 0x04, 0x4c, 0x70, 0xcf, 0x22, 0x90, 0x00, 0x00, - 0x74, 0x0e, 0xf0, 0x00, 0x00, 0x00, 0xe4, 0xf0, 0x12, 0x05, 0xcb, - 0x12, 0x1c, 0x84, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, - 0x30, 0xb4, 0x05, 0x0a, 0x12, 0x1c, 0x51, 0x50, 0x0d, 0x12, 0x18, - 0xf4, 0x80, 0x08, 0xe5, 0x30, 0xb4, 0x07, 0x03, 0x12, 0x06, 0xe8, - 0x12, 0x04, 0x6b, 0x80, 0xe4, 0x80, 0xfe, 0x22, 0xef, 0x24, 0x1e, - 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb, - 0xca, 0xec, 0xca, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, - 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, - 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xce, 0xea, 0xce, - 0xcf, 0xeb, 0xcf, 0x22, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, - 0xf5, 0x83, 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xed, 0x24, 0x1e, 0xf5, - 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xea, 0xf0, 0xa3, 0xeb, 0xf0, 0xef, - 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, - 0xed, 0xf0, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc2, 0xaf, 0xc2, 0x8e, - 0xc2, 0x8f, 0xd3, 0xe5, 0x40, 0x94, 0x00, 0xe5, 0x3f, 0x94, 0x00, - 0x40, 0x0d, 0xe5, 0x40, 0x15, 0x40, 0x70, 0x02, 0x15, 0x3f, 0x12, - 0x1c, 0x67, 0xd2, 0x8e, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, - 0x12, 0x08, 0xca, 0x50, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1c, - 0x7d, 0x7e, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x13, 0xc8, 0x90, - 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, - 0x12, 0x0e, 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x19, 0xce, 0x90, - 0x21, 0x01, 0xe0, 0xf5, 0x28, 0x74, 0x41, 0x25, 0x28, 0xf8, 0xe6, - 0xf5, 0x32, 0x74, 0x45, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x22, 0x90, - 0x21, 0x00, 0xe0, 0x60, 0x03, 0xd2, 0x0d, 0x22, 0xc2, 0x0d, 0x22, - 0x90, 0x34, 0x30, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x1f, 0xf0, - 0xa3, 0xe4, 0xf0, 0x90, 0x01, 0x10, 0xe0, 0x20, 0xe1, 0x03, 0x00, - 0x80, 0xf6, 0x90, 0x01, 0x12, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, - 0xf6, 0x22, 0xe4, 0xff, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x90, 0x30, - 0x8c, 0xf0, 0xef, 0x90, 0x1b, 0xba, 0x93, 0x90, 0x30, 0x8d, 0xf0, - 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, - 0x22, 0xe4, 0xff, 0xef, 0x90, 0x1b, 0xc4, 0x93, 0x90, 0x30, 0x8c, - 0xf0, 0xef, 0x90, 0x1b, 0xba, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, - 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, - 0x02, 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, - 0x6c, 0x90, 0xc8, 0x00, 0x01, 0x02, 0x03, 0x0b, 0x0f, 0x0a, 0x0e, - 0x09, 0x0d, 0x08, 0x0c, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0x3f, 0x4f, 0xf0, 0x90, 0x01, 0x02, - 0xe0, 0x44, 0x80, 0xf0, 0x22, 0xe4, 0xf5, 0x31, 0x90, 0x00, 0x0a, - 0x74, 0xff, 0xf0, 0x90, 0x22, 0x2e, 0x74, 0x21, 0xf0, 0xa3, 0x74, - 0x10, 0xf0, 0x22, 0x52, 0x53, 0x54, 0x12, 0x15, 0x16, 0x10, 0x11, - 0x40, 0x00, 0x20, 0x00, 0x40, 0xff, 0x3f, 0x3f, 0xbd, 0x28, 0x21, - 0x00, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, 0x74, 0xb0, 0xf0, - 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x22, 0x75, 0x31, 0x01, - 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, - 0x20, 0xf0, 0x22, 0x02, 0x1f, 0x07, 0x67, 0x18, 0x9f, 0x06, 0x60, - 0x00, 0x09, 0x1a, 0xc5, 0x05, 0x2f, 0x1c, 0x11, 0x90, 0x30, 0x40, - 0x74, 0x32, 0xf0, 0xa3, 0x74, 0xb0, 0xf0, 0xa3, 0xe4, 0xf0, 0xa3, - 0xf0, 0x22, 0x12, 0x08, 0xca, 0x50, 0x08, 0xd2, 0x09, 0x12, 0x0e, - 0x47, 0xe4, 0xf5, 0x2f, 0x22, 0x90, 0x34, 0x30, 0x74, 0x1f, 0xf0, - 0xa3, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0x22, 0x78, 0x7f, 0xe4, - 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x4c, 0x02, 0x1a, 0x07, 0xc2, 0xaf, - 0xc2, 0x8c, 0xc2, 0x8d, 0x12, 0x00, 0x0e, 0xd2, 0xaf, 0x22, 0xc2, - 0x8e, 0x8e, 0x3f, 0x8f, 0x40, 0x12, 0x1c, 0x67, 0xd2, 0x8e, 0x22, - 0xe5, 0x4a, 0x45, 0x49, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, - 0xe5, 0x4c, 0x45, 0x4b, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, - 0xc2, 0x8f, 0x75, 0x8d, 0xf5, 0x75, 0x8b, 0x41, 0x22, 0x8e, 0x49, - 0x8f, 0x4a, 0xd2, 0x8c, 0x22, 0x8e, 0x4b, 0x8f, 0x4c, 0xd2, 0x8c, - 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x0d, 0xe4, 0xf5, - 0x2e, 0x22, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0xbb, 0x60 -}; - -static const uint8_t rt2661_ucode[] = { - 0x02, 0x12, 0xde, 0x02, 0x14, 0xf0, 0xc2, 0x8c, 0x22, 0x22, 0x00, - 0x02, 0x16, 0xe5, 0xc2, 0xaf, 0xc2, 0x8d, 0x75, 0x8c, 0x94, 0x75, - 0x8a, 0x93, 0xd2, 0xaf, 0x22, 0x02, 0x19, 0x89, 0xe5, 0x30, 0x12, - 0x0f, 0xe5, 0x00, 0x3f, 0x00, 0x00, 0xad, 0x01, 0x01, 0x15, 0x02, - 0x01, 0xa9, 0x03, 0x01, 0xfd, 0x04, 0x02, 0x44, 0x05, 0x02, 0xb7, - 0x06, 0x03, 0x26, 0x07, 0x00, 0x00, 0x03, 0x5e, 0xc2, 0x01, 0x12, - 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, - 0xe5, 0x08, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, - 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, - 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, - 0x12, 0x02, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, - 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, - 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, - 0x12, 0x08, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, - 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x43, 0x12, - 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, - 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, - 0xe5, 0x08, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, - 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, - 0x1c, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, - 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, - 0x80, 0x1f, 0x43, 0x12, 0x08, 0x80, 0x1a, 0xe5, 0x27, 0x30, 0xe6, - 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, - 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, - 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, - 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, 0xe0, - 0xf5, 0x12, 0x43, 0x12, 0x01, 0x43, 0x12, 0x04, 0xe5, 0x26, 0x30, - 0xe5, 0x5c, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, - 0x54, 0xc0, 0x60, 0x1c, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, - 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, - 0x53, 0x12, 0xf7, 0x80, 0x30, 0x43, 0x12, 0x08, 0x80, 0x2b, 0xe5, - 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, 0x80, 0x03, 0x53, 0x12, - 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, 0x08, 0x80, 0x03, - 0x53, 0x12, 0xf7, 0xe5, 0x27, 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, - 0x34, 0xe0, 0x54, 0xe0, 0x4f, 0xf0, 0xe4, 0xf5, 0x2c, 0x90, 0x30, - 0x3a, 0xe5, 0x12, 0xf0, 0x80, 0x15, 0x90, 0x34, 0x98, 0xe0, 0x54, - 0xfe, 0xf0, 0xe5, 0x27, 0xf4, 0x54, 0x1f, 0xff, 0x90, 0x30, 0x34, - 0xe0, 0x54, 0xe0, 0x4f, 0xf0, 0x90, 0x30, 0x35, 0xe0, 0xf5, 0x12, - 0x53, 0x12, 0xe0, 0xe5, 0x12, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, - 0x06, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x30, 0xe5, - 0x3c, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x27, 0x30, - 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, - 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, - 0x08, 0xe5, 0x26, 0x54, 0xc0, 0x60, 0x08, 0x43, 0x12, 0x01, 0x43, - 0x12, 0x04, 0x80, 0x06, 0x53, 0x12, 0xfe, 0x43, 0x12, 0x04, 0x90, - 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x90, 0x34, 0x98, 0xe0, 0x54, - 0xfe, 0xf0, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0x90, 0x30, 0x3a, - 0xe0, 0xf5, 0x12, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, 0x02, - 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, - 0x12, 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0xe5, 0x26, 0x54, 0xc0, - 0x60, 0x08, 0x53, 0x12, 0xfe, 0x53, 0x12, 0xfb, 0x80, 0x06, 0x43, - 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, - 0xf0, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x22, 0x20, 0x02, 0x13, - 0x12, 0x1c, 0x9c, 0xaf, 0x29, 0x7e, 0x00, 0x12, 0x1c, 0xf2, 0xaf, - 0x35, 0x7e, 0x00, 0x12, 0x1c, 0xf9, 0xd2, 0x02, 0x90, 0x30, 0x3a, - 0xe0, 0xf5, 0x12, 0xe5, 0x26, 0x20, 0xe5, 0x0d, 0xc2, 0x01, 0x12, - 0x00, 0x06, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x90, - 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x54, 0xc0, 0x60, - 0x2c, 0xc2, 0x01, 0x12, 0x00, 0x06, 0xe5, 0x27, 0x30, 0xe6, 0x05, - 0x53, 0x12, 0xfd, 0x80, 0x03, 0x43, 0x12, 0x02, 0xe5, 0x27, 0x30, - 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x03, 0x43, 0x12, 0x08, 0x43, - 0x12, 0x01, 0x43, 0x12, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, - 0x22, 0x30, 0x01, 0x03, 0x02, 0x03, 0x5e, 0x12, 0x09, 0x81, 0xd2, - 0x01, 0x22, 0xc2, 0x01, 0x12, 0x00, 0x06, 0xe5, 0x26, 0x20, 0xe5, - 0x09, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfe, 0xf0, 0x80, 0x55, 0x90, - 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x26, 0x30, 0xe6, 0x0f, - 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x12, 0xfd, 0x80, 0x12, 0x43, - 0x12, 0x02, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x12, - 0x02, 0x80, 0x03, 0x53, 0x12, 0xfd, 0xe5, 0x26, 0x30, 0xe7, 0x0f, - 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x53, 0x12, 0xf7, 0x80, 0x12, 0x43, - 0x12, 0x08, 0x80, 0x0d, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x12, - 0x08, 0x80, 0x03, 0x53, 0x12, 0xf7, 0x43, 0x12, 0x01, 0x53, 0x12, - 0xfb, 0x90, 0x30, 0x3a, 0xe5, 0x12, 0xf0, 0x90, 0x30, 0x3a, 0xe0, - 0xf5, 0x12, 0x22, 0xe5, 0x26, 0x30, 0xe5, 0x2c, 0x20, 0x03, 0x21, - 0xd2, 0x03, 0x12, 0x1c, 0x9c, 0x75, 0x35, 0x06, 0x75, 0x29, 0x09, - 0xaf, 0x29, 0x7e, 0x00, 0x12, 0x1c, 0xf2, 0x90, 0x30, 0x3a, 0xe0, - 0xf5, 0x12, 0x53, 0x12, 0xfe, 0x43, 0x12, 0x04, 0xe5, 0x12, 0xf0, - 0x90, 0x34, 0x98, 0xe0, 0x44, 0x01, 0xf0, 0x22, 0x90, 0x34, 0x98, - 0xe0, 0x54, 0xfe, 0xf0, 0x22, 0x12, 0x1c, 0x72, 0x40, 0x03, 0x02, - 0x05, 0x5f, 0x90, 0x21, 0x02, 0xe0, 0xf5, 0x2d, 0x90, 0x00, 0x03, - 0xe0, 0x12, 0x0f, 0xe5, 0x03, 0xf1, 0x00, 0x04, 0x0f, 0x01, 0x03, - 0x9f, 0x10, 0x03, 0xb0, 0x11, 0x04, 0x33, 0x20, 0x04, 0x8e, 0x21, - 0x04, 0xb1, 0x22, 0x04, 0xc5, 0x30, 0x04, 0xd0, 0x31, 0x05, 0x16, - 0x50, 0x04, 0xe0, 0x51, 0x05, 0x33, 0x52, 0x05, 0x47, 0x60, 0x00, - 0x00, 0x05, 0x55, 0x90, 0x00, 0x0a, 0xe0, 0x20, 0xe5, 0x03, 0x30, - 0x07, 0x03, 0xd2, 0x08, 0x22, 0x12, 0x18, 0xb6, 0x22, 0x90, 0x21, - 0x00, 0xe0, 0xf5, 0x11, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24, - 0x21, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe0, 0x44, 0x80, - 0xf0, 0xe5, 0x11, 0xc4, 0x33, 0x54, 0xe0, 0x24, 0x2c, 0xf5, 0x82, - 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, 0x11, 0xf0, 0xc4, 0x33, 0x54, - 0xe0, 0x24, 0x2d, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe5, - 0x2d, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, 0x12, 0x08, 0xc7, - 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x31, 0x60, 0x05, 0x12, 0x09, 0x5c, - 0x80, 0x03, 0x12, 0x09, 0x6d, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, - 0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x75, 0x31, 0xff, 0x90, 0x01, 0x00, - 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x54, 0xfe, 0xf0, - 0x54, 0x3e, 0xf0, 0xe4, 0x90, 0x00, 0x0b, 0xf0, 0xf0, 0x90, 0x21, - 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x7e, 0x2b, 0x7f, - 0x80, 0x7d, 0x03, 0x12, 0x0a, 0x4f, 0x90, 0x34, 0xcd, 0xe0, 0x20, - 0xe3, 0xf9, 0x90, 0x21, 0x14, 0x12, 0x0f, 0xc1, 0x90, 0x34, 0xc0, - 0x12, 0x0f, 0xcd, 0x90, 0x21, 0x18, 0x12, 0x0f, 0xc1, 0x90, 0x34, - 0xc8, 0x12, 0x0f, 0xcd, 0x90, 0x21, 0x1c, 0x12, 0x0f, 0xc1, 0x90, - 0x34, 0xc4, 0x12, 0x0f, 0xcd, 0x90, 0x34, 0xcc, 0x74, 0x01, 0xf0, - 0xa3, 0xe0, 0x44, 0x04, 0xf0, 0x90, 0x01, 0x01, 0xe0, 0x44, 0x01, - 0xf0, 0x44, 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x10, 0xf0, - 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, - 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, 0x01, 0xe0, - 0x54, 0xfe, 0xf0, 0x54, 0xbf, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, - 0xef, 0xf0, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, - 0xe0, 0x22, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0x4f, - 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, - 0xd2, 0x05, 0x85, 0x2d, 0x23, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0x22, - 0x12, 0x1b, 0x23, 0xc2, 0x00, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, - 0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x85, 0x2d, 0x25, 0x90, 0x00, 0x0b, - 0xe0, 0x54, 0xfb, 0xff, 0xf0, 0xe4, 0x90, 0x00, 0x07, 0xf0, 0x90, - 0x00, 0x0a, 0x74, 0x04, 0xf0, 0xe4, 0x90, 0x00, 0x08, 0xf0, 0x90, - 0x21, 0x00, 0xe0, 0x90, 0x00, 0x09, 0xf0, 0x90, 0x00, 0x07, 0x74, - 0x71, 0xf0, 0xef, 0x44, 0x04, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90, - 0x21, 0x03, 0xf0, 0x22, 0x90, 0x21, 0x00, 0xe0, 0xff, 0x54, 0x1f, - 0xf5, 0x30, 0xa3, 0xe0, 0xf5, 0x27, 0x8f, 0x26, 0x12, 0x00, 0x1e, - 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, - 0x90, 0x21, 0x00, 0xe0, 0xf5, 0x2c, 0x12, 0x18, 0xed, 0xe4, 0x90, - 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, 0x22, 0x12, 0x1a, - 0x02, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, - 0x22, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, - 0x22, 0x8e, 0x15, 0x8f, 0x16, 0xca, 0xed, 0xca, 0xc9, 0xeb, 0xc9, - 0x30, 0x0a, 0x04, 0x7f, 0x4a, 0x80, 0x02, 0x7f, 0x42, 0xcb, 0xef, - 0xcb, 0xea, 0xc3, 0x94, 0x04, 0x50, 0x02, 0x80, 0x01, 0xc3, 0x40, - 0x04, 0xcb, 0x44, 0x20, 0xcb, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, - 0xeb, 0xf0, 0xa3, 0xe4, 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, - 0xa3, 0xa3, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0x85, 0x16, 0x82, 0x85, - 0x15, 0x83, 0xa3, 0xa3, 0xa3, 0xf0, 0xe5, 0x16, 0x24, 0x04, 0xf5, - 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0x0f, 0xf0, 0xe5, 0x16, - 0x24, 0x05, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe4, 0xf0, - 0xe5, 0x16, 0x24, 0x06, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, - 0xe4, 0xf0, 0xe5, 0x16, 0x24, 0x07, 0xf5, 0x82, 0xe4, 0x35, 0x15, - 0xf5, 0x83, 0x74, 0x10, 0xf0, 0xea, 0x90, 0x1b, 0x4b, 0x93, 0xfb, - 0xea, 0x64, 0x01, 0x60, 0x08, 0xea, 0x64, 0x02, 0x60, 0x03, 0xba, - 0x03, 0x04, 0xcb, 0x44, 0x08, 0xcb, 0xe5, 0x16, 0x24, 0x08, 0xf5, - 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xeb, 0xf0, 0xe5, 0x16, 0x24, - 0x15, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0x74, 0xff, 0xf0, - 0xe5, 0x16, 0x24, 0x16, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, - 0xe9, 0xf0, 0xe5, 0x16, 0x24, 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, - 0xf5, 0x83, 0x74, 0x04, 0xf0, 0x25, 0x1a, 0xf5, 0x1a, 0xe4, 0x35, - 0x19, 0xf5, 0x19, 0xea, 0xc3, 0x94, 0x04, 0x40, 0x03, 0x02, 0x07, - 0x17, 0xea, 0x60, 0x03, 0xba, 0x01, 0x1f, 0xea, 0x24, 0x01, 0xfd, - 0xe4, 0x33, 0xfc, 0xe5, 0x1a, 0xae, 0x19, 0x78, 0x03, 0xc3, 0x33, - 0xce, 0x33, 0xce, 0xd8, 0xf9, 0xff, 0x12, 0x0f, 0x56, 0x8e, 0x19, - 0x8f, 0x1a, 0x02, 0x06, 0xf7, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, - 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x0f, 0x44, 0xcc, 0xee, - 0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8, - 0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x0f, - 0x56, 0x8c, 0x1b, 0x8d, 0x1c, 0xea, 0x24, 0xff, 0xfd, 0xe4, 0x34, - 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x0b, 0x12, 0x0f, 0x44, 0xcc, 0xee, - 0xcc, 0xcd, 0xef, 0xcd, 0xe5, 0x1a, 0xc4, 0xf8, 0x54, 0x0f, 0xc8, - 0x68, 0xff, 0xe5, 0x19, 0xc4, 0x54, 0xf0, 0x48, 0xfe, 0x12, 0x0f, - 0x56, 0x8e, 0x19, 0x8f, 0x1a, 0xe5, 0x1c, 0x45, 0x1b, 0x60, 0x08, - 0x05, 0x1a, 0xe5, 0x1a, 0x70, 0x02, 0x05, 0x19, 0xea, 0x24, 0xff, - 0xfd, 0xe4, 0x34, 0xff, 0xfc, 0x7e, 0x00, 0x7f, 0x03, 0x12, 0x0f, - 0x44, 0xd3, 0xe5, 0x1c, 0x9f, 0xe5, 0x1b, 0x9e, 0x50, 0x18, 0xe5, - 0x1c, 0x45, 0x1b, 0x60, 0x12, 0xba, 0x03, 0x0f, 0xe5, 0x16, 0x24, - 0x09, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xe0, 0x44, 0x80, - 0xf0, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, - 0x83, 0xe5, 0x1a, 0xf0, 0xe5, 0x19, 0xff, 0xe5, 0x16, 0x24, 0x0b, - 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x2d, - 0xe5, 0x1a, 0x54, 0x3f, 0xff, 0xe5, 0x16, 0x24, 0x0a, 0xf5, 0x82, - 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x1a, 0xae, 0x19, - 0x78, 0x06, 0xce, 0xc3, 0x13, 0xce, 0x13, 0xd8, 0xf9, 0xff, 0xe5, - 0x16, 0x24, 0x0b, 0xf5, 0x82, 0xe4, 0x35, 0x15, 0xf5, 0x83, 0xef, - 0xf0, 0x85, 0x16, 0x82, 0x85, 0x15, 0x83, 0xe0, 0x44, 0x01, 0xf0, - 0x22, 0x90, 0x34, 0xcd, 0xe0, 0xf9, 0x20, 0xe3, 0xf8, 0xe5, 0x2b, - 0xf4, 0x60, 0x66, 0x90, 0x34, 0xc0, 0x12, 0x0f, 0xc1, 0x85, 0x34, - 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x0f, - 0xd9, 0xe5, 0x82, 0x24, 0x04, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, - 0x83, 0x12, 0x0f, 0xcd, 0x90, 0x34, 0xc8, 0x12, 0x0f, 0xc1, 0x85, - 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, - 0x0f, 0xd9, 0xe5, 0x82, 0x24, 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83, - 0xf5, 0x83, 0x12, 0x0f, 0xcd, 0x90, 0x34, 0xd0, 0x12, 0x0f, 0xc1, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, - 0x12, 0x0f, 0xd9, 0xe5, 0x82, 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, - 0x83, 0xf5, 0x83, 0x12, 0x0f, 0xcd, 0xe5, 0x34, 0x24, 0xf0, 0xff, - 0xe5, 0x33, 0x34, 0xde, 0xfe, 0xef, 0x78, 0x05, 0xce, 0xc3, 0x13, - 0xce, 0x13, 0xd8, 0xf9, 0xf5, 0x2b, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0x75, 0xf0, 0x20, 0x12, 0x0f, 0xd9, 0xe5, 0x82, 0x24, 0x04, - 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x0f, 0xc1, 0x90, - 0x34, 0xc0, 0x12, 0x0f, 0xcd, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x0f, 0xd9, 0xe5, 0x82, 0x24, - 0x08, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x0f, 0xc1, - 0x90, 0x34, 0xc8, 0x12, 0x0f, 0xcd, 0x85, 0x34, 0x82, 0x85, 0x33, - 0x83, 0x75, 0xf0, 0x20, 0xe5, 0x2b, 0x12, 0x0f, 0xd9, 0xe5, 0x82, - 0x24, 0x0c, 0xf5, 0x82, 0xe4, 0x35, 0x83, 0xf5, 0x83, 0x12, 0x0f, - 0xc1, 0x90, 0x34, 0xc4, 0x12, 0x0f, 0xcd, 0x90, 0x01, 0x01, 0xe0, - 0x44, 0x40, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0, 0xe9, - 0x44, 0x04, 0x90, 0x34, 0xcd, 0xf0, 0x90, 0x34, 0xcc, 0xe0, 0x44, - 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, - 0xf0, 0x22, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, - 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xed, 0x24, 0x1e, 0xf5, 0x82, 0xe4, - 0x3c, 0xf5, 0x83, 0xea, 0xf0, 0xa3, 0xeb, 0xf0, 0xef, 0x24, 0x1e, - 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, - 0x22, 0x00, 0x00, 0x90, 0x00, 0x00, 0x74, 0x0e, 0xf0, 0x00, 0x00, - 0x00, 0xe4, 0xf0, 0x12, 0x08, 0xc7, 0x12, 0x1d, 0x06, 0x90, 0x34, - 0x98, 0xe0, 0x44, 0x01, 0xf0, 0xe5, 0x30, 0xb4, 0x05, 0x0a, 0x12, - 0x1c, 0xca, 0x50, 0x0d, 0x12, 0x09, 0x81, 0x80, 0x08, 0xe5, 0x30, - 0xb4, 0x07, 0x03, 0x12, 0x09, 0xd0, 0x12, 0x10, 0xd7, 0x80, 0xe4, - 0x80, 0xfe, 0x22, 0xc2, 0xaf, 0xe4, 0xf5, 0x2f, 0xf5, 0x88, 0x75, - 0xa8, 0x0f, 0x75, 0x89, 0x11, 0xf5, 0xb8, 0xf5, 0xe8, 0x75, 0x90, - 0x0f, 0x75, 0x31, 0xff, 0x75, 0x2b, 0xff, 0x90, 0x22, 0x2e, 0xf0, - 0xa3, 0xf0, 0x90, 0x22, 0x4e, 0xf0, 0xa3, 0xf0, 0xc2, 0x05, 0xc2, - 0x08, 0xc2, 0x00, 0xc2, 0x07, 0xc2, 0x04, 0x90, 0x00, 0x0a, 0x74, - 0xff, 0xf0, 0x90, 0x00, 0x0b, 0x74, 0x01, 0xf0, 0x90, 0x01, 0x03, - 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0x04, 0xf0, 0x90, 0x01, 0x05, - 0x74, 0xff, 0xf0, 0xe4, 0x90, 0x01, 0x06, 0xf0, 0x90, 0x00, 0x04, - 0xf0, 0x90, 0x30, 0xe8, 0x74, 0x10, 0xf0, 0x90, 0x01, 0x07, 0xf0, - 0x90, 0x01, 0x08, 0x04, 0xf0, 0x90, 0x01, 0x09, 0x74, 0x48, 0xf0, - 0x90, 0x01, 0x0a, 0x74, 0x7f, 0xf0, 0x90, 0x01, 0x02, 0x74, 0x1f, - 0xf0, 0x90, 0x01, 0x00, 0x74, 0x14, 0xf0, 0x90, 0x01, 0x01, 0x74, - 0x20, 0xf0, 0x90, 0x00, 0x00, 0xe0, 0x44, 0x80, 0xf0, 0x75, 0x49, - 0x00, 0x75, 0x4a, 0x01, 0xc2, 0x01, 0xd2, 0xaf, 0x22, 0x75, 0x31, - 0x01, 0x90, 0x00, 0x0a, 0x74, 0xff, 0xf0, 0x90, 0x00, 0x0b, 0xe0, - 0x44, 0x20, 0xf0, 0x22, 0xe4, 0xf5, 0x31, 0x90, 0x00, 0x0a, 0x74, - 0xff, 0xf0, 0x90, 0x22, 0x2e, 0x74, 0x21, 0xf0, 0xa3, 0x74, 0x10, - 0xf0, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xff, 0xe5, 0x27, 0x30, 0xe6, - 0x12, 0x30, 0x0c, 0x06, 0xef, 0x54, 0xf5, 0xfe, 0x80, 0x04, 0xef, - 0x44, 0x0a, 0xfe, 0xcf, 0xee, 0xcf, 0x80, 0x10, 0x30, 0x0c, 0x06, - 0xef, 0x44, 0x0a, 0xfe, 0x80, 0x04, 0xef, 0x54, 0xf5, 0xfe, 0xcf, - 0xee, 0xcf, 0xcf, 0x54, 0xfe, 0xcf, 0xcf, 0x44, 0x04, 0xcf, 0x90, - 0x30, 0x3a, 0xef, 0xf0, 0x30, 0x0c, 0x09, 0x7f, 0x08, 0x7e, 0x00, - 0x12, 0x1c, 0xf2, 0x80, 0x07, 0x7f, 0x22, 0x7e, 0x01, 0x12, 0x1c, - 0xf2, 0xb2, 0x0c, 0x22, 0x90, 0x30, 0x3a, 0xe0, 0xf5, 0x10, 0x12, - 0x1c, 0xd5, 0x50, 0x26, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x53, 0x10, - 0xfd, 0x80, 0x03, 0x43, 0x10, 0x02, 0xe5, 0x27, 0x30, 0xe7, 0x05, - 0x53, 0x10, 0xf7, 0x80, 0x03, 0x43, 0x10, 0x08, 0x53, 0x10, 0xfe, - 0x43, 0x10, 0x04, 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0x12, 0x1c, - 0xca, 0x50, 0x48, 0x90, 0x01, 0x03, 0xe0, 0xf5, 0x10, 0x54, 0x1c, - 0x60, 0x3e, 0xe5, 0x10, 0x54, 0xe3, 0xf0, 0xa3, 0xe0, 0xf5, 0x10, - 0xf0, 0xe5, 0x27, 0x30, 0xe6, 0x05, 0x43, 0x10, 0x02, 0x80, 0x03, - 0x53, 0x10, 0xfd, 0xe5, 0x27, 0x30, 0xe7, 0x05, 0x43, 0x10, 0x08, - 0x80, 0x03, 0x53, 0x10, 0xf7, 0x53, 0x10, 0xfe, 0x43, 0x10, 0x04, - 0x90, 0x30, 0x3a, 0xe5, 0x10, 0xf0, 0xaf, 0x29, 0x7e, 0x00, 0x12, - 0x1c, 0xf2, 0xaf, 0x35, 0x7e, 0x00, 0x12, 0x1c, 0xf9, 0x22, 0x8e, - 0x12, 0x8f, 0x13, 0x8d, 0x14, 0xe5, 0x14, 0xa2, 0xe1, 0x92, 0x09, - 0xe5, 0x34, 0x24, 0x19, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, - 0xe0, 0xfd, 0xe5, 0x34, 0x24, 0x1a, 0xf5, 0x82, 0xe4, 0x35, 0x33, - 0xf5, 0x83, 0xe0, 0xfb, 0xa2, 0x09, 0x92, 0x0a, 0x75, 0x19, 0x00, - 0x75, 0x1a, 0x1a, 0x12, 0x05, 0x60, 0x30, 0x09, 0x04, 0x7f, 0xc8, - 0x80, 0x02, 0x7f, 0xe8, 0xe5, 0x13, 0x24, 0x18, 0xf5, 0x82, 0xe4, - 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x31, 0x60, 0x04, 0x7f, - 0x02, 0x80, 0x02, 0x7f, 0x01, 0xe5, 0x13, 0x24, 0x19, 0xf5, 0x82, - 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x34, 0x24, 0x19, - 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x7d, 0x1a, - 0x7c, 0x00, 0x12, 0x10, 0x11, 0xe5, 0x13, 0x24, 0x1a, 0xf5, 0x82, - 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0xe5, 0x13, 0x24, 0x1b, - 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xee, 0xf0, 0xe5, 0x31, - 0x60, 0x60, 0xe5, 0x13, 0x24, 0x1c, 0xff, 0xe4, 0x35, 0x12, 0xfe, - 0xe5, 0x34, 0x24, 0x12, 0xfd, 0xe4, 0x35, 0x33, 0xfc, 0x75, 0x1b, - 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, 0x22, 0xff, - 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, 0x1b, 0x11, - 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, 0x28, 0xff, 0xe4, - 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x08, 0x75, 0x1b, 0x11, 0x7b, - 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x34, 0x24, 0x18, 0xf5, 0x82, 0xe4, - 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0xe5, 0x13, 0x24, 0x2d, 0xf5, - 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x80, 0x3f, 0xe5, - 0x13, 0x24, 0x1c, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, - 0x10, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, - 0x24, 0x22, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x08, - 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, - 0x28, 0xff, 0xe4, 0x35, 0x12, 0xfe, 0x7c, 0x30, 0x7d, 0x10, 0x75, - 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xe5, 0x13, 0x24, 0x2e, - 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe4, 0xf0, 0xe5, 0x13, - 0x24, 0x2f, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe4, 0xf0, - 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, - 0xe0, 0xff, 0xc3, 0x13, 0xff, 0xe5, 0x13, 0x24, 0x30, 0xf5, 0x82, - 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x30, 0x09, 0x41, 0xe5, - 0x13, 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, - 0xff, 0xe5, 0x31, 0x60, 0x04, 0x7e, 0x00, 0x80, 0x02, 0x7e, 0x10, - 0xef, 0x4e, 0xf0, 0xe5, 0x31, 0x60, 0x06, 0x7e, 0x00, 0x7f, 0x00, - 0x80, 0x0f, 0xe5, 0x14, 0x30, 0xe0, 0x06, 0x7e, 0x00, 0x7f, 0xff, - 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, 0xf5, - 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, 0x13, - 0x24, 0x30, 0xf5, 0x82, 0xe4, 0x35, 0x12, 0xf5, 0x83, 0xe0, 0x44, - 0x40, 0xf0, 0xe5, 0x14, 0x30, 0xe0, 0x0f, 0xe5, 0x34, 0x24, 0x10, - 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x80, 0x02, - 0x7f, 0x00, 0xe5, 0x13, 0x24, 0x31, 0xf5, 0x82, 0xe4, 0x35, 0x12, - 0xf5, 0x83, 0xef, 0xf0, 0x22, 0xe5, 0x34, 0x24, 0x11, 0xf5, 0x82, - 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe7, 0x3b, 0xe5, 0x34, - 0x24, 0x1c, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x65, - 0x2b, 0x70, 0x03, 0x75, 0x2b, 0xff, 0xe5, 0x34, 0x24, 0x1d, 0xf5, - 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xff, 0x12, 0x1c, 0xe0, - 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x19, 0x56, 0x8e, 0x33, 0x8f, 0x34, - 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, - 0xc3, 0x22, 0xd2, 0x0a, 0xe5, 0x34, 0x24, 0x1b, 0xf5, 0x82, 0xe4, - 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x70, 0x3a, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, - 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xfe, 0xd0, 0x82, - 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xd3, 0x94, 0x00, 0xee, 0x64, - 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x0d, 0x68, 0x80, 0xc6, 0x85, - 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xc3, 0xee, - 0x64, 0x80, 0x94, 0x80, 0x50, 0x03, 0x02, 0x0d, 0x68, 0x12, 0x1c, - 0xbf, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, - 0xfd, 0xc3, 0x9f, 0xee, 0x64, 0x80, 0xf8, 0xec, 0x64, 0x80, 0x98, - 0x40, 0x20, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, 0xc0, - 0x82, 0xa3, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0xed, 0x9f, 0xff, - 0xec, 0x9e, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xc2, - 0x0a, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, - 0xff, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, - 0x83, 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xfd, 0xee, 0x94, 0x00, 0xfc, - 0x12, 0x17, 0x30, 0x50, 0x2c, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, - 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, - 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, - 0xa3, 0xef, 0xf0, 0xc2, 0x0a, 0x20, 0x0a, 0x03, 0x02, 0x0c, 0x78, - 0x7e, 0x22, 0x7f, 0x10, 0x12, 0x19, 0x56, 0x8e, 0x33, 0x8f, 0x34, - 0x8f, 0x82, 0x8e, 0x83, 0xe0, 0xfe, 0xa3, 0xe0, 0xd3, 0x94, 0x00, - 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0d, 0x7e, 0x22, 0x7f, 0x10, - 0xad, 0x34, 0xac, 0x33, 0x12, 0x16, 0x33, 0x80, 0x1a, 0x12, 0x1c, - 0x35, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xee, 0x8f, 0xf0, 0x12, - 0x0f, 0xab, 0x7e, 0x22, 0x7f, 0x30, 0xad, 0x34, 0xac, 0x33, 0x12, - 0x16, 0x33, 0x90, 0x22, 0x2e, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x65, - 0x34, 0x70, 0x03, 0xee, 0x65, 0x33, 0x70, 0x02, 0xd3, 0x22, 0x8e, - 0x33, 0x8f, 0x34, 0xc3, 0x22, 0xe5, 0x31, 0x64, 0x01, 0x70, 0x41, - 0x12, 0x1b, 0x83, 0x40, 0x03, 0x02, 0x0f, 0x43, 0x12, 0x1c, 0x00, - 0x50, 0x20, 0x7e, 0x2b, 0x7f, 0x80, 0x7d, 0x03, 0x12, 0x0a, 0x4f, - 0x7f, 0x01, 0x12, 0x1a, 0x27, 0x40, 0x09, 0xd2, 0x09, 0x12, 0x11, - 0x9b, 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x07, 0x4f, 0x75, 0x2f, 0x01, - 0x22, 0x7f, 0x01, 0x12, 0x1a, 0x27, 0x50, 0x04, 0x75, 0x2f, 0x02, - 0x22, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, 0x22, 0x12, - 0x1a, 0xcc, 0x50, 0x51, 0x12, 0x1c, 0x55, 0x90, 0x30, 0xf4, 0xe0, - 0xf5, 0x2a, 0x7e, 0x30, 0x7f, 0xec, 0xa3, 0xe0, 0xfd, 0xe4, 0xfb, - 0x12, 0x19, 0xda, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0xb4, 0x90, 0x00, - 0x0a, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xff, - 0xf0, 0xfd, 0x90, 0x01, 0x05, 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, - 0xe0, 0x44, 0x20, 0xf0, 0xed, 0x54, 0xbf, 0x90, 0x00, 0x0b, 0xf0, - 0x90, 0x34, 0xcc, 0xe0, 0x44, 0x01, 0xf0, 0xa3, 0xe0, 0x44, 0x01, - 0xf0, 0xa3, 0xe0, 0x44, 0x01, 0xf0, 0xd2, 0x04, 0x12, 0x1a, 0xe9, - 0x50, 0x43, 0x12, 0x1b, 0x06, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x30, - 0x7d, 0xec, 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, - 0x30, 0xf5, 0xe0, 0x75, 0xf0, 0x20, 0xa4, 0xff, 0xae, 0xf0, 0x12, - 0x1c, 0xb4, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xff, 0xf0, 0xfd, - 0xe4, 0x90, 0x00, 0x04, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, - 0xf0, 0x90, 0x00, 0x0a, 0x74, 0x40, 0xf0, 0x4d, 0x90, 0x00, 0x0b, - 0xf0, 0xc2, 0x04, 0x12, 0x1b, 0xad, 0x50, 0x38, 0x12, 0x1b, 0x06, - 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, 0x00, 0x75, 0x1b, 0x12, - 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, - 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0xb4, 0x90, - 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, - 0x90, 0x01, 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xc2, 0x04, 0x12, 0x1b, - 0xd7, 0x50, 0x25, 0x12, 0x1b, 0x06, 0x7f, 0x02, 0x12, 0x1a, 0x27, - 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0x90, 0x00, 0x0b, 0xe0, - 0x54, 0xfd, 0xff, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xef, 0x54, - 0xbf, 0x90, 0x00, 0x0b, 0xf0, 0xc2, 0x04, 0x12, 0x1b, 0x83, 0x50, - 0x2d, 0x12, 0x1b, 0x06, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, - 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00, - 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x90, 0x01, 0x06, - 0xe0, 0x54, 0xdf, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, - 0xc2, 0x04, 0x22, 0xef, 0x8d, 0xf0, 0xa4, 0xa8, 0xf0, 0xcf, 0x8c, - 0xf0, 0xa4, 0x28, 0xce, 0x8d, 0xf0, 0xa4, 0x2e, 0xfe, 0x22, 0xbc, - 0x00, 0x0b, 0xbe, 0x00, 0x29, 0xef, 0x8d, 0xf0, 0x84, 0xff, 0xad, - 0xf0, 0x22, 0xe4, 0xcc, 0xf8, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, - 0xee, 0x33, 0xfe, 0xec, 0x33, 0xfc, 0xee, 0x9d, 0xec, 0x98, 0x40, - 0x05, 0xfc, 0xee, 0x9d, 0xfe, 0x0f, 0xd5, 0xf0, 0xe9, 0xe4, 0xce, - 0xfd, 0x22, 0xed, 0xf8, 0xf5, 0xf0, 0xee, 0x84, 0x20, 0xd2, 0x1c, - 0xfe, 0xad, 0xf0, 0x75, 0xf0, 0x08, 0xef, 0x2f, 0xff, 0xed, 0x33, - 0xfd, 0x40, 0x07, 0x98, 0x50, 0x06, 0xd5, 0xf0, 0xf2, 0x22, 0xc3, - 0x98, 0xfd, 0x0f, 0xd5, 0xf0, 0xea, 0x22, 0xc5, 0xf0, 0xf8, 0xa3, - 0xe0, 0x28, 0xf0, 0xc5, 0xf0, 0xf8, 0xe5, 0x82, 0x15, 0x82, 0x70, - 0x02, 0x15, 0x83, 0xe0, 0x38, 0xf0, 0x22, 0xe0, 0xfc, 0xa3, 0xe0, - 0xfd, 0xa3, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x22, 0xec, 0xf0, 0xa3, - 0xed, 0xf0, 0xa3, 0xee, 0xf0, 0xa3, 0xef, 0xf0, 0x22, 0xa4, 0x25, - 0x82, 0xf5, 0x82, 0xe5, 0xf0, 0x35, 0x83, 0xf5, 0x83, 0x22, 0xd0, - 0x83, 0xd0, 0x82, 0xf8, 0xe4, 0x93, 0x70, 0x12, 0x74, 0x01, 0x93, - 0x70, 0x0d, 0xa3, 0xa3, 0x93, 0xf8, 0x74, 0x01, 0x93, 0xf5, 0x82, - 0x88, 0x83, 0xe4, 0x73, 0x74, 0x02, 0x93, 0x68, 0x60, 0xef, 0xa3, - 0xa3, 0xa3, 0x80, 0xdf, 0x8a, 0x83, 0x89, 0x82, 0xe4, 0x73, 0x8f, - 0x15, 0x8c, 0x16, 0x8d, 0x17, 0xe5, 0x15, 0xc3, 0x94, 0x04, 0x50, - 0x56, 0xe5, 0x15, 0x94, 0x00, 0x40, 0x06, 0x7a, 0x00, 0x7b, 0x60, - 0x80, 0x04, 0x7a, 0x00, 0x7b, 0xc0, 0xe5, 0x17, 0xc4, 0xf8, 0x54, - 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48, 0xfe, - 0xe5, 0x15, 0x90, 0x1b, 0x3d, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x0f, - 0x56, 0xef, 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xc4, 0xf8, - 0x54, 0x0f, 0xc8, 0x68, 0xff, 0xe5, 0x16, 0xc4, 0x54, 0xf0, 0x48, - 0xfe, 0xe5, 0x15, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x0f, 0x56, 0xed, - 0x4c, 0x60, 0x63, 0x0b, 0xbb, 0x00, 0x01, 0x0a, 0x80, 0x5c, 0x7a, - 0x00, 0x7b, 0x1a, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, 0xc3, 0x33, - 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, 0x3e, 0xfe, - 0xe5, 0x15, 0x90, 0x1b, 0x3d, 0x93, 0xfd, 0x7c, 0x00, 0x12, 0x0f, - 0x56, 0xef, 0x78, 0x02, 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, - 0x2b, 0xfb, 0xee, 0x3a, 0xfa, 0xe5, 0x17, 0xae, 0x16, 0x78, 0x02, - 0xc3, 0x33, 0xce, 0x33, 0xce, 0xd8, 0xf9, 0x24, 0x0b, 0xff, 0xe4, - 0x3e, 0xfe, 0xe5, 0x15, 0x90, 0x1b, 0x3d, 0x93, 0xfd, 0x7c, 0x00, - 0x12, 0x0f, 0x56, 0xed, 0x4c, 0x60, 0x07, 0x74, 0x04, 0x2b, 0xfb, - 0xe4, 0x3a, 0xfa, 0xcf, 0xeb, 0xcf, 0xce, 0xea, 0xce, 0x22, 0xe5, - 0x2e, 0x14, 0x60, 0x1d, 0x14, 0x60, 0x3d, 0x14, 0x60, 0x5d, 0x14, - 0x70, 0x03, 0x02, 0x11, 0x84, 0x24, 0x04, 0x60, 0x03, 0x02, 0x11, - 0x9a, 0x20, 0x0d, 0x03, 0x02, 0x11, 0x9a, 0x75, 0x2e, 0x01, 0x22, - 0x90, 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x03, 0x44, 0x20, 0xf0, - 0xe5, 0x40, 0x45, 0x3f, 0x60, 0x03, 0x02, 0x11, 0x9a, 0x75, 0x2e, - 0x02, 0x12, 0x1a, 0x4a, 0x12, 0x1c, 0x13, 0xaf, 0x28, 0x12, 0x1b, - 0x57, 0x22, 0x90, 0x01, 0x03, 0xe0, 0xff, 0x30, 0xe7, 0x76, 0xef, - 0x44, 0x80, 0x90, 0x01, 0x03, 0xf0, 0x12, 0x18, 0x42, 0x12, 0x1a, - 0x8d, 0x12, 0x1c, 0x45, 0x75, 0x2e, 0x03, 0xaf, 0x22, 0x7e, 0x00, - 0x12, 0x1c, 0xa8, 0x22, 0xe5, 0x40, 0x45, 0x3f, 0x70, 0x21, 0x12, - 0x15, 0x66, 0x12, 0x1c, 0x13, 0x12, 0x1a, 0x6d, 0x12, 0x1c, 0x45, - 0x12, 0x1c, 0x8e, 0x30, 0x0d, 0x0b, 0x75, 0x2e, 0x01, 0xaf, 0x32, - 0x7e, 0x00, 0x12, 0x1c, 0xa8, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, - 0x00, 0x0a, 0xe0, 0xff, 0x30, 0xe5, 0x2c, 0x44, 0x20, 0xf0, 0x12, - 0x15, 0x66, 0x12, 0x1c, 0x13, 0x12, 0x1a, 0x6d, 0x12, 0x1c, 0x45, - 0x12, 0x1c, 0x8e, 0x75, 0x2e, 0x04, 0x22, 0xe5, 0x40, 0x45, 0x3f, - 0x70, 0x10, 0x30, 0x0d, 0x0a, 0x75, 0x2e, 0x01, 0xaf, 0x32, 0xfe, - 0x12, 0x1c, 0xa8, 0x22, 0xe4, 0xf5, 0x2e, 0x22, 0x90, 0x00, 0x04, - 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0x30, 0x09, 0x32, 0xe5, - 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xc0, 0x83, 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, - 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, - 0xe0, 0xfd, 0xc3, 0xef, 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, - 0x83, 0xf0, 0xa3, 0xef, 0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, - 0xc3, 0x22, 0x12, 0x0c, 0x2e, 0x50, 0xf3, 0x90, 0x00, 0x0a, 0xe0, - 0x20, 0xe5, 0x03, 0x30, 0x07, 0x41, 0xe5, 0x34, 0x45, 0x33, 0x70, - 0x02, 0xc3, 0x22, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xc0, 0x83, - 0xc0, 0x82, 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x85, 0x34, 0x82, 0x85, - 0x33, 0x83, 0xa3, 0xa3, 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0xc3, 0xef, - 0x9d, 0xff, 0xee, 0x9c, 0xd0, 0x82, 0xd0, 0x83, 0xf0, 0xa3, 0xef, - 0xf0, 0xe5, 0x34, 0x45, 0x33, 0x70, 0x02, 0xc3, 0x22, 0x12, 0x0c, - 0x2e, 0x50, 0xf3, 0x80, 0xb5, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, - 0xe0, 0xfe, 0xa3, 0xe0, 0xff, 0x12, 0x17, 0xc0, 0xd3, 0x22, 0x12, - 0x1b, 0xad, 0x40, 0x05, 0x12, 0x1b, 0x83, 0x50, 0x44, 0x7e, 0x30, - 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, - 0x12, 0x15, 0xd0, 0x90, 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, - 0x0a, 0xf0, 0xe4, 0xff, 0xfe, 0x12, 0x1c, 0xb4, 0x90, 0x00, 0x0b, - 0xe0, 0x54, 0xbf, 0xf0, 0x54, 0x7f, 0xff, 0xf0, 0xe4, 0x90, 0x30, - 0xe9, 0xf0, 0xef, 0x54, 0xfd, 0x90, 0x00, 0x0b, 0xf0, 0xe4, 0x90, - 0x00, 0x04, 0xf0, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, - 0x12, 0x1b, 0xc2, 0x50, 0x48, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, - 0x7d, 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, - 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xe4, 0xff, - 0xfe, 0x12, 0x1c, 0xb4, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, - 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, 0x04, 0xf0, 0xff, 0x12, 0x1a, - 0x27, 0x50, 0x04, 0x75, 0x2f, 0x07, 0x22, 0x90, 0x01, 0x04, 0xe0, - 0x54, 0x7f, 0xf0, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, - 0x22, 0x78, 0x7f, 0xe4, 0xf6, 0xd8, 0xfd, 0x75, 0x81, 0x4c, 0x02, - 0x13, 0x25, 0x02, 0x08, 0x90, 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, - 0xa3, 0x40, 0x03, 0xf6, 0x80, 0x01, 0xf2, 0x08, 0xdf, 0xf4, 0x80, - 0x29, 0xe4, 0x93, 0xa3, 0xf8, 0x54, 0x07, 0x24, 0x0c, 0xc8, 0xc3, - 0x33, 0xc4, 0x54, 0x0f, 0x44, 0x20, 0xc8, 0x83, 0x40, 0x04, 0xf4, - 0x56, 0x80, 0x01, 0x46, 0xf6, 0xdf, 0xe4, 0x80, 0x0b, 0x01, 0x02, - 0x04, 0x08, 0x10, 0x20, 0x40, 0x80, 0x90, 0x00, 0x0a, 0xe4, 0x7e, - 0x01, 0x93, 0x60, 0xbc, 0xa3, 0xff, 0x54, 0x3f, 0x30, 0xe5, 0x09, - 0x54, 0x1f, 0xfe, 0xe4, 0x93, 0xa3, 0x60, 0x01, 0x0e, 0xcf, 0x54, - 0xc0, 0x25, 0xe0, 0x60, 0xa8, 0x40, 0xb8, 0xe4, 0x93, 0xa3, 0xfa, - 0xe4, 0x93, 0xa3, 0xf8, 0xe4, 0x93, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, - 0xca, 0xc5, 0x83, 0xca, 0xf0, 0xa3, 0xc8, 0xc5, 0x82, 0xc8, 0xca, - 0xc5, 0x83, 0xca, 0xdf, 0xe9, 0xde, 0xe7, 0x80, 0xbe, 0x12, 0x1b, - 0x83, 0x50, 0x2d, 0x12, 0x19, 0x22, 0x90, 0x01, 0x06, 0xe0, 0x54, - 0xdf, 0xf0, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, 0x00, 0x75, - 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00, 0x04, 0x74, - 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, 0x11, 0x9b, - 0xe4, 0xf5, 0x2f, 0x22, 0x12, 0x1b, 0xd7, 0x50, 0x50, 0x12, 0x19, - 0x22, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xe4, 0x90, 0x00, - 0x04, 0xf0, 0x90, 0x01, 0x03, 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, - 0xe0, 0x44, 0x80, 0xf0, 0x7f, 0x02, 0x12, 0x1a, 0x27, 0x50, 0x04, - 0x75, 0x2f, 0x05, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, 0x7d, - 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, 0x00, - 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, 0x12, - 0x11, 0x9b, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0xe4, 0xf5, - 0x2f, 0x22, 0x90, 0x30, 0x30, 0x74, 0x02, 0xf0, 0x75, 0x11, 0x07, - 0x75, 0x12, 0xd0, 0x90, 0x30, 0x30, 0xe0, 0x30, 0xe0, 0x0e, 0xe5, - 0x12, 0x15, 0x12, 0x70, 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, - 0x70, 0xeb, 0xe5, 0x12, 0x45, 0x11, 0x70, 0x12, 0x12, 0x1b, 0x23, - 0x90, 0x21, 0x00, 0xe0, 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, - 0x04, 0xf0, 0xc3, 0x22, 0xe4, 0x90, 0x34, 0x58, 0xf0, 0x90, 0x34, - 0x32, 0x74, 0x1f, 0xf0, 0x75, 0x11, 0x07, 0x75, 0x12, 0xd0, 0x90, - 0x34, 0x81, 0xe0, 0x64, 0x03, 0x60, 0x0e, 0xe5, 0x12, 0x15, 0x12, - 0x70, 0x02, 0x15, 0x11, 0xe5, 0x12, 0x45, 0x11, 0x70, 0xea, 0xe5, - 0x12, 0x45, 0x11, 0x70, 0x12, 0x12, 0x1b, 0x23, 0x90, 0x21, 0x00, - 0xe0, 0x60, 0x07, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xc3, - 0x22, 0x90, 0x34, 0x98, 0xe0, 0x44, 0x04, 0xf0, 0xe4, 0x90, 0x00, - 0x01, 0xf0, 0xd3, 0x22, 0x12, 0x1b, 0x6e, 0x50, 0x72, 0x12, 0x1c, - 0xbf, 0x85, 0x34, 0x82, 0x85, 0x33, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, - 0xc3, 0x9f, 0xf5, 0x12, 0xec, 0x9e, 0xf5, 0x11, 0xd3, 0xe5, 0x12, - 0x94, 0x00, 0xe5, 0x11, 0x64, 0x80, 0x94, 0x80, 0x40, 0x06, 0xae, - 0x11, 0xaf, 0x12, 0x80, 0x04, 0x7e, 0x00, 0x7f, 0x00, 0x8e, 0x11, - 0x8f, 0x12, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, - 0xf5, 0x83, 0xe0, 0xc3, 0x95, 0x12, 0xf5, 0x12, 0xe4, 0x95, 0x11, - 0xf5, 0x11, 0xc3, 0x64, 0x80, 0x94, 0x80, 0x50, 0x05, 0xe4, 0xf5, - 0x11, 0xf5, 0x12, 0xe5, 0x34, 0x24, 0x12, 0xff, 0xe4, 0x35, 0x33, - 0xfe, 0xad, 0x12, 0x7b, 0x01, 0x12, 0x19, 0xda, 0x90, 0x01, 0x05, - 0x74, 0x20, 0xf0, 0x90, 0x01, 0x06, 0xe0, 0x44, 0x20, 0xf0, 0x75, - 0x2f, 0x03, 0x22, 0xc0, 0xe0, 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, - 0xc0, 0xd0, 0x75, 0xd0, 0x08, 0xc2, 0xaf, 0x90, 0x22, 0x2e, 0xe0, - 0xfe, 0xa3, 0xe0, 0x8e, 0x33, 0xf5, 0x34, 0xe5, 0x2f, 0x25, 0xe0, - 0x24, 0x25, 0xf5, 0x82, 0xe4, 0x34, 0x1c, 0xf5, 0x83, 0xe4, 0x93, - 0xfe, 0x74, 0x01, 0x93, 0xca, 0xee, 0xca, 0xf9, 0x12, 0x10, 0x0b, - 0x12, 0x1c, 0x80, 0x50, 0x02, 0xd2, 0x07, 0x12, 0x18, 0x02, 0x12, - 0x03, 0x5f, 0x12, 0x1b, 0x98, 0x50, 0x05, 0xaf, 0x25, 0x12, 0x1c, - 0xe0, 0x30, 0x05, 0x1b, 0xe5, 0x2f, 0x70, 0x17, 0x20, 0x04, 0x14, - 0x12, 0x13, 0xf2, 0x92, 0x00, 0xc2, 0x05, 0xd2, 0x0b, 0xa2, 0x00, - 0xe4, 0x33, 0xf5, 0x14, 0xaf, 0x23, 0x12, 0x17, 0x78, 0xd2, 0xaf, - 0xd0, 0xd0, 0xd0, 0x82, 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, - 0x90, 0x29, 0xa0, 0xe0, 0x70, 0x63, 0x90, 0x30, 0x8c, 0xe4, 0xf0, - 0xa3, 0x74, 0xc2, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, - 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa0, 0xf0, 0x90, 0x30, - 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc5, 0xf0, 0xa3, 0x74, 0x01, 0xf0, - 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, 0x90, 0x29, 0xa1, - 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, 0xc4, 0xf0, 0xa3, - 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, 0x8c, 0xe0, 0xff, - 0x90, 0x29, 0xa2, 0xf0, 0x90, 0x30, 0x8c, 0xe4, 0xf0, 0xa3, 0x74, - 0xc3, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, - 0x8c, 0xe0, 0x90, 0x29, 0xa3, 0xf0, 0x22, 0x8e, 0x16, 0x8f, 0x17, - 0x8c, 0x18, 0x8d, 0x19, 0xe4, 0xff, 0xef, 0xc3, 0x9b, 0x50, 0x53, - 0xe5, 0x1b, 0x30, 0xe0, 0x12, 0xef, 0x7c, 0x00, 0x25, 0x19, 0xfd, - 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, 0x83, 0xe0, 0xf5, 0x1c, 0x80, - 0x1f, 0xe5, 0x1b, 0x30, 0xe1, 0x13, 0xef, 0x7c, 0x00, 0x25, 0x19, - 0xfd, 0xec, 0x35, 0x18, 0x8d, 0x82, 0xf5, 0x83, 0xe4, 0x93, 0xf5, - 0x1c, 0x80, 0x07, 0xe5, 0x19, 0x2f, 0xf8, 0xe6, 0xf5, 0x1c, 0xe5, - 0x1b, 0x30, 0xe4, 0x0f, 0xe5, 0x17, 0x2f, 0xf5, 0x82, 0xe4, 0x35, - 0x16, 0xf5, 0x83, 0xe5, 0x1c, 0xf0, 0x80, 0x06, 0xe5, 0x17, 0x2f, - 0xf8, 0xa6, 0x1c, 0x0f, 0x80, 0xa8, 0x22, 0x8c, 0x13, 0x8d, 0x14, - 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, - 0xa3, 0xe0, 0x4c, 0x60, 0x41, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, - 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xf5, 0x82, 0x8c, 0x83, - 0xe0, 0xfc, 0xa3, 0xe0, 0xfd, 0x85, 0x14, 0x82, 0x85, 0x13, 0x83, - 0xe0, 0xfa, 0xa3, 0xe0, 0xfb, 0xd3, 0xed, 0x9b, 0xea, 0x64, 0x80, - 0xf8, 0xec, 0x64, 0x80, 0x98, 0x40, 0x13, 0xef, 0x24, 0x1e, 0xf5, - 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xce, 0xec, - 0xce, 0xff, 0x80, 0xaf, 0xad, 0x14, 0xac, 0x13, 0x12, 0x08, 0x63, - 0x22, 0x12, 0x1b, 0x6e, 0x50, 0x4f, 0xe5, 0x34, 0x24, 0x12, 0xff, - 0xe4, 0x35, 0x33, 0xfe, 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, - 0x35, 0x33, 0xf5, 0x83, 0xe0, 0xfd, 0xe4, 0xfb, 0x12, 0x19, 0xda, - 0xe5, 0x34, 0x24, 0x10, 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, - 0xe0, 0xff, 0x7e, 0x00, 0x12, 0x1c, 0xb4, 0x90, 0x00, 0x0a, 0x74, - 0x40, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x40, 0xff, 0xf0, 0x90, - 0x00, 0x0a, 0x74, 0x80, 0xf0, 0x4f, 0x90, 0x00, 0x0b, 0xf0, 0x90, - 0x30, 0xe9, 0x74, 0x01, 0xf0, 0x75, 0x2f, 0x06, 0x22, 0xc0, 0xe0, - 0xc0, 0xf0, 0xc0, 0x83, 0xc0, 0x82, 0xc0, 0xd0, 0x75, 0xd0, 0x08, - 0xc2, 0xaf, 0xc2, 0x8c, 0xc2, 0x8d, 0xd3, 0xe5, 0x4a, 0x94, 0x00, - 0xe5, 0x49, 0x94, 0x00, 0x40, 0x08, 0xe5, 0x4a, 0x15, 0x4a, 0x70, - 0x02, 0x15, 0x49, 0xd3, 0xe5, 0x4c, 0x94, 0x00, 0xe5, 0x4b, 0x94, - 0x00, 0x40, 0x08, 0xe5, 0x4c, 0x15, 0x4c, 0x70, 0x02, 0x15, 0x4b, - 0x12, 0x00, 0x0e, 0xd2, 0x8c, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0x82, - 0xd0, 0x83, 0xd0, 0xf0, 0xd0, 0xe0, 0x32, 0xc3, 0xef, 0x94, 0x04, - 0xee, 0x64, 0x80, 0x94, 0x80, 0x40, 0x0c, 0xd3, 0xed, 0x94, 0x04, - 0xec, 0x64, 0x80, 0x94, 0x80, 0x50, 0x01, 0x22, 0xc3, 0xef, 0x94, - 0xfc, 0xee, 0x64, 0x80, 0x94, 0x7f, 0x40, 0x0c, 0xd3, 0xed, 0x94, - 0xfc, 0xec, 0x64, 0x80, 0x94, 0x7f, 0x50, 0x01, 0x22, 0xd3, 0xef, - 0x94, 0x04, 0xee, 0x64, 0x80, 0x94, 0x80, 0x50, 0x0d, 0xc3, 0xed, - 0x94, 0xfc, 0xec, 0x64, 0x80, 0x94, 0x7f, 0x40, 0x02, 0xd3, 0x22, - 0xc3, 0x22, 0xe4, 0xfe, 0xef, 0xf4, 0x60, 0x41, 0x74, 0x04, 0x2e, - 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xe0, 0xb4, 0xff, 0x23, - 0x74, 0x04, 0x2e, 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xf5, 0x83, 0xef, - 0xf0, 0x30, 0x0b, 0x0d, 0x74, 0x08, 0x2e, 0xf5, 0x82, 0xe4, 0x34, - 0x21, 0xf5, 0x83, 0xe5, 0x14, 0xf0, 0x90, 0x00, 0x02, 0x74, 0x01, - 0xf0, 0x22, 0xbe, 0x03, 0x0a, 0x90, 0x00, 0x02, 0x74, 0x01, 0xf0, - 0xe4, 0xfe, 0x80, 0xc2, 0x0e, 0x80, 0xbf, 0x22, 0x8e, 0x13, 0x8f, - 0x14, 0x12, 0x1c, 0xbf, 0xc3, 0xef, 0x95, 0x14, 0xff, 0xee, 0x95, - 0x13, 0xcd, 0xef, 0xcd, 0xfc, 0xd3, 0xed, 0x94, 0x00, 0xec, 0x64, - 0x80, 0x94, 0x80, 0x40, 0x05, 0xce, 0xec, 0xce, 0x80, 0x04, 0x7e, - 0x00, 0x7f, 0x01, 0xcc, 0xee, 0xcc, 0xec, 0x90, 0x00, 0x05, 0xf0, - 0x90, 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, - 0x90, 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x30, 0x07, 0x3c, - 0xe5, 0x2f, 0x70, 0x38, 0xc2, 0x07, 0x90, 0x22, 0x2e, 0xe0, 0xfe, - 0xa3, 0xe0, 0x8e, 0x11, 0xf5, 0x12, 0x90, 0x22, 0x4e, 0xe0, 0xfe, - 0xa3, 0xe0, 0xff, 0x90, 0x22, 0x2e, 0xee, 0xf0, 0xa3, 0xef, 0xf0, - 0x90, 0x22, 0x4e, 0xe5, 0x11, 0xf0, 0xa3, 0xe5, 0x12, 0xf0, 0x8e, - 0x33, 0x8f, 0x34, 0x30, 0x08, 0x05, 0x12, 0x18, 0xb6, 0xc2, 0x08, - 0xc2, 0x09, 0x12, 0x11, 0x9b, 0x22, 0xe4, 0xff, 0x90, 0x30, 0x8c, - 0xe4, 0xf0, 0xef, 0x90, 0x1b, 0xec, 0x93, 0x44, 0x80, 0x90, 0x30, - 0x8d, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x90, 0x30, - 0x8c, 0xe0, 0xfe, 0x74, 0x36, 0x2f, 0xf8, 0xc6, 0xee, 0xc6, 0xa3, - 0xe0, 0xfe, 0xef, 0x90, 0x1b, 0xec, 0x93, 0x44, 0x80, 0x6e, 0x60, - 0x01, 0x1f, 0x0f, 0xef, 0xc3, 0x94, 0x09, 0x40, 0xc8, 0x22, 0x7f, - 0x80, 0x7e, 0x29, 0xe4, 0xfd, 0xfc, 0x8f, 0x82, 0x8e, 0x83, 0xe0, - 0xfb, 0x74, 0x45, 0x2d, 0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x04, 0x2f, - 0xf5, 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfb, 0x74, 0x41, 0x2d, - 0xf8, 0xc6, 0xeb, 0xc6, 0x74, 0x08, 0x2f, 0xff, 0xe4, 0x3e, 0xfe, - 0x0d, 0xbd, 0x00, 0x01, 0x0c, 0xed, 0x64, 0x04, 0x4c, 0x70, 0xcf, - 0x22, 0x90, 0x21, 0x00, 0xe0, 0xc4, 0x33, 0x54, 0xe0, 0x24, 0x10, - 0xf5, 0x82, 0xe4, 0x34, 0x21, 0xab, 0x82, 0xfa, 0x12, 0x1c, 0x35, - 0x8b, 0x82, 0x8a, 0x83, 0xee, 0x8f, 0xf0, 0x12, 0x0f, 0xab, 0x7e, - 0x22, 0x7f, 0x30, 0xcd, 0xeb, 0xcd, 0xcc, 0xea, 0xcc, 0x12, 0x16, - 0x33, 0xe4, 0x90, 0x21, 0x03, 0xf0, 0xaf, 0x2d, 0x12, 0x1c, 0xe0, - 0x22, 0xe4, 0xff, 0xe5, 0x30, 0x24, 0xfe, 0x70, 0x2c, 0xe4, 0xfe, - 0xee, 0xc3, 0x95, 0x2c, 0x50, 0x12, 0x74, 0x01, 0xc8, 0xee, 0xc8, - 0x08, 0x80, 0x02, 0xc3, 0x33, 0xd8, 0xfc, 0xcf, 0x4f, 0xcf, 0x0e, - 0x80, 0xe8, 0x90, 0x30, 0x34, 0xe0, 0x54, 0xe0, 0xfe, 0xe5, 0x27, - 0x54, 0x1f, 0x6f, 0xf4, 0xce, 0x4e, 0xce, 0xee, 0xf0, 0x22, 0x90, - 0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54, - 0xfe, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x20, 0xe3, 0xf9, 0x90, 0x01, - 0x11, 0xe0, 0x54, 0x22, 0xff, 0xbf, 0x22, 0x03, 0xd3, 0x80, 0x01, - 0xc3, 0x50, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, - 0x01, 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0xef, 0x24, 0x1e, 0xf5, - 0x82, 0xe4, 0x3e, 0xf5, 0x83, 0xe0, 0xfc, 0xa3, 0xe0, 0xfb, 0xca, - 0xec, 0xca, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3c, 0xf5, 0x83, 0xe0, - 0xfc, 0xa3, 0xe0, 0xfd, 0xef, 0x24, 0x1e, 0xf5, 0x82, 0xe4, 0x3e, - 0xf5, 0x83, 0xec, 0xf0, 0xa3, 0xed, 0xf0, 0xce, 0xea, 0xce, 0xcf, - 0xeb, 0xcf, 0x22, 0xc0, 0xe0, 0xc0, 0xd0, 0xc2, 0xaf, 0xc2, 0x8e, - 0xc2, 0x8f, 0xd3, 0xe5, 0x40, 0x94, 0x00, 0xe5, 0x3f, 0x94, 0x00, - 0x40, 0x0d, 0xe5, 0x40, 0x15, 0x40, 0x70, 0x02, 0x15, 0x3f, 0x12, - 0x1c, 0xe9, 0xd2, 0x8e, 0xd2, 0xaf, 0xd0, 0xd0, 0xd0, 0xe0, 0x32, - 0x12, 0x1b, 0x6e, 0x50, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0x7c, 0x1d, - 0x7d, 0x00, 0x75, 0x1b, 0x12, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0x90, - 0x00, 0x04, 0x74, 0x02, 0xf0, 0x90, 0x00, 0x0a, 0xf0, 0xd2, 0x09, - 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, 0x22, 0x8e, 0x13, 0x8f, 0x14, - 0x8d, 0x15, 0xeb, 0x60, 0x09, 0x14, 0x70, 0x1b, 0xaf, 0x15, 0x12, - 0x1a, 0xad, 0x22, 0x7e, 0x30, 0x7f, 0xe0, 0xac, 0x13, 0xad, 0x14, - 0x75, 0x1b, 0x11, 0x7b, 0x06, 0x12, 0x15, 0xd0, 0xaf, 0x15, 0x12, - 0x1a, 0xad, 0x22, 0x12, 0x18, 0x7d, 0x90, 0x21, 0x01, 0xe0, 0xf5, - 0x28, 0x74, 0x41, 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x32, 0x74, 0x45, - 0x25, 0x28, 0xf8, 0xe6, 0xf5, 0x22, 0x90, 0x21, 0x00, 0xe0, 0x60, - 0x03, 0xd2, 0x0d, 0x22, 0xc2, 0x0d, 0x22, 0xcd, 0xef, 0xcd, 0x90, - 0x01, 0x02, 0xe0, 0x30, 0xe7, 0x02, 0xc3, 0x22, 0x7e, 0x2a, 0x7f, - 0x00, 0x12, 0x0a, 0x4f, 0x90, 0x01, 0x04, 0xe0, 0x44, 0x80, 0xf0, - 0x90, 0x01, 0x02, 0xe0, 0x44, 0x80, 0xf0, 0xd3, 0x22, 0x90, 0x34, - 0x30, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0x74, 0x1f, 0xf0, 0xa3, 0xe4, - 0xf0, 0x90, 0x01, 0x10, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, 0xf6, - 0x90, 0x01, 0x12, 0xe0, 0x20, 0xe1, 0x03, 0x00, 0x80, 0xf6, 0x22, - 0xe4, 0xff, 0x74, 0x36, 0x2f, 0xf8, 0xe6, 0x90, 0x30, 0x8c, 0xf0, - 0xef, 0x90, 0x1b, 0xec, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74, - 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, 0xe4, - 0xff, 0xef, 0x90, 0x1b, 0xf6, 0x93, 0x90, 0x30, 0x8c, 0xf0, 0xef, - 0x90, 0x1b, 0xec, 0x93, 0x90, 0x30, 0x8d, 0xf0, 0xa3, 0x74, 0x01, - 0xf0, 0xa3, 0xe4, 0xf0, 0x0f, 0xbf, 0x09, 0xe3, 0x22, 0xe4, 0x90, - 0x00, 0x05, 0xf0, 0xef, 0x60, 0x02, 0x80, 0x02, 0x7f, 0x01, 0x90, - 0x00, 0x06, 0xef, 0xf0, 0x90, 0x00, 0x04, 0x74, 0x51, 0xf0, 0x90, - 0x00, 0x0b, 0xe0, 0x44, 0x02, 0xf0, 0x22, 0x90, 0x30, 0xf0, 0xe0, - 0xf5, 0x2a, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, - 0xf2, 0xe0, 0x60, 0x08, 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, - 0x22, 0xc3, 0x22, 0x90, 0x30, 0xf0, 0xe0, 0xf5, 0x2a, 0x90, 0x00, - 0x0a, 0xe0, 0x30, 0xe4, 0x0e, 0x90, 0x30, 0xf2, 0xe0, 0x70, 0x08, - 0x90, 0x00, 0x0a, 0x74, 0x10, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, - 0x34, 0xce, 0xe0, 0x44, 0x02, 0xf0, 0x90, 0x34, 0xcd, 0xe0, 0x54, - 0xfe, 0xf0, 0x90, 0x01, 0x00, 0xe0, 0x54, 0xf7, 0xf0, 0x90, 0x01, - 0x01, 0xe0, 0x54, 0xbf, 0xf0, 0x22, 0x90, 0x00, 0x01, 0x74, 0x0e, - 0xf0, 0x90, 0x34, 0x98, 0xe0, 0x54, 0xfb, 0xf0, 0x90, 0x34, 0x58, - 0x74, 0x01, 0xf0, 0x90, 0x30, 0x30, 0x74, 0x04, 0xf0, 0x22, 0x02, - 0x04, 0x0b, 0x16, 0x0c, 0x12, 0x18, 0x24, 0x30, 0x48, 0x60, 0x6c, - 0x90, 0xc8, 0x00, 0x01, 0x02, 0x03, 0x0b, 0x0f, 0x0a, 0x0e, 0x09, - 0x0d, 0x08, 0x0c, 0xef, 0xc4, 0x33, 0x33, 0x54, 0xc0, 0xff, 0x90, - 0x01, 0x00, 0xe0, 0x54, 0x3f, 0x4f, 0xf0, 0x90, 0x01, 0x02, 0xe0, - 0x44, 0x80, 0xf0, 0x22, 0x90, 0x01, 0x03, 0xe0, 0x30, 0xe7, 0x0c, - 0x74, 0x80, 0xf0, 0x90, 0x01, 0x04, 0xe0, 0x54, 0x7f, 0xf0, 0xd3, - 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe1, 0x0c, 0x74, - 0x02, 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfd, 0xf0, 0xd3, 0x22, - 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe2, 0x0c, 0x74, 0x04, - 0xf0, 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xfb, 0xf0, 0xd3, 0x22, 0xc3, - 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe6, 0x0c, 0x74, 0x40, 0xf0, - 0x90, 0x00, 0x0b, 0xe0, 0x54, 0xbf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, - 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe7, 0x0c, 0x74, 0x80, 0xf0, 0x90, - 0x00, 0x0b, 0xe0, 0x54, 0x7f, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, - 0x01, 0x05, 0xe0, 0x30, 0xe5, 0x0c, 0x74, 0x20, 0xf0, 0x90, 0x01, - 0x06, 0xe0, 0x54, 0xdf, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x52, 0x53, - 0x54, 0x12, 0x15, 0x16, 0x10, 0x11, 0x40, 0x00, 0x20, 0x00, 0x40, - 0xff, 0x3f, 0x3f, 0xbd, 0x28, 0x21, 0x00, 0xe5, 0x34, 0x24, 0x11, - 0xf5, 0x82, 0xe4, 0x35, 0x33, 0xf5, 0x83, 0xe0, 0x30, 0xe6, 0x02, - 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, - 0x74, 0xb0, 0xf0, 0xa3, 0x74, 0x01, 0xf0, 0xa3, 0xe4, 0xf0, 0x22, - 0x0d, 0xc5, 0x14, 0x78, 0x16, 0x90, 0x13, 0x6a, 0x00, 0x09, 0x19, - 0xb2, 0x12, 0x42, 0x1c, 0x64, 0x90, 0x30, 0x64, 0xe0, 0xfd, 0xa3, - 0xe0, 0xfe, 0xed, 0x25, 0xe0, 0xff, 0xee, 0x33, 0xfe, 0x22, 0x90, - 0x30, 0x40, 0x74, 0x32, 0xf0, 0xa3, 0x74, 0xb0, 0xf0, 0xa3, 0xe4, - 0xf0, 0xa3, 0xf0, 0x22, 0x90, 0x01, 0x00, 0xe0, 0x44, 0x08, 0xf0, - 0x90, 0x01, 0x01, 0xe0, 0x44, 0x40, 0xf0, 0x22, 0x12, 0x1b, 0x6e, - 0x50, 0x08, 0xd2, 0x09, 0x12, 0x11, 0x9b, 0xe4, 0xf5, 0x2f, 0x22, - 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe0, 0x05, 0x74, 0x01, 0xf0, 0xd3, - 0x22, 0xc3, 0x22, 0x90, 0x00, 0x0a, 0xe0, 0x30, 0xe5, 0x05, 0x74, - 0x20, 0xf0, 0xd3, 0x22, 0xc3, 0x22, 0x90, 0x34, 0x30, 0x74, 0x1f, - 0xf0, 0xa3, 0xe4, 0xf0, 0xa3, 0xf0, 0xa3, 0xf0, 0x22, 0xc2, 0xaf, - 0xc2, 0x8c, 0xc2, 0x8d, 0x12, 0x00, 0x0e, 0xd2, 0xaf, 0x22, 0xc2, - 0x8e, 0x8e, 0x3f, 0x8f, 0x40, 0x12, 0x1c, 0xe9, 0xd2, 0x8e, 0x22, - 0x90, 0x30, 0x3c, 0xef, 0xf0, 0xee, 0x44, 0x80, 0xa3, 0xf0, 0x22, - 0x90, 0x30, 0x78, 0xe0, 0xfd, 0xa3, 0xe0, 0xfe, 0xed, 0xff, 0x22, - 0xe5, 0x4a, 0x45, 0x49, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, - 0xe5, 0x4c, 0x45, 0x4b, 0x70, 0x03, 0xd3, 0x80, 0x01, 0xc3, 0x22, - 0xc2, 0x0b, 0xe4, 0xf5, 0x14, 0x12, 0x17, 0x78, 0x22, 0xc2, 0x8f, - 0x75, 0x8d, 0xf5, 0x75, 0x8b, 0x41, 0x22, 0x8e, 0x49, 0x8f, 0x4a, - 0xd2, 0x8c, 0x22, 0x8e, 0x4b, 0x8f, 0x4c, 0xd2, 0x8c, 0x22, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0xc2, 0x0d, 0xe4, 0xf5, 0x2e, 0x22, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, - 0x00, 0x00, 0x00, 0x00, 0x00, 0x08, 0x43, 0xcf -}; diff --git a/sys/dev/ral/rt2661var.h b/sys/dev/ral/rt2661var.h index 9f12a15..0c15840 100644 --- a/sys/dev/ral/rt2661var.h +++ b/sys/dev/ral/rt2661var.h @@ -51,7 +51,8 @@ struct rt2661_tx_data { bus_dmamap_t map; struct mbuf *m; struct ieee80211_node *ni; - struct ral_rssdesc id; + uint8_t rix; + int8_t rssi; }; struct rt2661_tx_ring { @@ -87,14 +88,21 @@ struct rt2661_rx_ring { struct rt2661_node { struct ieee80211_node ni; - struct ral_rssadapt rssadapt; + struct ieee80211_amrr_node amrr; }; +#define RT2661_NODE(ni) ((struct rt2661_node *)(ni)) + +struct rt2661_vap { + struct ieee80211vap ral_vap; + struct ieee80211_amrr amrr; + + int (*ral_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define RT2661_VAP(vap) ((struct rt2661_vap *)(vap)) struct rt2661_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); device_t sc_dev; bus_space_tag_t sc_st; bus_space_handle_t sc_sh; @@ -102,15 +110,21 @@ struct rt2661_softc { struct mtx sc_mtx; struct callout watchdog_ch; - struct callout rssadapt_ch; int sc_tx_timer; int sc_invalid; + int sc_debug; + + const struct ieee80211_rate_table *sc_rates; /* * The same in both up to here * ------------------------------------------------ */ + int sc_flags; +#define RAL_FW_LOADED 0x1 +#define RAL_INPUT_RUNNING 0x2 + int sc_id; struct ieee80211_channel *sc_curchan; uint8_t rf_rev; @@ -148,23 +162,10 @@ struct rt2661_softc { int dwelltime; - struct bpf_if *sc_drvbpf; - - union { - struct rt2661_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct rt2661_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - - union { - struct rt2661_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct rt2661_tx_radiotap_header sc_txtap; int sc_txtap_len; -#define RAL_INPUT_RUNNING 1 - int sc_flags; }; int rt2661_attach(device_t, int); @@ -174,5 +175,6 @@ void rt2661_suspend(void *); void rt2661_resume(void *); void rt2661_intr(void *); -#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) -#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) +#define RAL_LOCK(sc) mtx_lock(&(sc)->sc_mtx) +#define RAL_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) +#define RAL_UNLOCK(sc) mtx_unlock(&(sc)->sc_mtx) diff --git a/sys/dev/usb/if_rum.c b/sys/dev/usb/if_rum.c index 7657d10..ec46c84 100644 --- a/sys/dev/usb/if_rum.c +++ b/sys/dev/usb/if_rum.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -128,23 +129,23 @@ MODULE_DEPEND(rum, wlan, 1, 1, 1); MODULE_DEPEND(rum, wlan_amrr, 1, 1, 1); MODULE_DEPEND(rum, usb, 1, 1, 1); +static struct ieee80211vap *rum_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void rum_vap_delete(struct ieee80211vap *); static int rum_alloc_tx_list(struct rum_softc *); static void rum_free_tx_list(struct rum_softc *); static int rum_alloc_rx_list(struct rum_softc *); static void rum_free_rx_list(struct rum_softc *); -static int rum_media_change(struct ifnet *); static void rum_task(void *); static void rum_scantask(void *); -static int rum_newstate(struct ieee80211com *, +static int rum_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void rum_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); static void rum_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static int rum_rxrate(struct rum_rx_desc *); -static int rum_ack_rate(struct ieee80211com *, int); -static uint16_t rum_txtime(int, int, uint32_t); -static uint8_t rum_plcp_signal(int); static void rum_setup_tx_desc(struct rum_softc *, struct rum_tx_desc *, uint32_t, uint16_t, int, int); @@ -185,13 +186,17 @@ static void rum_update_promisc(struct rum_softc *); static const char *rum_get_rf(int); static void rum_read_eeprom(struct rum_softc *); static int rum_bbp_init(struct rum_softc *); +static void rum_init_locked(struct rum_softc *); static void rum_init(void *); static void rum_stop(void *); static int rum_load_microcode(struct rum_softc *, const u_char *, size_t); -static int rum_prepare_beacon(struct rum_softc *); +static int rum_prepare_beacon(struct rum_softc *, + struct ieee80211vap *); static int rum_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); +static struct ieee80211_node *rum_node_alloc(struct ieee80211_node_table *); +static void rum_newassoc(struct ieee80211_node *, int); static void rum_scan_start(struct ieee80211com *); static void rum_scan_end(struct ieee80211com *); static void rum_set_channel(struct ieee80211com *); @@ -378,21 +383,21 @@ rum_attach(device_t self) { struct rum_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; struct ifnet *ifp; const uint8_t *ucode = NULL; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status error; - int i, ntries, size, bands; + int i, ntries, size; + uint8_t bands; uint32_t tmp; sc->sc_udev = uaa->device; sc->sc_dev = self; if (usbd_set_config_no(sc->sc_udev, RT2573_CONFIG_NO, 0) != 0) { - printf("%s: could not set configuration no\n", - device_get_nameunit(sc->sc_dev)); + device_printf(self, "could not set configuration no\n"); return ENXIO; } @@ -400,8 +405,7 @@ rum_attach(device_t self) error = usbd_device2interface_handle(sc->sc_udev, RT2573_IFACE_INDEX, &sc->sc_iface); if (error != 0) { - printf("%s: could not get interface handle\n", - device_get_nameunit(sc->sc_dev)); + device_printf(self, "could not get interface handle\n"); return ENXIO; } @@ -414,8 +418,8 @@ rum_attach(device_t self) for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { - printf("%s: no endpoint descriptor for iface %d\n", - device_get_nameunit(sc->sc_dev), i); + device_printf(self, + "no endpoint descriptor for iface %d\n", i); return ENXIO; } @@ -427,18 +431,23 @@ rum_attach(device_t self) sc->sc_tx_no = ed->bEndpointAddress; } if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) { - printf("%s: missing endpoint\n", - device_get_nameunit(sc->sc_dev)); + device_printf(self, "missing endpoint\n"); return ENXIO; } + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(self, "can not if_alloc()\n"); + return ENXIO; + } + ic = ifp->if_l2com; + mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); usb_init_task(&sc->sc_task, rum_task, sc); usb_init_task(&sc->sc_scantask, rum_scantask, sc); callout_init(&sc->watchdog_ch, 0); - callout_init(&sc->amrr_ch, 0); /* retrieve RT2573 rev. no */ for (ntries = 0; ntries < 1000; ntries++) { @@ -447,32 +456,22 @@ rum_attach(device_t self) DELAY(1000); } if (ntries == 1000) { - printf("%s: timeout waiting for chip to settle\n", - device_get_nameunit(sc->sc_dev)); - return ENXIO; + device_printf(self, "timeout waiting for chip to settle\n"); + goto bad; } /* retrieve MAC address and various other things from EEPROM */ rum_read_eeprom(sc); - printf("%s: MAC/BBP RT2573 (rev 0x%05x), RF %s\n", - device_get_nameunit(sc->sc_dev), tmp, rum_get_rf(sc->rf_rev)); + device_printf(self, "MAC/BBP RT2573 (rev 0x%05x), RF %s\n", + tmp, rum_get_rf(sc->rf_rev)); ucode = rt2573_ucode; size = sizeof rt2573_ucode; error = rum_load_microcode(sc, ucode, size); if (error != 0) { - device_printf(sc->sc_dev, "could not load 8051 microcode\n"); - mtx_destroy(&sc->sc_mtx); - return ENXIO; - } - - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - printf("%s: can not if_alloc()\n", - device_get_nameunit(sc->sc_dev)); - mtx_destroy(&sc->sc_mtx); - return ENXIO; + device_printf(self, "could not load 8051 microcode\n"); + goto bad; } ifp->if_softc = sc; @@ -488,82 +487,47 @@ rum_attach(device_t self) ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = - IEEE80211_C_IBSS | /* IBSS mode supported */ - IEEE80211_C_MONITOR | /* monitor mode supported */ - IEEE80211_C_HOSTAP | /* HostAp mode supported */ - IEEE80211_C_TXPMGT | /* tx power management */ - IEEE80211_C_SHPREAMBLE | /* short preamble supported */ - IEEE80211_C_SHSLOT | /* short slot time supported */ - IEEE80211_C_BGSCAN | /* bg scanning supported */ - IEEE80211_C_WPA; /* 802.11i */ + IEEE80211_C_IBSS /* IBSS mode supported */ + | IEEE80211_C_MONITOR /* monitor mode supported */ + | IEEE80211_C_HOSTAP /* HostAp mode supported */ + | IEEE80211_C_TXPMGT /* tx power management */ + | IEEE80211_C_SHPREAMBLE /* short preamble supported */ + | IEEE80211_C_SHSLOT /* short slot time supported */ + | IEEE80211_C_BGSCAN /* bg scanning supported */ + | IEEE80211_C_WPA /* 802.11i */ + ; bands = 0; setbit(&bands, IEEE80211_MODE_11B); setbit(&bands, IEEE80211_MODE_11G); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); - - if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) { - struct ieee80211_channel *c; - - /* set supported .11a channels */ - for (i = 34; i <= 46; i += 4) { - c = &ic->ic_channels[ic->ic_nchans++]; - c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - c->ic_flags = IEEE80211_CHAN_A; - c->ic_ieee = i; - } - for (i = 36; i <= 64; i += 4) { - c = &ic->ic_channels[ic->ic_nchans++]; - c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - c->ic_flags = IEEE80211_CHAN_A; - c->ic_ieee = i; - } - for (i = 100; i <= 140; i += 4) { - c = &ic->ic_channels[ic->ic_nchans++]; - c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - c->ic_flags = IEEE80211_CHAN_A; - c->ic_ieee = i; - } - for (i = 149; i <= 165; i += 4) { - c = &ic->ic_channels[ic->ic_nchans++]; - c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_5GHZ); - c->ic_flags = IEEE80211_CHAN_A; - c->ic_ieee = i; - } - } + if (sc->rf_rev == RT2573_RF_5225 || sc->rf_rev == RT2573_RF_5226) + setbit(&bands, IEEE80211_MODE_11A); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); + ic->ic_newassoc = rum_newassoc; + ic->ic_raw_xmit = rum_raw_xmit; + ic->ic_node_alloc = rum_node_alloc; ic->ic_scan_start = rum_scan_start; ic->ic_scan_end = rum_scan_end; ic->ic_set_channel = rum_set_channel; - /* enable s/w bmiss handling in sta mode */ - ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; + ic->ic_vap_create = rum_vap_create; + ic->ic_vap_delete = rum_vap_delete; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = rum_newstate; - ic->ic_raw_xmit = rum_raw_xmit; - ieee80211_media_init(ic, rum_media_change, ieee80211_media_status); - - ieee80211_amrr_init(&sc->amrr, ic, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + IEEE80211_RADIOTAP_HDRLEN, - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(RT2573_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof sc->sc_txtap; sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(RT2573_TX_RADIOTAP_PRESENT); @@ -571,20 +535,26 @@ rum_attach(device_t self) ieee80211_announce(ic); return 0; +bad: + mtx_destroy(&sc->sc_mtx); + if_free(ifp); + return ENXIO; } static int rum_detach(device_t self) { struct rum_softc *sc = device_get_softc(self); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; rum_stop(sc); + bpfdetach(ifp); + ieee80211_ifdetach(ic); + usb_rem_task(sc->sc_udev, &sc->sc_task); usb_rem_task(sc->sc_udev, &sc->sc_scantask); callout_stop(&sc->watchdog_ch); - callout_stop(&sc->amrr_ch); if (sc->amrr_xfer != NULL) { usbd_free_xfer(sc->amrr_xfer); @@ -603,22 +573,66 @@ rum_detach(device_t self) rum_free_rx_list(sc); rum_free_tx_list(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; } +static struct ieee80211vap * +rum_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct rum_vap *rvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + rvp = (struct rum_vap *) malloc(sizeof(struct rum_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (rvp == NULL) + return NULL; + vap = &rvp->vap; + /* enable s/w bmiss handling for sta mode */ + ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + + /* override state transition machine */ + rvp->newstate = vap->iv_newstate; + vap->iv_newstate = rum_newstate; + + callout_init(&rvp->amrr_ch, 0); + ieee80211_amrr_init(&rvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 1000 /* 1 sec */); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +rum_vap_delete(struct ieee80211vap *vap) +{ + struct rum_vap *rvp = RUM_VAP(vap); + + callout_stop(&rvp->amrr_ch); + ieee80211_amrr_cleanup(&rvp->amrr); + ieee80211_vap_detach(vap); + free(rvp, M_80211_VAP); +} + static int rum_alloc_tx_list(struct rum_softc *sc) { struct rum_tx_data *data; int i, error; - sc->tx_queued = 0; + sc->tx_queued = sc->tx_cur = 0; for (i = 0; i < RUM_TX_LIST_COUNT; i++) { data = &sc->tx_data[i]; @@ -627,16 +641,16 @@ rum_alloc_tx_list(struct rum_softc *sc) data->xfer = usbd_alloc_xfer(sc->sc_udev); if (data->xfer == NULL) { - printf("%s: could not allocate tx xfer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate tx xfer\n"); error = ENOMEM; goto fail; } data->buf = usbd_alloc_buffer(data->xfer, RT2573_TX_DESC_SIZE + MCLBYTES); if (data->buf == NULL) { - printf("%s: could not allocate tx buffer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate tx buffer\n"); error = ENOMEM; goto fail; } @@ -684,22 +698,22 @@ rum_alloc_rx_list(struct rum_softc *sc) data->xfer = usbd_alloc_xfer(sc->sc_udev); if (data->xfer == NULL) { - printf("%s: could not allocate rx xfer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate rx xfer\n"); error = ENOMEM; goto fail; } if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { - printf("%s: could not allocate rx buffer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate rx buffer\n"); error = ENOMEM; goto fail; } data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if (data->m == NULL) { - printf("%s: could not allocate rx mbuf\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate rx mbuf\n"); error = ENOMEM; goto fail; } @@ -733,39 +747,20 @@ rum_free_rx_list(struct rum_softc *sc) } } -static int -rum_media_change(struct ifnet *ifp) -{ - struct rum_softc *sc = ifp->if_softc; - int error; - - RUM_LOCK(sc); - - error = ieee80211_media_change(ifp); - if (error != ENETRESET) { - RUM_UNLOCK(sc); - return error; - } - - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) - rum_init(sc); - - RUM_UNLOCK(sc); - - return 0; -} - static void rum_task(void *arg) { struct rum_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct rum_vap *rvp = RUM_VAP(vap); + const struct ieee80211_txparam *tp; enum ieee80211_state ostate; struct ieee80211_node *ni; uint32_t tmp; - ostate = ic->ic_state; + ostate = vap->iv_state; RUM_LOCK(sc); @@ -779,9 +774,9 @@ rum_task(void *arg) break; case IEEE80211_S_RUN: - ni = ic->ic_bss; + ni = vap->iv_bss; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { + if (vap->iv_opmode != IEEE80211_M_MONITOR) { rum_update_slot(ic->ic_ifp); rum_enable_mrr(sc); rum_set_txpreamble(sc); @@ -789,16 +784,16 @@ rum_task(void *arg) rum_set_bssid(sc, ni->ni_bssid); } - if (ic->ic_opmode == IEEE80211_M_HOSTAP || - ic->ic_opmode == IEEE80211_M_IBSS) - rum_prepare_beacon(sc); + if (vap->iv_opmode == IEEE80211_M_HOSTAP || + vap->iv_opmode == IEEE80211_M_IBSS) + rum_prepare_beacon(sc, vap); - if (ic->ic_opmode != IEEE80211_M_MONITOR) + if (vap->iv_opmode != IEEE80211_M_MONITOR) rum_enable_tsf_sync(sc); - /* enable automatic rate adaptation in STA mode */ - if (ic->ic_opmode == IEEE80211_M_STA && - ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) + /* enable automatic rate adaptation */ + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; + if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) rum_amrr_start(sc, ni); break; default: @@ -807,40 +802,42 @@ rum_task(void *arg) RUM_UNLOCK(sc); - sc->sc_newstate(ic, sc->sc_state, sc->sc_arg); + IEEE80211_LOCK(ic); + rvp->newstate(vap, sc->sc_state, sc->sc_arg); + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + IEEE80211_UNLOCK(ic); } static int -rum_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +rum_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct rum_vap *rvp = RUM_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct rum_softc *sc = ic->ic_ifp->if_softc; - callout_stop(&sc->amrr_ch); + callout_stop(&rvp->amrr_ch); /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; usb_rem_task(sc->sc_udev, &sc->sc_task); - if (nstate == IEEE80211_S_INIT) - sc->sc_newstate(ic, nstate, arg); - else + if (nstate == IEEE80211_S_INIT) { + rvp->newstate(vap, nstate, arg); + return 0; + } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return 0; + return EINPROGRESS; + } } -/* quickly determine if a given rate is CCK or OFDM */ -#define RUM_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) - -#define RUM_ACK_SIZE 14 /* 10 + 4(FCS) */ -#define RUM_CTS_SIZE 14 /* 10 + 4(FCS) */ - static void rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct rum_tx_data *data = priv; struct rum_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; if (data->m != NULL && data->m->m_flags & M_TXCB) ieee80211_process_callback(data->ni, data->m, 0/*XXX*/); @@ -849,8 +846,8 @@ rum_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; - printf("%s: could not transmit buffer: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(status)); + device_printf(sc->sc_dev, "could not transmit buffer: %s\n", + usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->sc_tx_pipeh); @@ -879,10 +876,9 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct rum_rx_data *data = priv; struct rum_softc *sc = data->sc; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_rx_desc *desc; - struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *mnew, *m; int len, rssi; @@ -934,31 +930,29 @@ rum_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) rssi = rum_get_rssi(sc, desc->rssi); - wh = mtod(m, struct ieee80211_frame *); - ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); - - /* Error happened during RSSI conversion. */ - if (rssi < 0) - rssi = ni->ni_rssi; - - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rum_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; - tap->wr_rate = rum_rxrate(desc); + tap->wr_rate = ieee80211_plcp2rate(desc->rate, + le32toh(desc->flags) & RT2573_RX_OFDM); tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wr_antenna = sc->rx_ant; tap->wr_antsignal = rssi; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, rssi, RT2573_NOISE_FLOOR, 0); - - /* node is no longer needed */ - ieee80211_free_node(ni); + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + /* Error happened during RSSI conversion. */ + if (rssi < 0) + rssi = -30; /* XXX ignored by net80211 */ + (void) ieee80211_input(ni, m, rssi, RT2573_NOISE_FLOOR, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, RT2573_NOISE_FLOOR, 0); DPRINTFN(15, ("rx done\n")); @@ -968,125 +962,12 @@ skip: /* setup a new transfer */ usbd_transfer(xfer); } -/* - * This function is only used by the Rx radiotap code. - */ -static int -rum_rxrate(struct rum_rx_desc *desc) -{ - if (le32toh(desc->flags) & RT2573_RX_OFDM) { - /* reverse function of rum_plcp_signal */ - switch (desc->rate) { - case 0xb: return 12; - case 0xf: return 18; - case 0xa: return 24; - case 0xe: return 36; - case 0x9: return 48; - case 0xd: return 72; - case 0x8: return 96; - case 0xc: return 108; - } - } else { - if (desc->rate == 10) - return 2; - if (desc->rate == 20) - return 4; - if (desc->rate == 55) - return 11; - if (desc->rate == 110) - return 22; - } - return 2; /* should not get there */ -} - -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - */ -static int -rum_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - -/* - * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. - * The function automatically determines the operating mode depending on the - * given rate. `flags' indicates whether short preamble is in use or not. - */ -static uint16_t -rum_txtime(int len, int rate, uint32_t flags) -{ - uint16_t txtime; - - if (RUM_RATE_IS_OFDM(rate)) { - /* IEEE Std 802.11a-1999, pp. 37 */ - txtime = (8 + 4 * len + 3 + rate - 1) / rate; - txtime = 16 + 4 + 4 * txtime + 6; - } else { - /* IEEE Std 802.11b-1999, pp. 28 */ - txtime = (16 * len + rate - 1) / rate; - if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) - txtime += 72 + 24; - else - txtime += 144 + 48; - } - return txtime; -} - -static uint8_t -rum_plcp_signal(int rate) -{ - switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* unsupported rates (should not get there) */ - default: return 0xff; - } -} - static void rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, uint32_t flags, uint16_t xflags, int len, int rate) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int remainder; @@ -1100,11 +981,11 @@ rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, RT2573_LOGCWMIN(4) | RT2573_LOGCWMAX(10)); /* setup PLCP fields */ - desc->plcp_signal = rum_plcp_signal(rate); + desc->plcp_signal = ieee80211_rate2plcp(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; - if (RUM_RATE_IS_OFDM(rate)) { + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { desc->flags |= htole32(RT2573_TX_OFDM); plcp_length = len & 0xfff; @@ -1128,43 +1009,108 @@ rum_setup_tx_desc(struct rum_softc *sc, struct rum_tx_desc *desc, #define RUM_TX_TIMEOUT 5000 static int +rum_sendprot(struct rum_softc *sc, + const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) +{ + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_frame *wh; + struct rum_tx_desc *desc; + struct rum_tx_data *data; + struct mbuf *mprot; + int protrate, ackrate, pktlen, flags, isshort; + uint16_t dur; + usbd_status error; + + KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, + ("protection %d", prot)); + + wh = mtod(m, const struct ieee80211_frame *); + pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + + protrate = ieee80211_ctl_rate(sc->sc_rates, rate); + ackrate = ieee80211_ack_rate(sc->sc_rates, rate); + + isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); + + ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags = RT2573_TX_MORE_FRAG; + if (prot == IEEE80211_PROT_RTSCTS) { + /* NB: CTS is the same size as an ACK */ + dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags |= RT2573_TX_NEED_ACK; + mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); + } else { + mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); + } + if (mprot == NULL) { + /* XXX stat + msg */ + return ENOBUFS; + } + data = &sc->tx_data[sc->tx_cur]; + desc = (struct rum_tx_desc *)data->buf; + + data->m = mprot; + data->ni = ieee80211_ref_node(ni); + m_copydata(mprot, 0, mprot->m_pkthdr.len, + data->buf + RT2573_TX_DESC_SIZE); + rum_setup_tx_desc(sc, desc, flags, 0, mprot->m_pkthdr.len, protrate); + + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, + /* NB: no roundup necessary */ + RT2573_TX_DESC_SIZE + mprot->m_pkthdr.len, + USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); + + error = usbd_transfer(data->xfer); + if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { + data->m = NULL; + data->ni = NULL; + return error; + } + + sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; + + return 0; +} + +static int rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_tx_desc *desc; struct rum_tx_data *data; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; uint32_t flags = 0; uint16_t dur; usbd_status error; - int xferlen, rate; - - data = &sc->tx_data[0]; - desc = (struct rum_tx_desc *)data->buf; - - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; + int xferlen; + data = &sc->tx_data[sc->tx_cur]; data->m = m0; data->ni = ni; + desc = (struct rum_tx_desc *)data->buf; wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; } + wh = mtod(m0, struct ieee80211_frame *); } - wh = mtod(m0, struct ieee80211_frame *); + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RT2573_TX_NEED_ACK; - dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), - ic->ic_flags) + sc->sifs; + dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, + ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); /* tell hardware to add timestamp for probe responses */ @@ -1174,20 +1120,20 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) flags |= RT2573_TX_TIMESTAMP; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rum_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - tap->wt_rate = rate; + tap->wt_rate = tp->mgmtrate; tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); - rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); + rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, tp->mgmtrate); /* align end on a 4-bytes boundary */ xferlen = (RT2573_TX_DESC_SIZE + m0->m_pkthdr.len + 3) & ~3; @@ -1200,7 +1146,7 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) xferlen += 4; DPRINTFN(10, ("sending mgt frame len=%d rate=%d xfer len=%d\n", - m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, rate, xferlen)); + m0->m_pkthdr.len + (int)RT2573_TX_DESC_SIZE, tp->mgmtrate, xferlen)); usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RUM_TX_TIMEOUT, rum_txeof); @@ -1214,6 +1160,7 @@ rum_tx_mgt(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; return 0; } @@ -1222,14 +1169,17 @@ static int rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_tx_desc *desc; struct rum_tx_data *data; uint32_t flags; usbd_status error; int xferlen, rate; - data = &sc->tx_data[0]; + KASSERT(params != NULL, ("no raw xmit params")); + + data = &sc->tx_data[sc->tx_cur]; desc = (struct rum_tx_desc *)data->buf; rate = params->ibp_rate0 & IEEE80211_RATE_VAL; @@ -1238,8 +1188,22 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, m_freem(m0); return EINVAL; } + flags = 0; + if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) + flags |= RT2573_TX_NEED_ACK; + if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { + error = rum_sendprot(sc, m0, ni, + params->ibp_flags & IEEE80211_BPF_RTS ? + IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, + rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; + } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rum_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1248,16 +1212,12 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; - flags = 0; - if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) - flags |= RT2573_TX_NEED_ACK; - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); /* XXX need to setup descriptor ourself */ rum_setup_tx_desc(sc, desc, flags, 0, m0->m_pkthdr.len, rate); @@ -1284,6 +1244,7 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, return error; sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; return 0; } @@ -1291,10 +1252,13 @@ rum_tx_raw(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, static int rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_tx_desc *desc; struct rum_tx_data *data; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; uint32_t flags = 0; uint16_t dur; @@ -1303,15 +1267,18 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) - rate = ic->ic_fixed_rate; - else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - - rate &= IEEE80211_RATE_VAL; + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) + rate = tp->mcastrate; + else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) + rate = tp->ucastrate; + else { + (void) ieee80211_amrr_choose(ni, &RUM_NODE(ni)->amn); + rate = ni->ni_txrate; + } if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1321,7 +1288,24 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); } - data = &sc->tx_data[0]; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + int prot = IEEE80211_PROT_NONE; + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) + prot = IEEE80211_PROT_RTSCTS; + else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) + prot = ic->ic_protmode; + if (prot != IEEE80211_PROT_NONE) { + error = rum_sendprot(sc, m0, ni, prot, rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RT2573_TX_LONG_RETRY | RT2573_TX_IFS_SIFS; + } + } + + data = &sc->tx_data[sc->tx_cur]; desc = (struct rum_tx_desc *)data->buf; data->m = m0; @@ -1331,12 +1315,12 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) flags |= RT2573_TX_NEED_ACK; flags |= RT2573_TX_MORE_FRAG; - dur = rum_txtime(RUM_ACK_SIZE, rum_ack_rate(ic, rate), - ic->ic_flags) + sc->sifs; + dur = ieee80211_ack_duration(sc->sc_rates, rate, + ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct rum_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1345,7 +1329,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RT2573_TX_DESC_SIZE); @@ -1376,6 +1360,7 @@ rum_tx_data(struct rum_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RUM_TX_LIST_COUNT; return 0; } @@ -1384,77 +1369,30 @@ static void rum_start(struct ifnet *ifp) { struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; struct ieee80211_node *ni; - struct mbuf *m0; - struct ether_header *eh; + struct mbuf *m; for (;;) { - IF_POLL(&ic->ic_mgtq, m0); - if (m0 != NULL) { - if (sc->tx_queued >= RUM_TX_LIST_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IF_DEQUEUE(&ic->ic_mgtq, m0); - - ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (rum_tx_mgt(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - break; - } - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - if (sc->tx_queued >= RUM_TX_LIST_COUNT) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - if (m0->m_len < sizeof (struct ether_header) && - !(m0 = m_pullup(m0, sizeof (struct ether_header)))) - continue; - - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - BPF_MTAP(ifp, m0); - - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ieee80211_free_node(ni); - continue; - } - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (rum_tx_data(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + if (sc->tx_queued >= RUM_TX_LIST_COUNT-1) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + continue; + } + if (rum_tx_data(sc, m, ni) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; } - sc->sc_tx_timer = 5; - ic->ic_lastdata = ticks; callout_reset(&sc->watchdog_ch, hz, rum_watchdog, sc); } } @@ -1484,37 +1422,35 @@ static int rum_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; RUM_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - rum_update_promisc(sc); - else + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { rum_init(sc); + startall = 1; + } else + rum_update_promisc(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) rum_stop(sc); } break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - rum_init(sc); - error = 0; + error = ether_ioctl(ifp, cmd, data); } - RUM_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } @@ -1532,8 +1468,8 @@ rum_eeprom_read(struct rum_softc *sc, uint16_t addr, void *buf, int len) error = usbd_do_request(sc->sc_udev, &req, buf); if (error != 0) { - printf("%s: could not read EEPROM: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not read EEPROM: %s\n", + usbd_errstr(error)); } } @@ -1561,8 +1497,9 @@ rum_read_multi(struct rum_softc *sc, uint16_t reg, void *buf, int len) error = usbd_do_request(sc->sc_udev, &req, buf); if (error != 0) { - printf("%s: could not multi read MAC register: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, + "could not multi read MAC register: %s\n", + usbd_errstr(error)); } } @@ -1588,8 +1525,9 @@ rum_write_multi(struct rum_softc *sc, uint16_t reg, void *buf, size_t len) error = usbd_do_request(sc->sc_udev, &req, buf); if (error != 0) { - printf("%s: could not multi write MAC register: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, + "could not multi write MAC register: %s\n", + usbd_errstr(error)); } } @@ -1604,8 +1542,7 @@ rum_bbp_write(struct rum_softc *sc, uint8_t reg, uint8_t val) break; } if (ntries == 5) { - printf("%s: could not write to BBP\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not write to BBP\n"); return; } @@ -1624,8 +1561,7 @@ rum_bbp_read(struct rum_softc *sc, uint8_t reg) break; } if (ntries == 5) { - printf("%s: could not read BBP\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not read BBP\n"); return 0; } @@ -1639,7 +1575,7 @@ rum_bbp_read(struct rum_softc *sc, uint8_t reg) DELAY(1); } - printf("%s: could not read BBP\n", device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not read BBP\n"); return 0; } @@ -1654,8 +1590,7 @@ rum_rf_write(struct rum_softc *sc, uint8_t reg, uint32_t val) break; } if (ntries == 5) { - printf("%s: could not write to RF\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not write to RF\n"); return; } @@ -1697,13 +1632,14 @@ rum_select_antenna(struct rum_softc *sc) static void rum_enable_mrr(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR4); tmp &= ~RT2573_MRR_CCK_FALLBACK; - if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) + if (!IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) tmp |= RT2573_MRR_CCK_FALLBACK; tmp |= RT2573_MRR_ENABLED; @@ -1713,12 +1649,14 @@ rum_enable_mrr(struct rum_softc *sc) static void rum_set_txpreamble(struct rum_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR4); tmp &= ~RT2573_SHORT_PREAMBLE; - if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE) + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) tmp |= RT2573_SHORT_PREAMBLE; rum_write(sc, RT2573_TXRX_CSR4, tmp); @@ -1727,13 +1665,14 @@ rum_set_txpreamble(struct rum_softc *sc) static void rum_set_basicrates(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; /* update basic rate set */ if (ic->ic_curmode == IEEE80211_MODE_11B) { /* 11b basic rates: 1, 2Mbps */ rum_write(sc, RT2573_TXRX_CSR5, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { + } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bsschan)) { /* 11a basic rates: 6, 12, 24Mbps */ rum_write(sc, RT2573_TXRX_CSR5, 0x150); } else { @@ -1787,15 +1726,13 @@ rum_select_band(struct rum_softc *sc, struct ieee80211_channel *c) else tmp |= RT2573_PA_PE_5GHZ; rum_write(sc, RT2573_PHY_CSR0, tmp); - - /* 802.11a uses a 16 microseconds short interframe space */ - sc->sifs = IEEE80211_IS_CHAN_5GHZ(c) ? 16 : 10; } static void rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct rfprog *rfprog; uint8_t bbp3, bbp94 = RT2573_BBPR94_DEFAULT; int8_t power; @@ -1868,10 +1805,12 @@ rum_set_chan(struct rum_softc *sc, struct ieee80211_channel *c) static void rum_enable_tsf_sync(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; - if (ic->ic_opmode != IEEE80211_M_STA) { + if (vap->iv_opmode != IEEE80211_M_STA) { /* * Change default 16ms TBTT adjustment to 8ms. * Must be done before enabling beacon generation. @@ -1882,10 +1821,10 @@ rum_enable_tsf_sync(struct rum_softc *sc) tmp = rum_read(sc, RT2573_TXRX_CSR9) & 0xff000000; /* set beacon interval (in 1/16ms unit) */ - tmp |= ic->ic_bss->ni_intval * 16; + tmp |= vap->iv_bss->ni_intval * 16; tmp |= RT2573_TSF_TICKING | RT2573_ENABLE_TBTT; - if (ic->ic_opmode == IEEE80211_M_STA) + if (vap->iv_opmode == IEEE80211_M_STA) tmp |= RT2573_TSF_MODE(1); else tmp |= RT2573_TSF_MODE(2) | RT2573_GENERATE_BEACON; @@ -1897,7 +1836,7 @@ static void rum_update_slot(struct ifnet *ifp) { struct rum_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; uint8_t slottime; uint32_t tmp; @@ -1937,7 +1876,7 @@ rum_set_macaddr(struct rum_softc *sc, const uint8_t *addr) static void rum_update_promisc(struct rum_softc *sc) { - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; tmp = rum_read(sc, RT2573_TXRX_CSR0); @@ -1967,7 +1906,8 @@ rum_get_rf(int rev) static void rum_read_eeprom(struct rum_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t val; #ifdef RUM_DEBUG int i; @@ -2082,12 +2022,11 @@ rum_bbp_init(struct rum_softc *sc) } static void -rum_init(void *priv) +rum_init_locked(struct rum_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct rum_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct rum_rx_data *data; uint32_t tmp; usbd_status error; @@ -2111,8 +2050,8 @@ rum_init(void *priv) DELAY(1000); } if (ntries == 1000) { - printf("%s: timeout waiting for BBP/RF to wakeup\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "timeout waiting for BBP/RF to wakeup\n"); goto fail; } @@ -2138,8 +2077,7 @@ rum_init(void *priv) */ sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->amrr_xfer == NULL) { - printf("%s: could not allocate AMRR xfer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not allocate AMRR xfer\n"); goto fail; } @@ -2149,15 +2087,15 @@ rum_init(void *priv) error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, &sc->sc_tx_pipeh); if (error != 0) { - printf("%s: could not open Tx pipe: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not open Tx pipe: %s\n", + usbd_errstr(error)); goto fail; } error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, &sc->sc_rx_pipeh); if (error != 0) { - printf("%s: could not open Rx pipe: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not open Rx pipe: %s\n", + usbd_errstr(error)); goto fail; } @@ -2166,14 +2104,12 @@ rum_init(void *priv) */ error = rum_alloc_tx_list(sc); if (error != 0) { - printf("%s: could not allocate Tx list\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not allocate Tx list\n"); goto fail; } error = rum_alloc_rx_list(sc); if (error != 0) { - printf("%s: could not allocate Rx list\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not allocate Rx list\n"); goto fail; } @@ -2204,13 +2140,6 @@ rum_init(void *priv) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; - - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - return; fail: rum_stop(sc); @@ -2218,18 +2147,30 @@ fail: rum_stop(sc); } static void +rum_init(void *priv) +{ + struct rum_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + RUM_LOCK(sc); + rum_init_locked(sc); + RUM_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void rum_stop(void *priv) { struct rum_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; sc->sc_tx_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - /* disable Rx */ tmp = rum_read(sc, RT2573_TXRX_CSR0); rum_write(sc, RT2573_TXRX_CSR0, tmp | RT2573_DISABLE_RX); @@ -2277,30 +2218,28 @@ rum_load_microcode(struct rum_softc *sc, const u_char *ucode, size_t size) error = usbd_do_request(sc->sc_udev, &req, NULL); if (error != 0) { - printf("%s: could not run firmware: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not run firmware: %s\n", + usbd_errstr(error)); } return error; } static int -rum_prepare_beacon(struct rum_softc *sc) +rum_prepare_beacon(struct rum_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = vap->iv_ic; + const struct ieee80211_txparam *tp; struct rum_tx_desc desc; struct mbuf *m0; - int rate; - m0 = ieee80211_beacon_alloc(ic->ic_bss, &sc->sc_bo); + m0 = ieee80211_beacon_alloc(vap->iv_bss, &RUM_VAP(vap)->bo); if (m0 == NULL) { return ENOBUFS; } - /* send beacons at the lowest available rate */ - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; - + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; rum_setup_tx_desc(sc, &desc, RT2573_TX_TIMESTAMP, RT2573_TX_HWSEQ, - m0->m_pkthdr.len, rate); + m0->m_pkthdr.len, tp->mgmtrate); /* copy the first 24 bytes of Tx descriptor into NIC memory */ rum_write_multi(sc, RT2573_HW_BEACON_BASE0, (uint8_t *)&desc, 24); @@ -2318,8 +2257,7 @@ static int rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, const struct ieee80211_bpf_params *params) { - struct ieee80211com *ic = ni->ni_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = ni->ni_ic->ic_ifp; struct rum_softc *sc = ifp->if_softc; /* prevent management frames from being sent if we're not ready */ @@ -2328,16 +2266,13 @@ rum_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, ieee80211_free_node(ni); return ENETDOWN; } - if (sc->tx_queued >= RUM_TX_LIST_COUNT) { + if (sc->tx_queued >= RUM_TX_LIST_COUNT-1) { ifp->if_drv_flags |= IFF_DRV_OACTIVE; m_freem(m); ieee80211_free_node(ni); return EIO; } - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m); - ifp->if_opackets++; if (params == NULL) { @@ -2368,26 +2303,22 @@ bad: static void rum_amrr_start(struct rum_softc *sc, struct ieee80211_node *ni) { - int i; + struct ieee80211vap *vap = ni->ni_vap; + struct rum_vap *rvp = RUM_VAP(vap); /* clear statistic registers (STA_CSR0 to STA_CSR5) */ rum_read_multi(sc, RT2573_STA_CSR0, sc->sta, sizeof sc->sta); - ieee80211_amrr_node_init(&sc->amrr, &sc->amn); - - /* set rate to some reasonable initial value */ - for (i = ni->ni_rates.rs_nrates - 1; - i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; - i--); - ni->ni_txrate = i; + ieee80211_amrr_node_init(&rvp->amrr, &RUM_NODE(ni)->amn, ni); - callout_reset(&sc->amrr_ch, hz, rum_amrr_timeout, sc); + callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap); } static void rum_amrr_timeout(void *arg) { - struct rum_softc *sc = (struct rum_softc *)arg; + struct ieee80211vap *vap = arg; + struct rum_softc *sc = vap->iv_ic->ic_ifp->if_softc; usb_device_request_t req; /* @@ -2399,7 +2330,7 @@ rum_amrr_timeout(void *arg) USETW(req.wIndex, RT2573_STA_CSR0); USETW(req.wLength, sizeof sc->sta); - usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc, + usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, vap, USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, rum_amrr_update); (void)usbd_transfer(sc->amrr_xfer); @@ -2409,8 +2340,11 @@ static void rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { - struct rum_softc *sc = (struct rum_softc *)priv; - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ieee80211vap *vap = priv; + struct rum_vap *rvp = RUM_VAP(vap); + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct rum_softc *sc = ifp->if_softc; + int ok, fail; if (status != USBD_NORMAL_COMPLETION) { device_printf(sc->sc_dev, "could not retrieve Tx statistics - " @@ -2418,21 +2352,34 @@ rum_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, return; } - /* count TX retry-fail as Tx errors */ - ifp->if_oerrors += le32toh(sc->sta[5]) >> 16; + ok = (le32toh(sc->sta[4]) >> 16) + /* TX ok w/o retry */ + (le32toh(sc->sta[5]) & 0xffff); /* TX ok w/ retry */ + fail = (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ + + ieee80211_amrr_tx_update(&RUM_NODE(vap->iv_bss)->amn, + ok+fail, ok, (le32toh(sc->sta[5]) & 0xffff) + fail); + + ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - sc->amn.amn_retrycnt = - (le32toh(sc->sta[4]) >> 16) + /* TX one-retry ok count */ - (le32toh(sc->sta[5]) & 0xffff) + /* TX more-retry ok count */ - (le32toh(sc->sta[5]) >> 16); /* TX retry-fail count */ + callout_reset(&rvp->amrr_ch, hz, rum_amrr_timeout, vap); +} - sc->amn.amn_txcnt = - sc->amn.amn_retrycnt + - (le32toh(sc->sta[4]) & 0xffff); /* TX no-retry ok count */ +/* ARGUSED */ +static struct ieee80211_node * +rum_node_alloc(struct ieee80211_node_table *nt __unused) +{ + struct rum_node *rn; - ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn); + rn = malloc(sizeof(struct rum_node), M_80211_NODE, M_NOWAIT | M_ZERO); + return rn != NULL ? &rn->ni : NULL; +} - callout_reset(&sc->amrr_ch, hz, rum_amrr_timeout, sc); +static void +rum_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct ieee80211vap *vap = ni->ni_vap; + + ieee80211_amrr_node_init(&RUM_VAP(vap)->amrr, &RUM_NODE(ni)->amn, ni); } static void @@ -2469,14 +2416,17 @@ rum_set_channel(struct ieee80211com *ic) /* do it in a process context */ sc->sc_scan_action = RUM_SET_CHANNEL; usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); + + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); } static void rum_scantask(void *arg) { struct rum_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint32_t tmp; RUM_LOCK(sc); @@ -2492,7 +2442,7 @@ rum_scantask(void *arg) case RUM_SCAN_END: rum_enable_tsf_sync(sc); /* XXX keep local copy */ - rum_set_bssid(sc, ic->ic_bss->ni_bssid); + rum_set_bssid(sc, vap->iv_bss->ni_bssid); break; case RUM_SET_CHANNEL: @@ -2513,6 +2463,8 @@ rum_scantask(void *arg) static int rum_get_rssi(struct rum_softc *sc, uint8_t raw) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int lna, agc, rssi; lna = (raw >> 5) & 0x3; @@ -2530,7 +2482,7 @@ rum_get_rssi(struct rum_softc *sc, uint8_t raw) rssi = (2 * agc) - RT2573_NOISE_FLOOR; - if (IEEE80211_IS_CHAN_2GHZ(sc->sc_ic.ic_curchan)) { + if (IEEE80211_IS_CHAN_2GHZ(ic->ic_curchan)) { rssi += sc->rssi_2ghz_corr; if (lna == 1) diff --git a/sys/dev/usb/if_rumvar.h b/sys/dev/usb/if_rumvar.h index e7d6d15..59980c0 100644 --- a/sys/dev/usb/if_rumvar.h +++ b/sys/dev/usb/if_rumvar.h @@ -18,7 +18,7 @@ */ #define RUM_RX_LIST_COUNT 1 -#define RUM_TX_LIST_COUNT 1 +#define RUM_TX_LIST_COUNT 8 struct rum_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -69,11 +69,26 @@ struct rum_rx_data { struct mbuf *m; }; +struct rum_node { + struct ieee80211_node ni; + struct ieee80211_amrr_node amn; +}; +#define RUM_NODE(ni) ((struct rum_node *)(ni)) + +struct rum_vap { + struct ieee80211vap vap; + struct ieee80211_beacon_offsets bo; + struct ieee80211_amrr amrr; + struct callout amrr_ch; + + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define RUM_VAP(vap) ((struct rum_vap *)(vap)) + struct rum_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); + const struct ieee80211_rate_table *sc_rates; device_t sc_dev; usbd_device_handle sc_udev; @@ -94,9 +109,6 @@ struct rum_softc { int sc_arg; struct usb_task sc_task; - struct ieee80211_amrr amrr; - struct ieee80211_amrr_node amn; - struct usb_task sc_scantask; int sc_scan_action; #define RUM_SCAN_START 0 @@ -106,13 +118,11 @@ struct rum_softc { struct rum_rx_data rx_data[RUM_RX_LIST_COUNT]; struct rum_tx_data tx_data[RUM_TX_LIST_COUNT]; int tx_queued; - - struct ieee80211_beacon_offsets sc_bo; + int tx_cur; struct mtx sc_mtx; struct callout watchdog_ch; - struct callout amrr_ch; int sc_tx_timer; @@ -133,23 +143,12 @@ struct rum_softc { int ext_5ghz_lna; int rssi_2ghz_corr; int rssi_5ghz_corr; - int sifs; uint8_t bbp17; - struct bpf_if *sc_drvbpf; - - union { - struct rum_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct rum_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - union { - struct rum_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct rum_tx_radiotap_header sc_txtap; int sc_txtap_len; }; diff --git a/sys/dev/usb/if_ural.c b/sys/dev/usb/if_ural.c index c2b063f..40a225b 100644 --- a/sys/dev/usb/if_ural.c +++ b/sys/dev/usb/if_ural.c @@ -51,6 +51,7 @@ __FBSDID("$FreeBSD$"); #include #include +#include #include #include @@ -115,23 +116,23 @@ MODULE_DEPEND(ural, wlan, 1, 1, 1); MODULE_DEPEND(ural, wlan_amrr, 1, 1, 1); MODULE_DEPEND(ural, usb, 1, 1, 1); +static struct ieee80211vap *ural_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void ural_vap_delete(struct ieee80211vap *); static int ural_alloc_tx_list(struct ural_softc *); static void ural_free_tx_list(struct ural_softc *); static int ural_alloc_rx_list(struct ural_softc *); static void ural_free_rx_list(struct ural_softc *); -static int ural_media_change(struct ifnet *); static void ural_task(void *); static void ural_scantask(void *); -static int ural_newstate(struct ieee80211com *, +static int ural_newstate(struct ieee80211vap *, enum ieee80211_state, int); -static int ural_rxrate(struct ural_rx_desc *); static void ural_txeof(usbd_xfer_handle, usbd_private_handle, usbd_status); static void ural_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); -static int ural_ack_rate(struct ieee80211com *, int); -static uint16_t ural_txtime(int, int, uint32_t); -static uint8_t ural_plcp_signal(int); static void ural_setup_tx_desc(struct ural_softc *, struct ural_tx_desc *, uint32_t, int, int); static int ural_tx_bcn(struct ural_softc *, struct mbuf *, @@ -142,7 +143,6 @@ static int ural_tx_data(struct ural_softc *, struct mbuf *, struct ieee80211_node *); static void ural_start(struct ifnet *); static void ural_watchdog(void *); -static int ural_reset(struct ifnet *); static int ural_ioctl(struct ifnet *, u_long, caddr_t); static void ural_set_testmode(struct ural_softc *); static void ural_eeprom_read(struct ural_softc *, uint16_t, void *, @@ -156,6 +156,8 @@ static void ural_write_multi(struct ural_softc *, uint16_t, void *, static void ural_bbp_write(struct ural_softc *, uint8_t, uint8_t); static uint8_t ural_bbp_read(struct ural_softc *, uint8_t); static void ural_rf_write(struct ural_softc *, uint8_t, uint32_t); +static struct ieee80211_node *ural_node_alloc(struct ieee80211_node_table *); +static void ural_newassoc(struct ieee80211_node *, int); static void ural_scan_start(struct ieee80211com *); static void ural_scan_end(struct ieee80211com *); static void ural_set_channel(struct ieee80211com *); @@ -165,7 +167,8 @@ static void ural_disable_rf_tune(struct ural_softc *); static void ural_enable_tsf_sync(struct ural_softc *); static void ural_update_slot(struct ifnet *); static void ural_set_txpreamble(struct ural_softc *); -static void ural_set_basicrates(struct ural_softc *); +static void ural_set_basicrates(struct ural_softc *, + const struct ieee80211_channel *); static void ural_set_bssid(struct ural_softc *, const uint8_t *); static void ural_set_macaddr(struct ural_softc *, uint8_t *); static void ural_update_promisc(struct ural_softc *); @@ -174,6 +177,7 @@ static void ural_read_eeprom(struct ural_softc *); static int ural_bbp_init(struct ural_softc *); static void ural_set_txantenna(struct ural_softc *, int); static void ural_set_rxantenna(struct ural_softc *, int); +static void ural_init_locked(struct ural_softc *); static void ural_init(void *); static void ural_stop(void *); static int ural_raw_xmit(struct ieee80211_node *, struct mbuf *, @@ -387,18 +391,18 @@ ural_attach(device_t self) struct ural_softc *sc = device_get_softc(self); struct usb_attach_arg *uaa = device_get_ivars(self); struct ifnet *ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; usb_interface_descriptor_t *id; usb_endpoint_descriptor_t *ed; usbd_status error; - int i, bands; + int i; + uint8_t bands; sc->sc_udev = uaa->device; sc->sc_dev = self; if (usbd_set_config_no(sc->sc_udev, RAL_CONFIG_NO, 0) != 0) { - printf("%s: could not set configuration no\n", - device_get_nameunit(sc->sc_dev)); + device_printf(self, "could not set configuration no\n"); return ENXIO; } @@ -406,8 +410,7 @@ ural_attach(device_t self) error = usbd_device2interface_handle(sc->sc_udev, RAL_IFACE_INDEX, &sc->sc_iface); if (error != 0) { - printf("%s: could not get interface handle\n", - device_get_nameunit(sc->sc_dev)); + device_printf(self, "could not get interface handle\n"); return ENXIO; } @@ -420,8 +423,8 @@ ural_attach(device_t self) for (i = 0; i < id->bNumEndpoints; i++) { ed = usbd_interface2endpoint_descriptor(sc->sc_iface, i); if (ed == NULL) { - printf("%s: no endpoint descriptor for %d\n", - device_get_nameunit(sc->sc_dev), i); + device_printf(self, "no endpoint descriptor for %d\n", + i); return ENXIO; } @@ -433,10 +436,16 @@ ural_attach(device_t self) sc->sc_tx_no = ed->bEndpointAddress; } if (sc->sc_rx_no == -1 || sc->sc_tx_no == -1) { - printf("%s: missing endpoint\n", - device_get_nameunit(sc->sc_dev)); + device_printf(self, "missing endpoint\n"); + return ENXIO; + } + + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); + if (ifp == NULL) { + device_printf(sc->sc_dev, "can not if_alloc()\n"); return ENXIO; } + ic = ifp->if_l2com; mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); @@ -444,7 +453,6 @@ ural_attach(device_t self) usb_init_task(&sc->sc_task, ural_task, sc); usb_init_task(&sc->sc_scantask, ural_scantask, sc); callout_init(&sc->watchdog_ch, 0); - callout_init(&sc->amrr_ch, 0); /* retrieve RT2570 rev. no */ sc->asic_rev = ural_read(sc, RAL_MAC_CSR0); @@ -452,16 +460,8 @@ ural_attach(device_t self) /* retrieve MAC address and various other things from EEPROM */ ural_read_eeprom(sc); - printf("%s: MAC/BBP RT2570 (rev 0x%02x), RF %s\n", - device_get_nameunit(sc->sc_dev), sc->asic_rev, - ural_get_rf(sc->rf_rev)); - - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); - if (ifp == NULL) { - printf("%s: can not if_alloc()\n", - device_get_nameunit(sc->sc_dev)); - return ENXIO; - } + device_printf(sc->sc_dev, "MAC/BBP RT2570 (rev 0x%02x), RF %s\n", + sc->asic_rev, ural_get_rf(sc->rf_rev)); ifp->if_softc = sc; if_initname(ifp, "ural", device_get_unit(sc->sc_dev)); @@ -476,8 +476,6 @@ ural_attach(device_t self) ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; /* set device capabilities */ ic->ic_caps = @@ -496,34 +494,29 @@ ural_attach(device_t self) setbit(&bands, IEEE80211_MODE_11G); if (sc->rf_rev == RAL_RF_5222) setbit(&bands, IEEE80211_MODE_11A); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); - ic->ic_reset = ural_reset; - /* enable s/w bmiss handling in sta mode */ - ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; + ic->ic_newassoc = ural_newassoc; + ic->ic_raw_xmit = ural_raw_xmit; + ic->ic_node_alloc = ural_node_alloc; ic->ic_scan_start = ural_scan_start; ic->ic_scan_end = ural_scan_end; ic->ic_set_channel = ural_set_channel; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = ural_newstate; - ic->ic_raw_xmit = ural_raw_xmit; - ieee80211_media_init(ic, ural_media_change, ieee80211_media_status); + ic->ic_vap_create = ural_vap_create; + ic->ic_vap_delete = ural_vap_delete; - ieee80211_amrr_init(&sc->amrr, ic, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + 64, &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof(sc->sc_txtap)); - sc->sc_rxtap_len = sizeof sc->sc_rxtapu; + sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); sc->sc_rxtap.wr_ihdr.it_present = htole32(RAL_RX_RADIOTAP_PRESENT); - sc->sc_txtap_len = sizeof sc->sc_txtapu; + sc->sc_txtap_len = sizeof sc->sc_txtap; sc->sc_txtap.wt_ihdr.it_len = htole16(sc->sc_txtap_len); sc->sc_txtap.wt_ihdr.it_present = htole32(RAL_TX_RADIOTAP_PRESENT); @@ -537,13 +530,16 @@ static int ural_detach(device_t self) { struct ural_softc *sc = device_get_softc(self); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; ural_stop(sc); + bpfdetach(ifp); + ieee80211_ifdetach(ic); + usb_rem_task(sc->sc_udev, &sc->sc_task); + usb_rem_task(sc->sc_udev, &sc->sc_scantask); callout_stop(&sc->watchdog_ch); - callout_stop(&sc->amrr_ch); if (sc->amrr_xfer != NULL) { usbd_free_xfer(sc->amrr_xfer); @@ -563,22 +559,66 @@ ural_detach(device_t self) ural_free_rx_list(sc); ural_free_tx_list(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); if_free(ifp); - mtx_destroy(&sc->sc_mtx); return 0; } +static struct ieee80211vap * +ural_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct ural_vap *uvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + uvp = (struct ural_vap *) malloc(sizeof(struct ural_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (uvp == NULL) + return NULL; + vap = &uvp->vap; + /* enable s/w bmiss handling for sta mode */ + ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + + /* override state transition machine */ + uvp->newstate = vap->iv_newstate; + vap->iv_newstate = ural_newstate; + + callout_init(&uvp->amrr_ch, 0); + ieee80211_amrr_init(&uvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 1000 /* 1 sec */); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +ural_vap_delete(struct ieee80211vap *vap) +{ + struct ural_vap *uvp = URAL_VAP(vap); + + callout_stop(&uvp->amrr_ch); + ieee80211_amrr_cleanup(&uvp->amrr); + ieee80211_vap_detach(vap); + free(uvp, M_80211_VAP); +} + static int ural_alloc_tx_list(struct ural_softc *sc) { struct ural_tx_data *data; int i, error; - sc->tx_queued = 0; + sc->tx_queued = sc->tx_cur = 0; for (i = 0; i < RAL_TX_LIST_COUNT; i++) { data = &sc->tx_data[i]; @@ -587,8 +627,8 @@ ural_alloc_tx_list(struct ural_softc *sc) data->xfer = usbd_alloc_xfer(sc->sc_udev); if (data->xfer == NULL) { - printf("%s: could not allocate tx xfer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate tx xfer\n"); error = ENOMEM; goto fail; } @@ -596,8 +636,8 @@ ural_alloc_tx_list(struct ural_softc *sc) data->buf = usbd_alloc_buffer(data->xfer, RAL_TX_DESC_SIZE + MCLBYTES); if (data->buf == NULL) { - printf("%s: could not allocate tx buffer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate tx buffer\n"); error = ENOMEM; goto fail; } @@ -643,23 +683,23 @@ ural_alloc_rx_list(struct ural_softc *sc) data->xfer = usbd_alloc_xfer(sc->sc_udev); if (data->xfer == NULL) { - printf("%s: could not allocate rx xfer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate rx xfer\n"); error = ENOMEM; goto fail; } if (usbd_alloc_buffer(data->xfer, MCLBYTES) == NULL) { - printf("%s: could not allocate rx buffer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate rx buffer\n"); error = ENOMEM; goto fail; } data->m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); if (data->m == NULL) { - printf("%s: could not allocate rx mbuf\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate rx mbuf\n"); error = ENOMEM; goto fail; } @@ -694,39 +734,20 @@ ural_free_rx_list(struct ural_softc *sc) } } -static int -ural_media_change(struct ifnet *ifp) -{ - struct ural_softc *sc = ifp->if_softc; - int error; - - RAL_LOCK(sc); - - error = ieee80211_media_change(ifp); - if (error != ENETRESET) { - RAL_UNLOCK(sc); - return error; - } - - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING)) - ural_init(sc); - - RAL_UNLOCK(sc); - - return 0; -} - static void ural_task(void *xarg) { struct ural_softc *sc = xarg; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ural_vap *uvp = URAL_VAP(vap); + const struct ieee80211_txparam *tp; enum ieee80211_state ostate; struct ieee80211_node *ni; struct mbuf *m; - ostate = ic->ic_state; + ostate = vap->iv_state; RAL_LOCK(sc); switch (sc->sc_state) { @@ -741,27 +762,27 @@ ural_task(void *xarg) break; case IEEE80211_S_RUN: - ni = ic->ic_bss; + ni = vap->iv_bss; - if (ic->ic_opmode != IEEE80211_M_MONITOR) { + if (vap->iv_opmode != IEEE80211_M_MONITOR) { ural_update_slot(ic->ic_ifp); ural_set_txpreamble(sc); - ural_set_basicrates(sc); + ural_set_basicrates(sc, ic->ic_bsschan); ural_set_bssid(sc, ni->ni_bssid); } - if (ic->ic_opmode == IEEE80211_M_HOSTAP || - ic->ic_opmode == IEEE80211_M_IBSS) { - m = ieee80211_beacon_alloc(ni, &sc->sc_bo); + if (vap->iv_opmode == IEEE80211_M_HOSTAP || + vap->iv_opmode == IEEE80211_M_IBSS) { + m = ieee80211_beacon_alloc(ni, &uvp->bo); if (m == NULL) { - printf("%s: could not allocate beacon\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not allocate beacon\n"); return; } if (ural_tx_bcn(sc, m, ni) != 0) { - printf("%s: could not send beacon\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "could not send beacon\n"); return; } } @@ -769,12 +790,12 @@ ural_task(void *xarg) /* make tx led blink on tx (controlled by ASIC) */ ural_write(sc, RAL_MAC_CSR20, 1); - if (ic->ic_opmode != IEEE80211_M_MONITOR) + if (vap->iv_opmode != IEEE80211_M_MONITOR) ural_enable_tsf_sync(sc); - /* enable automatic rate adaptation in STA mode */ - if (ic->ic_opmode == IEEE80211_M_STA && - ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) + /* enable automatic rate adaptation */ + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; + if (tp->ucastrate == IEEE80211_FIXED_RATE_NONE) ural_amrr_start(sc, ni); break; @@ -784,15 +805,21 @@ ural_task(void *xarg) } RAL_UNLOCK(sc); - sc->sc_newstate(ic, sc->sc_state, sc->sc_arg); + + IEEE80211_LOCK(ic); + uvp->newstate(vap, sc->sc_state, sc->sc_arg); + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + IEEE80211_UNLOCK(ic); } static void ural_scantask(void *arg) { struct ural_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); RAL_LOCK(sc); if (sc->sc_scan_action == URAL_SCAN_START) { @@ -806,77 +833,42 @@ ural_scantask(void *arg) } else { ural_enable_tsf_sync(sc); /* XXX keep local copy */ - ural_set_bssid(sc, ic->ic_bss->ni_bssid); + ural_set_bssid(sc, vap->iv_bss->ni_bssid); } RAL_UNLOCK(sc); } static int -ural_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +ural_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct ural_vap *uvp = URAL_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct ural_softc *sc = ic->ic_ifp->if_softc; - callout_stop(&sc->amrr_ch); + callout_stop(&uvp->amrr_ch); /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; usb_rem_task(sc->sc_udev, &sc->sc_task); - if (nstate == IEEE80211_S_INIT) - sc->sc_newstate(ic, nstate, arg); - else + if (nstate == IEEE80211_S_INIT) { + uvp->newstate(vap, nstate, arg); + return 0; + } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - return 0; + return EINPROGRESS; + } } -/* quickly determine if a given rate is CCK or OFDM */ -#define RAL_RATE_IS_OFDM(rate) ((rate) >= 12 && (rate) != 22) - -#define RAL_ACK_SIZE 14 /* 10 + 4(FCS) */ -#define RAL_CTS_SIZE 14 /* 10 + 4(FCS) */ - -#define RAL_SIFS 10 /* us */ - #define RAL_RXTX_TURNAROUND 5 /* us */ -/* - * This function is only used by the Rx radiotap code. - */ -static int -ural_rxrate(struct ural_rx_desc *desc) -{ - if (le32toh(desc->flags) & RAL_RX_OFDM) { - /* reverse function of ural_plcp_signal */ - switch (desc->rate) { - case 0xb: return 12; - case 0xf: return 18; - case 0xa: return 24; - case 0xe: return 36; - case 0x9: return 48; - case 0xd: return 72; - case 0x8: return 96; - case 0xc: return 108; - } - } else { - if (desc->rate == 10) - return 2; - if (desc->rate == 20) - return 4; - if (desc->rate == 55) - return 11; - if (desc->rate == 110) - return 22; - } - return 2; /* should not get there */ -} - static void ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ural_tx_data *data = priv; struct ural_softc *sc = data->sc; - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; if (data->m->m_flags & M_TXCB) ieee80211_process_callback(data->ni, data->m, @@ -885,8 +877,8 @@ ural_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) return; - printf("%s: could not transmit buffer: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(status)); + device_printf(sc->sc_dev, "could not transmit buffer: %s\n", + usbd_errstr(status)); if (status == USBD_STALLED) usbd_clear_endpoint_stall_async(sc->sc_rx_pipeh); @@ -916,13 +908,12 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { struct ural_rx_data *data = priv; struct ural_softc *sc = data->sc; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ural_rx_desc *desc; - struct ieee80211_frame *wh; struct ieee80211_node *ni; struct mbuf *mnew, *m; - int len; + int len, rssi; if (status != USBD_NORMAL_COMPLETION) { if (status == USBD_NOT_STARTED || status == USBD_CANCELLED) @@ -970,30 +961,30 @@ ural_rxeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) m->m_pkthdr.rcvif = ifp; m->m_pkthdr.len = m->m_len = (le32toh(desc->flags) >> 16) & 0xfff; - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct ural_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = IEEE80211_RADIOTAP_F_FCS; - tap->wr_rate = ural_rxrate(desc); + tap->wr_rate = ieee80211_plcp2rate(desc->rate, + le32toh(desc->flags) & RAL_RX_OFDM); tap->wr_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wr_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wr_antenna = sc->rx_ant; tap->wr_antsignal = URAL_RSSI(desc->rssi); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } /* Strip trailing 802.11 MAC FCS. */ m_adj(m, -IEEE80211_CRC_LEN); - wh = mtod(m, struct ieee80211_frame *); - ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *)wh); - - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, URAL_RSSI(desc->rssi), RAL_NOISE_FLOOR, 0); - - /* node is no longer needed */ - ieee80211_free_node(ni); + rssi = URAL_RSSI(desc->rssi); + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + (void) ieee80211_input(ni, m, rssi, RAL_NOISE_FLOOR, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, RAL_NOISE_FLOOR, 0); DPRINTFN(15, ("rx done\n")); @@ -1003,95 +994,12 @@ skip: /* setup a new transfer */ usbd_transfer(xfer); } -/* - * Return the expected ack rate for a frame transmitted at rate `rate'. - * XXX: this should depend on the destination node basic rate set. - */ -static int -ural_ack_rate(struct ieee80211com *ic, int rate) -{ - switch (rate) { - /* CCK rates */ - case 2: - return 2; - case 4: - case 11: - case 22: - return (ic->ic_curmode == IEEE80211_MODE_11B) ? 4 : rate; - - /* OFDM rates */ - case 12: - case 18: - return 12; - case 24: - case 36: - return 24; - case 48: - case 72: - case 96: - case 108: - return 48; - } - - /* default to 1Mbps */ - return 2; -} - -/* - * Compute the duration (in us) needed to transmit `len' bytes at rate `rate'. - * The function automatically determines the operating mode depending on the - * given rate. `flags' indicates whether short preamble is in use or not. - */ -static uint16_t -ural_txtime(int len, int rate, uint32_t flags) -{ - uint16_t txtime; - - if (RAL_RATE_IS_OFDM(rate)) { - /* IEEE Std 802.11a-1999, pp. 37 */ - txtime = (8 + 4 * len + 3 + rate - 1) / rate; - txtime = 16 + 4 + 4 * txtime + 6; - } else { - /* IEEE Std 802.11b-1999, pp. 28 */ - txtime = (16 * len + rate - 1) / rate; - if (rate != 2 && (flags & IEEE80211_F_SHPREAMBLE)) - txtime += 72 + 24; - else - txtime += 144 + 48; - } - return txtime; -} - -static uint8_t -ural_plcp_signal(int rate) -{ - switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* unsupported rates (should not get there) */ - default: return 0xff; - } -} - static void ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, uint32_t flags, int len, int rate) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t plcp_length; int remainder; @@ -1103,11 +1011,11 @@ ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, desc->wme |= htole16(RAL_IVOFFSET(sizeof (struct ieee80211_frame))); /* setup PLCP fields */ - desc->plcp_signal = ural_plcp_signal(rate); + desc->plcp_signal = ieee80211_rate2plcp(rate); desc->plcp_service = 4; len += IEEE80211_CRC_LEN; - if (RAL_RATE_IS_OFDM(rate)) { + if (ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) { desc->flags |= htole32(RAL_TX_OFDM); plcp_length = len & 0xfff; @@ -1136,14 +1044,17 @@ ural_setup_tx_desc(struct ural_softc *sc, struct ural_tx_desc *desc, static int ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_txparam *tp; struct ural_tx_desc *desc; usbd_xfer_handle xfer; - uint8_t cmd = 0; + uint8_t cmd; usbd_status error; uint8_t *buf; - int xferlen, rate; + int xferlen; - rate = IEEE80211_IS_CHAN_5GHZ(ni->ni_chan) ? 12 : 2; + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; xfer = usbd_alloc_xfer(sc->sc_udev); if (xfer == NULL) @@ -1158,6 +1069,7 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) return ENOMEM; } + cmd = 0; usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, &cmd, sizeof cmd, USBD_FORCE_SHORT_XFER, RAL_TX_TIMEOUT, NULL); @@ -1171,10 +1083,10 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) m_copydata(m0, 0, m0->m_pkthdr.len, buf + RAL_TX_DESC_SIZE); ural_setup_tx_desc(sc, desc, RAL_TX_IFS_NEWBACKOFF | RAL_TX_TIMESTAMP, - m0->m_pkthdr.len, rate); + m0->m_pkthdr.len, tp->mgmtrate); DPRINTFN(10, ("sending beacon frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, rate, xferlen)); + m0->m_pkthdr.len, tp->mgmtrate, xferlen)); usbd_setup_xfer(xfer, sc->sc_tx_pipeh, NULL, buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, NULL); @@ -1188,40 +1100,43 @@ ural_tx_bcn(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) static int ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; + const struct ieee80211_txparam *tp; struct ural_tx_desc *desc; struct ural_tx_data *data; struct ieee80211_frame *wh; struct ieee80211_key *k; - uint32_t flags = 0; + uint32_t flags; uint16_t dur; usbd_status error; - int xferlen, rate; + int xferlen; - data = &sc->tx_data[0]; + data = &sc->tx_data[sc->tx_cur]; desc = (struct ural_tx_desc *)data->buf; - rate = IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan) ? 12 : 2; + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_curchan)]; wh = mtod(m0, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; } + wh = mtod(m0, struct ieee80211_frame *); } data->m = m0; data->ni = ni; - wh = mtod(m0, struct ieee80211_frame *); - + flags = 0; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { flags |= RAL_TX_ACK; - dur = ural_txtime(RAL_ACK_SIZE, rate, ic->ic_flags) + RAL_SIFS; + dur = ieee80211_ack_duration(sc->sc_rates, tp->mgmtrate, + ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); /* tell hardware to add timestamp for probe responses */ @@ -1232,20 +1147,20 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) flags |= RAL_TX_TIMESTAMP; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct ural_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; - tap->wt_rate = rate; + tap->wt_rate = tp->mgmtrate; tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); - ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate); + ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, tp->mgmtrate); /* align end on a 2-bytes boundary */ xferlen = (RAL_TX_DESC_SIZE + m0->m_pkthdr.len + 1) & ~1; @@ -1258,7 +1173,7 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) xferlen += 2; DPRINTFN(10, ("sending mgt frame len=%u rate=%u xfer len=%u\n", - m0->m_pkthdr.len, rate, xferlen)); + m0->m_pkthdr.len, tp->mgmtrate, xferlen)); usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, xferlen, USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, @@ -1273,6 +1188,71 @@ ural_tx_mgt(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; + + return 0; +} + +static int +ural_sendprot(struct ural_softc *sc, + const struct mbuf *m, struct ieee80211_node *ni, int prot, int rate) +{ + struct ieee80211com *ic = ni->ni_ic; + const struct ieee80211_frame *wh; + struct ural_tx_desc *desc; + struct ural_tx_data *data; + struct mbuf *mprot; + int protrate, ackrate, pktlen, flags, isshort; + uint16_t dur; + usbd_status error; + + KASSERT(prot == IEEE80211_PROT_RTSCTS || prot == IEEE80211_PROT_CTSONLY, + ("protection %d", prot)); + + wh = mtod(m, const struct ieee80211_frame *); + pktlen = m->m_pkthdr.len + IEEE80211_CRC_LEN; + + protrate = ieee80211_ctl_rate(sc->sc_rates, rate); + ackrate = ieee80211_ack_rate(sc->sc_rates, rate); + + isshort = (ic->ic_flags & IEEE80211_F_SHPREAMBLE) != 0; + dur = ieee80211_compute_duration(sc->sc_rates, pktlen, rate, isshort); + + ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags = RAL_TX_RETRY(7); + if (prot == IEEE80211_PROT_RTSCTS) { + /* NB: CTS is the same size as an ACK */ + dur += ieee80211_ack_duration(sc->sc_rates, rate, isshort); + flags |= RAL_TX_ACK; + mprot = ieee80211_alloc_rts(ic, wh->i_addr1, wh->i_addr2, dur); + } else { + mprot = ieee80211_alloc_cts(ic, ni->ni_vap->iv_myaddr, dur); + } + if (mprot == NULL) { + /* XXX stat + msg */ + return ENOBUFS; + } + data = &sc->tx_data[sc->tx_cur]; + desc = (struct ural_tx_desc *)data->buf; + + data->m = mprot; + data->ni = ieee80211_ref_node(ni); + m_copydata(mprot, 0, mprot->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); + ural_setup_tx_desc(sc, desc, flags, mprot->m_pkthdr.len, protrate); + + usbd_setup_xfer(data->xfer, sc->sc_tx_pipeh, data, data->buf, + /* NB: no roundup necessary */ + RAL_TX_DESC_SIZE + mprot->m_pkthdr.len, + USBD_FORCE_SHORT_XFER | USBD_NO_COPY, RAL_TX_TIMEOUT, ural_txeof); + + error = usbd_transfer(data->xfer); + if (error != USBD_NORMAL_COMPLETION && error != USBD_IN_PROGRESS) { + data->m = NULL; + data->ni = NULL; + return error; + } + + sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; return 0; } @@ -1281,14 +1261,17 @@ static int ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, const struct ieee80211_bpf_params *params) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ural_tx_desc *desc; struct ural_tx_data *data; uint32_t flags; usbd_status error; int xferlen, rate; - data = &sc->tx_data[0]; + KASSERT(params != NULL, ("no raw xmit params")); + + data = &sc->tx_data[sc->tx_cur]; desc = (struct ural_tx_desc *)data->buf; rate = params->ibp_rate0 & IEEE80211_RATE_VAL; @@ -1297,8 +1280,22 @@ ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, m_freem(m0); return EINVAL; } + flags = 0; + if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) + flags |= RAL_TX_ACK; + if (params->ibp_flags & (IEEE80211_BPF_RTS|IEEE80211_BPF_CTS)) { + error = ural_sendprot(sc, m0, ni, + params->ibp_flags & IEEE80211_BPF_RTS ? + IEEE80211_PROT_RTSCTS : IEEE80211_PROT_CTSONLY, + rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RAL_TX_IFS_SIFS; + } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct ural_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1307,16 +1304,12 @@ ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } data->m = m0; data->ni = ni; - flags = 0; - if ((params->ibp_flags & IEEE80211_BPF_NOACK) == 0) - flags |= RAL_TX_ACK; - m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); /* XXX need to setup descriptor ourself */ ural_setup_tx_desc(sc, desc, flags, m0->m_pkthdr.len, rate); @@ -1347,6 +1340,7 @@ ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; return 0; } @@ -1354,10 +1348,13 @@ ural_tx_raw(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, static int ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = sc->sc_ifp; struct ural_tx_desc *desc; struct ural_tx_data *data; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; uint32_t flags = 0; uint16_t dur; @@ -1366,25 +1363,42 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); - if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) - rate = ic->ic_fixed_rate; + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if (IEEE80211_IS_MULTICAST(wh->i_addr1)) + rate = tp->mcastrate; + else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) + rate = tp->ucastrate; else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - - rate &= IEEE80211_RATE_VAL; + rate = ni->ni_txrate; if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; } - /* packet header may have moved, reset our local pointer */ wh = mtod(m0, struct ieee80211_frame *); } - data = &sc->tx_data[0]; + if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { + int prot = IEEE80211_PROT_NONE; + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) + prot = IEEE80211_PROT_RTSCTS; + else if ((ic->ic_flags & IEEE80211_F_USEPROT) && + ieee80211_rate2phytype(sc->sc_rates, rate) == IEEE80211_T_OFDM) + prot = ic->ic_protmode; + if (prot != IEEE80211_PROT_NONE) { + error = ural_sendprot(sc, m0, ni, prot, rate); + if (error) { + m_freem(m0); + return error; + } + flags |= RAL_TX_IFS_SIFS; + } + } + + data = &sc->tx_data[sc->tx_cur]; desc = (struct ural_tx_desc *)data->buf; data->m = m0; @@ -1394,12 +1408,12 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) flags |= RAL_TX_ACK; flags |= RAL_TX_RETRY(7); - dur = ural_txtime(RAL_ACK_SIZE, ural_ack_rate(ic, rate), - ic->ic_flags) + RAL_SIFS; + dur = ieee80211_ack_duration(sc->sc_rates, rate, + ic->ic_flags & IEEE80211_F_SHPREAMBLE); *(uint16_t *)wh->i_dur = htole16(dur); } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct ural_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -1408,7 +1422,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); tap->wt_antenna = sc->tx_ant; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } m_copydata(m0, 0, m0->m_pkthdr.len, data->buf + RAL_TX_DESC_SIZE); @@ -1440,6 +1454,7 @@ ural_tx_data(struct ural_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) } sc->tx_queued++; + sc->tx_cur = (sc->tx_cur + 1) % RAL_TX_LIST_COUNT; return 0; } @@ -1448,77 +1463,30 @@ static void ural_start(struct ifnet *ifp) { struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct mbuf *m0; - struct ether_header *eh; struct ieee80211_node *ni; + struct mbuf *m; for (;;) { - IF_POLL(&ic->ic_mgtq, m0); - if (m0 != NULL) { - if (sc->tx_queued >= RAL_TX_LIST_COUNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IF_DEQUEUE(&ic->ic_mgtq, m0); - - ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (ural_tx_mgt(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - break; - } - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - if (sc->tx_queued >= RAL_TX_LIST_COUNT) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - if (m0->m_len < sizeof (struct ether_header) && - !(m0 = m_pullup(m0, sizeof (struct ether_header)))) - continue; - - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - BPF_MTAP(ifp, m0); - - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ieee80211_free_node(ni); - continue; - } - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (ural_tx_data(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + if (sc->tx_queued >= RAL_TX_LIST_COUNT-1) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + continue; + } + if (ural_tx_data(sc, m, ni) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; } - sc->sc_tx_timer = 5; - ic->ic_lastdata = ticks; callout_reset(&sc->watchdog_ch, hz, ural_watchdog, sc); } } @@ -1544,61 +1512,40 @@ ural_watchdog(void *arg) RAL_UNLOCK(sc); } -/* - * This function allows for fast channel switching in monitor mode (used by - * net-mgmt/kismet). In IBSS mode, we must explicitly reset the interface to - * generate a new beacon frame. - */ -static int -ural_reset(struct ifnet *ifp) -{ - struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - - if (ic->ic_opmode != IEEE80211_M_MONITOR) - return ENETRESET; - - ural_set_chan(sc, ic->ic_curchan); - - return 0; -} - static int ural_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 1; RAL_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) + if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) { + ural_init_locked(sc); + startall = 1; + } else ural_update_promisc(sc); - else - ural_init(sc); } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) ural_stop(sc); } break; - + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - (ic->ic_roaming != IEEE80211_ROAMING_MANUAL)) - ural_init(sc); - error = 0; + error = ether_ioctl(ifp, cmd, data); + break; } - RAL_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } @@ -1616,8 +1563,8 @@ ural_set_testmode(struct ural_softc *sc) error = usbd_do_request(sc->sc_udev, &req, NULL); if (error != 0) { - printf("%s: could not set test mode: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not set test mode: %s\n", + usbd_errstr(error)); } } @@ -1635,8 +1582,8 @@ ural_eeprom_read(struct ural_softc *sc, uint16_t addr, void *buf, int len) error = usbd_do_request(sc->sc_udev, &req, buf); if (error != 0) { - printf("%s: could not read EEPROM: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not read EEPROM: %s\n", + usbd_errstr(error)); } } @@ -1655,8 +1602,8 @@ ural_read(struct ural_softc *sc, uint16_t reg) error = usbd_do_request(sc->sc_udev, &req, &val); if (error != 0) { - printf("%s: could not read MAC register: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not read MAC register: %s\n", + usbd_errstr(error)); return 0; } @@ -1677,8 +1624,8 @@ ural_read_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len) error = usbd_do_request(sc->sc_udev, &req, buf); if (error != 0) { - printf("%s: could not read MAC register: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not read MAC register: %s\n", + usbd_errstr(error)); } } @@ -1696,8 +1643,8 @@ ural_write(struct ural_softc *sc, uint16_t reg, uint16_t val) error = usbd_do_request(sc->sc_udev, &req, NULL); if (error != 0) { - printf("%s: could not write MAC register: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not write MAC register: %s\n", + usbd_errstr(error)); } } @@ -1715,8 +1662,8 @@ ural_write_multi(struct ural_softc *sc, uint16_t reg, void *buf, int len) error = usbd_do_request(sc->sc_udev, &req, buf); if (error != 0) { - printf("%s: could not write MAC register: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not write MAC register: %s\n", + usbd_errstr(error)); } } @@ -1731,7 +1678,7 @@ ural_bbp_write(struct ural_softc *sc, uint8_t reg, uint8_t val) break; } if (ntries == 5) { - printf("%s: could not write to BBP\n", device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not write to BBP\n"); return; } @@ -1753,7 +1700,7 @@ ural_bbp_read(struct ural_softc *sc, uint8_t reg) break; } if (ntries == 5) { - printf("%s: could not read BBP\n", device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not read BBP\n"); return 0; } @@ -1771,7 +1718,7 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) break; } if (ntries == 5) { - printf("%s: could not write to RF\n", device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not write to RF\n"); return; } @@ -1785,6 +1732,24 @@ ural_rf_write(struct ural_softc *sc, uint8_t reg, uint32_t val) DPRINTFN(15, ("RF R[%u] <- 0x%05x\n", reg & 0x3, val & 0xfffff)); } +/* ARGUSED */ +static struct ieee80211_node * +ural_node_alloc(struct ieee80211_node_table *nt __unused) +{ + struct ural_node *un; + + un = malloc(sizeof(struct ural_node), M_80211_NODE, M_NOWAIT | M_ZERO); + return un != NULL ? &un->ni : NULL; +} + +static void +ural_newassoc(struct ieee80211_node *ni, int isnew) +{ + struct ieee80211vap *vap = ni->ni_vap; + + ieee80211_amrr_node_init(&URAL_VAP(vap)->amrr, &URAL_NODE(ni)->amn, ni); +} + static void ural_scan_start(struct ieee80211com *ic) { @@ -1822,12 +1787,15 @@ ural_set_channel(struct ieee80211com *ic) /* do it in a process context */ sc->sc_scan_action = URAL_SET_CHANNEL; usb_add_task(sc->sc_udev, &sc->sc_scantask, USB_TASKQ_DRIVER); + + sc->sc_rates = ieee80211_get_ratetable(ic->ic_curchan); } static void ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint8_t power, tmp; u_int i, chan; @@ -1924,17 +1892,9 @@ ural_set_chan(struct ural_softc *sc, struct ieee80211_channel *c) ural_disable_rf_tune(sc); } + /* XXX doesn't belong here */ /* update basic rate set */ - if (IEEE80211_IS_CHAN_B(c)) { - /* 11b basic rates: 1, 2Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x3); - } else if (IEEE80211_IS_CHAN_A(c)) { - /* 11a basic rates: 6, 12, 24Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x150); - } else { - /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x15f); - } + ural_set_basicrates(sc, c); } /* @@ -1963,13 +1923,15 @@ ural_disable_rf_tune(struct ural_softc *sc) static void ural_enable_tsf_sync(struct ural_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); uint16_t logcwmin, preload, tmp; /* first, disable TSF synchronization */ ural_write(sc, RAL_TXRX_CSR19, 0); - tmp = (16 * ic->ic_bss->ni_intval) << 4; + tmp = (16 * vap->iv_bss->ni_intval) << 4; ural_write(sc, RAL_TXRX_CSR18, tmp); logcwmin = (ic->ic_opmode == IEEE80211_M_IBSS) ? 2 : 0; @@ -1992,7 +1954,7 @@ static void ural_update_slot(struct ifnet *ifp) { struct ural_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; uint16_t slottime, sifs, eifs; slottime = (ic->ic_flags & IEEE80211_F_SHSLOT) ? 9 : 20; @@ -2017,32 +1979,33 @@ ural_update_slot(struct ifnet *ifp) static void ural_set_txpreamble(struct ural_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t tmp; tmp = ural_read(sc, RAL_TXRX_CSR10); tmp &= ~RAL_SHORT_PREAMBLE; - if (sc->sc_ic.ic_flags & IEEE80211_F_SHPREAMBLE) + if (ic->ic_flags & IEEE80211_F_SHPREAMBLE) tmp |= RAL_SHORT_PREAMBLE; ural_write(sc, RAL_TXRX_CSR10, tmp); } static void -ural_set_basicrates(struct ural_softc *sc) +ural_set_basicrates(struct ural_softc *sc, const struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; - + /* XXX wrong, take from rate set */ /* update basic rate set */ - if (ic->ic_curmode == IEEE80211_MODE_11B) { - /* 11b basic rates: 1, 2Mbps */ - ural_write(sc, RAL_TXRX_CSR11, 0x3); - } else if (IEEE80211_IS_CHAN_5GHZ(ic->ic_bss->ni_chan)) { + if (IEEE80211_IS_CHAN_5GHZ(c)) { /* 11a basic rates: 6, 12, 24Mbps */ ural_write(sc, RAL_TXRX_CSR11, 0x150); - } else { + } else if (IEEE80211_IS_CHAN_ANYG(c)) { /* 11g basic rates: 1, 2, 5.5, 11, 6, 12, 24Mbps */ ural_write(sc, RAL_TXRX_CSR11, 0x15f); + } else { + /* 11b basic rates: 1, 2Mbps */ + ural_write(sc, RAL_TXRX_CSR11, 0x3); } } @@ -2083,7 +2046,7 @@ ural_set_macaddr(struct ural_softc *sc, uint8_t *addr) static void ural_update_promisc(struct ural_softc *sc) { - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; tmp = ural_read(sc, RAL_TXRX_CSR2); @@ -2116,7 +2079,8 @@ ural_get_rf(int rev) static void ural_read_eeprom(struct ural_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint16_t val; ural_eeprom_read(sc, RAL_EEPROM_CONFIG0, &val, 2); @@ -2222,12 +2186,11 @@ ural_set_rxantenna(struct ural_softc *sc, int antenna) } static void -ural_init(void *priv) +ural_init_locked(struct ural_softc *sc) { #define N(a) (sizeof (a) / sizeof ((a)[0])) - struct ural_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ural_rx_data *data; uint16_t tmp; usbd_status error; @@ -2251,8 +2214,8 @@ ural_init(void *priv) DELAY(1000); } if (ntries == 100) { - printf("%s: timeout waiting for BBP/RF to wakeup\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, + "timeout waiting for BBP/RF to wakeup\n"); goto fail; } @@ -2281,8 +2244,7 @@ ural_init(void *priv) */ sc->amrr_xfer = usbd_alloc_xfer(sc->sc_udev); if (sc->amrr_xfer == NULL) { - printf("%s: could not allocate AMRR xfer\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not allocate AMRR xfer\n"); goto fail; } @@ -2292,16 +2254,16 @@ ural_init(void *priv) error = usbd_open_pipe(sc->sc_iface, sc->sc_tx_no, USBD_EXCLUSIVE_USE, &sc->sc_tx_pipeh); if (error != 0) { - printf("%s: could not open Tx pipe: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not open Tx pipe: %s\n", + usbd_errstr(error)); goto fail; } error = usbd_open_pipe(sc->sc_iface, sc->sc_rx_no, USBD_EXCLUSIVE_USE, &sc->sc_rx_pipeh); if (error != 0) { - printf("%s: could not open Rx pipe: %s\n", - device_get_nameunit(sc->sc_dev), usbd_errstr(error)); + device_printf(sc->sc_dev, "could not open Rx pipe: %s\n", + usbd_errstr(error)); goto fail; } @@ -2310,15 +2272,13 @@ ural_init(void *priv) */ error = ural_alloc_tx_list(sc); if (error != 0) { - printf("%s: could not allocate Tx list\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not allocate Tx list\n"); goto fail; } error = ural_alloc_rx_list(sc); if (error != 0) { - printf("%s: could not allocate Rx list\n", - device_get_nameunit(sc->sc_dev)); + device_printf(sc->sc_dev, "could not allocate Rx list\n"); goto fail; } @@ -2346,13 +2306,6 @@ ural_init(void *priv) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; - - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - return; fail: ural_stop(sc); @@ -2360,17 +2313,29 @@ fail: ural_stop(sc); } static void +ural_init(void *priv) +{ + struct ural_softc *sc = priv; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + + RAL_LOCK(sc); + ural_init_locked(sc); + RAL_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void ural_stop(void *priv) { struct ural_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; sc->sc_tx_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); - /* disable Rx */ ural_write(sc, RAL_TXRX_CSR2, RAL_DISABLE_RX); @@ -2420,9 +2385,6 @@ ural_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, return EIO; } - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m); - ifp->if_opackets++; if (params == NULL) { @@ -2453,27 +2415,22 @@ bad: static void ural_amrr_start(struct ural_softc *sc, struct ieee80211_node *ni) { - int i; + struct ieee80211vap *vap = ni->ni_vap; + struct ural_vap *uvp = URAL_VAP(vap); /* clear statistic registers (STA_CSR0 to STA_CSR10) */ ural_read_multi(sc, RAL_STA_CSR0, sc->sta, sizeof sc->sta); - ieee80211_amrr_node_init(&sc->amrr, &sc->amn); - - /* set rate to some reasonable initial value */ - for (i = ni->ni_rates.rs_nrates - 1; - i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; - i--); - - ni->ni_txrate = i; + ieee80211_amrr_node_init(&uvp->amrr, &URAL_NODE(ni)->amn, ni); - callout_reset(&sc->amrr_ch, hz, ural_amrr_timeout, sc); + callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap); } static void ural_amrr_timeout(void *arg) { - struct ural_softc *sc = (struct ural_softc *)arg; + struct ieee80211vap *vap = arg; + struct ural_softc *sc = vap->iv_ic->ic_ifp->if_softc; usb_device_request_t req; /* @@ -2485,7 +2442,7 @@ ural_amrr_timeout(void *arg) USETW(req.wIndex, RAL_STA_CSR0); USETW(req.wLength, sizeof sc->sta); - usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, sc, + usbd_setup_default_xfer(sc->amrr_xfer, sc->sc_udev, vap, USBD_DEFAULT_TIMEOUT, &req, sc->sta, sizeof sc->sta, 0, ural_amrr_update); (void)usbd_transfer(sc->amrr_xfer); @@ -2495,8 +2452,12 @@ static void ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { - struct ural_softc *sc = (struct ural_softc *)priv; - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ieee80211vap *vap = priv; + struct ural_vap *uvp = URAL_VAP(vap); + struct ifnet *ifp = vap->iv_ic->ic_ifp; + struct ural_softc *sc = ifp->if_softc; + struct ieee80211_node *ni = vap->iv_bss; + int ok, fail; if (status != USBD_NORMAL_COMPLETION) { device_printf(sc->sc_dev, "could not retrieve Tx statistics - " @@ -2504,19 +2465,15 @@ ural_amrr_update(usbd_xfer_handle xfer, usbd_private_handle priv, return; } - /* count TX retry-fail as Tx errors */ - ifp->if_oerrors += sc->sta[9]; - - sc->amn.amn_retrycnt = - sc->sta[7] + /* TX one-retry ok count */ - sc->sta[8] + /* TX more-retry ok count */ - sc->sta[9]; /* TX retry-fail count */ + ok = sc->sta[7] + /* TX ok w/o retry */ + sc->sta[8]; /* TX ok w/ retry */ + fail = sc->sta[9]; /* TX retry-fail count */ - sc->amn.amn_txcnt = - sc->amn.amn_retrycnt + - sc->sta[6]; /* TX no-retry ok count */ + ieee80211_amrr_tx_update(&URAL_NODE(ni)->amn, + ok+fail, ok, sc->sta[8] + fail); + (void) ieee80211_amrr_choose(ni, &URAL_NODE(ni)->amn); - ieee80211_amrr_choose(&sc->amrr, sc->sc_ic.ic_bss, &sc->amn); + ifp->if_oerrors += fail; /* count TX retry-fail as Tx errors */ - callout_reset(&sc->amrr_ch, hz, ural_amrr_timeout, sc); + callout_reset(&uvp->amrr_ch, hz, ural_amrr_timeout, vap); } diff --git a/sys/dev/usb/if_uralvar.h b/sys/dev/usb/if_uralvar.h index 665b05b..39aef9e 100644 --- a/sys/dev/usb/if_uralvar.h +++ b/sys/dev/usb/if_uralvar.h @@ -18,7 +18,7 @@ */ #define RAL_RX_LIST_COUNT 1 -#define RAL_TX_LIST_COUNT 1 +#define RAL_TX_LIST_COUNT 8 #define URAL_SCAN_START 1 #define URAL_SCAN_END 2 @@ -74,15 +74,31 @@ struct ural_rx_data { struct mbuf *m; }; +struct ural_node { + struct ieee80211_node ni; + struct ieee80211_amrr_node amn; +}; +#define URAL_NODE(ni) ((struct ural_node *)(ni)) + +struct ural_vap { + struct ieee80211vap vap; + struct ieee80211_beacon_offsets bo; + struct ieee80211_amrr amrr; + struct callout amrr_ch; + + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define URAL_VAP(vap) ((struct ural_vap *)(vap)) + struct ural_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); device_t sc_dev; usbd_device_handle sc_udev; usbd_interface_handle sc_iface; + const struct ieee80211_rate_table *sc_rates; + int sc_rx_no; int sc_tx_no; @@ -100,19 +116,14 @@ struct ural_softc { struct usb_task sc_task; struct usb_task sc_scantask; - struct ieee80211_amrr amrr; - struct ieee80211_amrr_node amn; - struct ural_rx_data rx_data[RAL_RX_LIST_COUNT]; struct ural_tx_data tx_data[RAL_TX_LIST_COUNT]; int tx_queued; - - struct ieee80211_beacon_offsets sc_bo; + int tx_cur; struct mtx sc_mtx; struct callout watchdog_ch; - struct callout amrr_ch; int sc_tx_timer; uint16_t sta[11]; @@ -130,20 +141,10 @@ struct ural_softc { int tx_ant; int nb_ant; - struct bpf_if *sc_drvbpf; - - union { - struct ural_rx_radiotap_header th; - uint8_t pad[64]; - } sc_rxtapu; -#define sc_rxtap sc_rxtapu.th + struct ural_rx_radiotap_header sc_rxtap; int sc_rxtap_len; - union { - struct ural_tx_radiotap_header th; - uint8_t pad[64]; - } sc_txtapu; -#define sc_txtap sc_txtapu.th + struct ural_tx_radiotap_header sc_txtap; int sc_txtap_len; }; diff --git a/sys/dev/usb/if_zyd.c b/sys/dev/usb/if_zyd.c index 509d33c..bf51177 100644 --- a/sys/dev/usb/if_zyd.c +++ b/sys/dev/usb/if_zyd.c @@ -47,9 +47,8 @@ #include #include +#include #include -#include -#include #include #include @@ -67,10 +66,7 @@ #include #include -#ifdef USB_DEBUG #define ZYD_DEBUG -#endif - #ifdef ZYD_DEBUG #define DPRINTF(x) do { if (zyddebug > 0) printf x; } while (0) #define DPRINTFN(n, x) do { if (zyddebug > (n)) printf x; } while (0) @@ -154,6 +150,11 @@ static device_probe_t zyd_match; static device_attach_t zyd_attach; static device_detach_t zyd_detach; +static struct ieee80211vap *zyd_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void zyd_vap_delete(struct ieee80211vap *); static int zyd_attachhook(struct zyd_softc *); static int zyd_complete_attach(struct zyd_softc *); static int zyd_open_pipes(struct zyd_softc *); @@ -163,9 +164,8 @@ static void zyd_free_tx_list(struct zyd_softc *); static int zyd_alloc_rx_list(struct zyd_softc *); static void zyd_free_rx_list(struct zyd_softc *); static struct ieee80211_node *zyd_node_alloc(struct ieee80211_node_table *); -static int zyd_media_change(struct ifnet *); static void zyd_task(void *); -static int zyd_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int zyd_newstate(struct ieee80211vap *, enum ieee80211_state, int); static int zyd_cmd(struct zyd_softc *, uint16_t, const void *, int, void *, int, u_int); static int zyd_read16(struct zyd_softc *, uint16_t, uint16_t *); @@ -205,11 +205,11 @@ static int zyd_set_macaddr(struct zyd_softc *, const uint8_t *); static int zyd_set_bssid(struct zyd_softc *, const uint8_t *); static int zyd_switch_radio(struct zyd_softc *, int); static void zyd_set_led(struct zyd_softc *, int, int); -static void zyd_set_multi(struct zyd_softc *); +static void zyd_set_multi(void *); +static void zyd_update_mcast(struct ifnet *); static int zyd_set_rxfilter(struct zyd_softc *); static void zyd_set_chan(struct zyd_softc *, struct ieee80211_channel *); static int zyd_set_beacon_interval(struct zyd_softc *, int); -static uint8_t zyd_plcp_signal(int); static void zyd_intr(usbd_xfer_handle, usbd_private_handle, usbd_status); static void zyd_rx_data(struct zyd_softc *, const uint8_t *, uint16_t); static void zyd_rxeof(usbd_xfer_handle, usbd_private_handle, usbd_status); @@ -219,13 +219,14 @@ static int zyd_tx_mgt(struct zyd_softc *, struct mbuf *, static int zyd_tx_data(struct zyd_softc *, struct mbuf *, struct ieee80211_node *); static void zyd_start(struct ifnet *); +static int zyd_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); static void zyd_watchdog(void *); static int zyd_ioctl(struct ifnet *, u_long, caddr_t); +static void zyd_init_locked(struct zyd_softc *); static void zyd_init(void *); static void zyd_stop(struct zyd_softc *, int); static int zyd_loadfirmware(struct zyd_softc *, u_char *, size_t); -static void zyd_iter_func(void *, struct ieee80211_node *); -static void zyd_amrr_timeout(void *); static void zyd_newassoc(struct ieee80211_node *, int); static void zyd_scantask(void *); static void zyd_scan_start(struct ieee80211com *); @@ -282,7 +283,7 @@ zyd_attach(device_t dev) sc->sc_dev = dev; - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); return ENXIO; @@ -325,18 +326,18 @@ bad: static int zyd_complete_attach(struct zyd_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; usbd_status error; - int bands; + uint8_t bands; mtx_init(&sc->sc_mtx, device_get_nameunit(sc->sc_dev), MTX_NETWORK_LOCK, MTX_DEF | MTX_RECURSE); usb_init_task(&sc->sc_scantask, zyd_scantask, sc); usb_init_task(&sc->sc_task, zyd_task, sc); + usb_init_task(&sc->sc_mcasttask, zyd_set_multi, sc); - callout_init(&sc->sc_amrr_ch, 0); callout_init(&sc->sc_watchdog_ch, 0); error = usbd_set_config_no(sc->sc_udev, ZYD_CONFIG_NO, 1); @@ -381,10 +382,11 @@ zyd_complete_attach(struct zyd_softc *sc) sc->fw_rev >> 8, sc->fw_rev & 0xff, zyd_rf_name(sc->rf_rev), sc->pa_rev, ether_sprintf(ic->ic_myaddr)); + IEEE80211_ADDR_COPY(sc->sc_bssid, ic->ic_myaddr); + ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; + ic->ic_opmode = IEEE80211_M_STA; /* set device capabilities */ ic->ic_caps = @@ -398,29 +400,22 @@ zyd_complete_attach(struct zyd_softc *sc) bands = 0; setbit(&bands, IEEE80211_MODE_11B); setbit(&bands, IEEE80211_MODE_11G); - ieee80211_init_channels(ic, 0, CTRY_DEFAULT, bands, 0, 1); + ieee80211_init_channels(ic, NULL, &bands); ieee80211_ifattach(ic); - ic->ic_node_alloc = zyd_node_alloc; ic->ic_newassoc = zyd_newassoc; - - /* enable s/w bmiss handling in sta mode */ - ic->ic_flags_ext |= IEEE80211_FEXT_SWBMISS; + ic->ic_raw_xmit = zyd_raw_xmit; + ic->ic_node_alloc = zyd_node_alloc; ic->ic_scan_start = zyd_scan_start; ic->ic_scan_end = zyd_scan_end; ic->ic_set_channel = zyd_set_channel; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = zyd_newstate; - ieee80211_media_init(ic, zyd_media_change, ieee80211_media_status); - ieee80211_amrr_init(&sc->amrr, ic, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); + ic->ic_vap_create = zyd_vap_create; + ic->ic_vap_delete = zyd_vap_delete; + ic->ic_update_mcast = zyd_update_mcast; - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->sc_txtap)); sc->sc_rxtap_len = sizeof(sc->sc_rxtap); sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); @@ -447,8 +442,8 @@ static int zyd_detach(device_t dev) { struct zyd_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; if (!device_is_attached(dev)) return 0; @@ -457,17 +452,16 @@ zyd_detach(device_t dev) ifp->if_flags &= ~IFF_UP; zyd_stop(sc, 1); + bpfdetach(ifp); + ieee80211_ifdetach(ic); + usb_rem_task(sc->sc_udev, &sc->sc_scantask); usb_rem_task(sc->sc_udev, &sc->sc_task); - callout_stop(&sc->sc_amrr_ch); callout_stop(&sc->sc_watchdog_ch); zyd_close_pipes(sc); - bpfdetach(ifp); - ieee80211_ifdetach(ic); if_free(ifp); - mtx_destroy(&sc->sc_mtx); usbd_add_drv_event(USB_EVENT_DRIVER_DETACH, sc->sc_udev, sc->sc_dev); @@ -475,6 +469,51 @@ zyd_detach(device_t dev) return 0; } +static struct ieee80211vap * +zyd_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct zyd_vap *zvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + zvp = (struct zyd_vap *) malloc(sizeof(struct zyd_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (zvp == NULL) + return NULL; + vap = &zvp->vap; + /* enable s/w bmiss handling for sta mode */ + ieee80211_vap_setup(ic, vap, name, unit, opmode, + flags | IEEE80211_CLONE_NOBEACONS, bssid, mac); + + /* override state transition machine */ + zvp->newstate = vap->iv_newstate; + vap->iv_newstate = zyd_newstate; + + ieee80211_amrr_init(&zvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 1000 /* 1 sec */); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +zyd_vap_delete(struct ieee80211vap *vap) +{ + struct zyd_vap *zvp = ZYD_VAP(vap); + + ieee80211_amrr_cleanup(&zvp->amrr); + ieee80211_vap_detach(vap); + free(zvp, M_80211_VAP); +} + static int zyd_open_pipes(struct zyd_softc *sc) { @@ -666,86 +705,70 @@ zyd_node_alloc(struct ieee80211_node_table *nt __unused) return zn != NULL ? &zn->ni : NULL; } -static int -zyd_media_change(struct ifnet *ifp) -{ - struct zyd_softc *sc = ifp->if_softc; - int error; - - error = ieee80211_media_change(ifp); - if (error != ENETRESET) - return error; - - if ((ifp->if_flags & IFF_UP) == IFF_UP && - (ifp->if_drv_flags & IFF_DRV_RUNNING) == IFF_DRV_RUNNING) - zyd_init(sc); - - return 0; -} - static void zyd_task(void *arg) { struct zyd_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - enum ieee80211_state ostate; - - ostate = ic->ic_state; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct zyd_vap *zvp = ZYD_VAP(vap); switch (sc->sc_state) { case IEEE80211_S_RUN: { - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211_node *ni = vap->iv_bss; zyd_set_chan(sc, ic->ic_curchan); - if (ic->ic_opmode != IEEE80211_M_MONITOR) { + if (vap->iv_opmode != IEEE80211_M_MONITOR) { /* turn link LED on */ zyd_set_led(sc, ZYD_LED1, 1); /* make data LED blink upon Tx */ zyd_write32(sc, sc->fwbase + ZYD_FW_LINK_STATUS, 1); - zyd_set_bssid(sc, ni->ni_bssid); + IEEE80211_ADDR_COPY(sc->sc_bssid, ni->ni_bssid); + zyd_set_bssid(sc, sc->sc_bssid); } - if (ic->ic_opmode == IEEE80211_M_STA) { + if (vap->iv_opmode == IEEE80211_M_STA) { /* fake a join to init the tx rate */ zyd_newassoc(ni, 1); } - - /* start automatic rate control timer */ - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) - callout_reset(&sc->sc_amrr_ch, hz, - zyd_amrr_timeout, sc); - break; } default: break; } - sc->sc_newstate(ic, sc->sc_state, sc->sc_arg); + IEEE80211_LOCK(ic); + zvp->newstate(vap, sc->sc_state, sc->sc_arg); + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, sc->sc_state, sc->sc_arg); + IEEE80211_UNLOCK(ic); } static int -zyd_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +zyd_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct zyd_vap *zvp = ZYD_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct zyd_softc *sc = ic->ic_ifp->if_softc; usb_rem_task(sc->sc_udev, &sc->sc_task); - callout_stop(&sc->sc_amrr_ch); /* do it in a process context */ sc->sc_state = nstate; sc->sc_arg = arg; - if (nstate == IEEE80211_S_INIT) - sc->sc_newstate(ic, nstate, arg); - else + if (nstate == IEEE80211_S_INIT) { + zvp->newstate(vap, nstate, arg); + return 0; + } else { usb_add_task(sc->sc_udev, &sc->sc_task, USB_TASKQ_DRIVER); - - return 0; + return EINPROGRESS; + } } static int @@ -1582,7 +1605,8 @@ fail: return error; static int zyd_read_eeprom(struct zyd_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t tmp; uint16_t val; int i; @@ -1607,6 +1631,7 @@ zyd_read_eeprom(struct zyd_softc *sc) (void)zyd_read32(sc, ZYD_EEPROM_SUBID, &tmp); sc->regdomain = tmp >> 16; DPRINTF(("regulatory domain %x\n", sc->regdomain)); + /* XXX propagate to net80211 after mapping to SKU */ /* read Tx power calibration tables */ for (i = 0; i < 7; i++) { @@ -1687,10 +1712,11 @@ zyd_set_led(struct zyd_softc *sc, int which, int on) } static void -zyd_set_multi(struct zyd_softc *sc) +zyd_set_multi(void *arg) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct zyd_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ifmultiaddr *ifma; uint32_t low, high; uint8_t v; @@ -1725,12 +1751,22 @@ zyd_set_multi(struct zyd_softc *sc) zyd_write32(sc, ZYD_MAC_GHTBH, high); } +static void +zyd_update_mcast(struct ifnet *ifp) +{ + struct zyd_softc *sc = ifp->if_softc; + + usb_add_task(sc->sc_udev, &sc->sc_mcasttask, USB_TASKQ_DRIVER); +} + static int zyd_set_rxfilter(struct zyd_softc *sc) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; uint32_t rxfilter; - switch (sc->sc_ic.ic_opmode) { + switch (ic->ic_opmode) { case IEEE80211_M_STA: rxfilter = ZYD_FILTER_BSS; break; @@ -1751,7 +1787,8 @@ zyd_set_rxfilter(struct zyd_softc *sc) static void zyd_set_chan(struct zyd_softc *sc, struct ieee80211_channel *c) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct zyd_rf *rf = &sc->sc_rf; uint32_t tmp; u_int chan; @@ -1809,31 +1846,6 @@ zyd_set_beacon_interval(struct zyd_softc *sc, int bintval) return 0; } -static uint8_t -zyd_plcp_signal(int rate) -{ - switch (rate) { - /* CCK rates (returned values are device-dependent) */ - case 2: return 0x0; - case 4: return 0x1; - case 11: return 0x2; - case 22: return 0x3; - - /* OFDM rates (cf IEEE Std 802.11a-1999, pp. 14 Table 80) */ - case 12: return 0xb; - case 18: return 0xf; - case 24: return 0xa; - case 36: return 0xe; - case 48: return 0x9; - case 72: return 0xd; - case 96: return 0x8; - case 108: return 0xc; - - /* unsupported rates (should not get there) */ - default: return 0xff; - } -} - static void zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) { @@ -1857,8 +1869,9 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) if (le16toh(cmd->code) == ZYD_NOTIF_RETRYSTATUS) { struct zyd_notif_retry *retry = (struct zyd_notif_retry *)cmd->data; - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); struct ieee80211_node *ni; DPRINTF(("retry intr: rate=0x%x addr=%s count=%d (0x%x)\n", @@ -1870,15 +1883,12 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) * retry statistics. In BSS mode, this node is the AP we're * associated to so no lookup is actually needed. */ - if (ic->ic_opmode != IEEE80211_M_STA) { - ni = ieee80211_find_node(&ic->ic_sta, retry->macaddr); - if (ni == NULL) - return; /* just ignore */ - } else - ni = ic->ic_bss; - - ((struct zyd_node *)ni)->amn.amn_retrycnt++; - + ni = ieee80211_find_txnode(vap, retry->macaddr); + if (ni != NULL) { + ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, + IEEE80211_AMRR_FAILURE, 1); + ieee80211_free_node(ni); + } if (le16toh(retry->count) & 0x100) ifp->if_oerrors++; /* too many retries */ } else if (le16toh(cmd->code) == ZYD_NOTIF_IORD) { @@ -1918,30 +1928,16 @@ zyd_intr(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) } } -static __inline uint8_t -zyd_plcp2ieee(int signal, int isofdm) -{ - if (isofdm) { - static const uint8_t ofdmrates[16] = - { 0, 0, 0, 0, 0, 0, 0, 96, 48, 24, 12, 108, 72, 36, 18 }; - return ofdmrates[signal & 0xf]; - } else { - static const uint8_t cckrates[16] = - { 0, 0, 0, 0, 4, 0, 0, 11, 0, 0, 2, 0, 0, 0, 22, 0 }; - return cckrates[signal & 0xf]; - } -} - static void zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) { - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_node *ni; const struct zyd_plcphdr *plcp; const struct zyd_rx_stat *stat; struct mbuf *m; - int rlen; + int rlen, rssi, nf; if (len < ZYD_MIN_FRAGSZ) { DPRINTF(("%s: frame too short (length=%d)\n", @@ -1980,7 +1976,7 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) m->m_pkthdr.len = m->m_len = rlen; bcopy((const uint8_t *)(plcp + 1), mtod(m, uint8_t *), rlen); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct zyd_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; @@ -1989,20 +1985,23 @@ zyd_rx_data(struct zyd_softc *sc, const uint8_t *buf, uint16_t len) /* XXX toss, no way to express errors */ if (stat->flags & ZYD_RX_DECRYPTERR) tap->wr_flags |= IEEE80211_RADIOTAP_F_BADFCS; - tap->wr_rate = - zyd_plcp2ieee(plcp->signal, stat->flags & ZYD_RX_OFDM); + tap->wr_rate = ieee80211_plcp2rate(plcp->signal, + stat->flags & ZYD_RX_OFDM); tap->wr_antsignal = stat->rssi + -95; tap->wr_antnoise = -95; /* XXX */ - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } - ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); - ieee80211_input(ic, m, ni, - stat->rssi > 63 ? 127 : 2 * stat->rssi, -95/*XXX*/, 0); + rssi = stat->rssi > 63 ? 127 : 2 * stat->rssi; + nf = -95; /* XXX */ - /* node is no longer needed */ - ieee80211_free_node(ni); + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + (void) ieee80211_input(ni, m, rssi, nf, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, nf, 0); } static void @@ -2067,7 +2066,8 @@ skip: /* setup a new transfer */ static int zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; struct ifnet *ifp = sc->sc_ifp; struct zyd_tx_desc *desc; struct zyd_tx_data *data; @@ -2085,7 +2085,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) wh = mtod(m0, struct ieee80211_frame *); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -2106,7 +2106,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->flags = ZYD_TX_FLAG_BACKOFF; if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { /* multicast frames are not sent at OFDM rates in 802.11b/g */ - if (totlen > ic->ic_rtsthreshold) { + if (totlen > vap->iv_rtsthreshold) { desc->flags |= ZYD_TX_FLAG_RTS; } else if (ZYD_RATE_IS_OFDM(rate) && (ic->ic_flags & IEEE80211_F_USEPROT)) { @@ -2123,7 +2123,7 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); - desc->phy = zyd_plcp_signal(rate); + desc->phy = ieee80211_rate2plcp(rate); if (ZYD_RATE_IS_OFDM(rate)) { desc->phy |= ZYD_TX_PHY_OFDM; if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) @@ -2145,13 +2145,13 @@ zyd_tx_mgt(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->plcp_service |= ZYD_PLCP_LENGEXT; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct zyd_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_rate = rate; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } m_copydata(m0, 0, m0->m_pkthdr.len, @@ -2200,7 +2200,8 @@ zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) ni = data->ni; /* update rate control statistics */ - ((struct zyd_node *)ni)->amn.amn_txcnt++; + ieee80211_amrr_tx_complete(&ZYD_NODE(ni)->amn, + IEEE80211_AMRR_SUCCESS, 0); /* * Do any tx complete callback. Note this must @@ -2227,11 +2228,13 @@ zyd_txeof(usbd_xfer_handle xfer, usbd_private_handle priv, usbd_status status) static int zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ieee80211com *ic = ni->ni_ic; struct ifnet *ifp = sc->sc_ifp; struct zyd_tx_desc *desc; struct zyd_tx_data *data; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; int xferlen, totlen, rate; uint16_t pktlen; @@ -2242,17 +2245,19 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc = (struct zyd_tx_desc *)data->buf; desc->flags = ZYD_TX_FLAG_BACKOFF; + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; if (IEEE80211_IS_MULTICAST(wh->i_addr1)) { - rate = ic->ic_mcast_rate; + rate = tp->mcastrate; desc->flags |= ZYD_TX_FLAG_MULTICAST; - } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) - rate = ic->ic_fixed_rate; - else - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - rate &= IEEE80211_RATE_VAL; + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; + } else { + (void) ieee80211_amrr_choose(ni, &ZYD_NODE(ni)->amn); + rate = ni->ni_txrate; + } if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -2273,7 +2278,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) if (!IEEE80211_IS_MULTICAST(wh->i_addr1)) { /* multicast frames are not sent at OFDM rates in 802.11b/g */ - if (totlen > ic->ic_rtsthreshold) { + if (totlen > vap->iv_rtsthreshold) { desc->flags |= ZYD_TX_FLAG_RTS; } else if (ZYD_RATE_IS_OFDM(rate) && (ic->ic_flags & IEEE80211_F_USEPROT)) { @@ -2289,7 +2294,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) (IEEE80211_FC0_TYPE_CTL | IEEE80211_FC0_SUBTYPE_PS_POLL)) desc->flags |= ZYD_TX_FLAG_TYPE(ZYD_TX_TYPE_PS_POLL); - desc->phy = zyd_plcp_signal(rate); + desc->phy = ieee80211_rate2plcp(rate); if (ZYD_RATE_IS_OFDM(rate)) { desc->phy |= ZYD_TX_PHY_OFDM; if (IEEE80211_IS_CHAN_5GHZ(ic->ic_curchan)) @@ -2311,7 +2316,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) desc->plcp_service |= ZYD_PLCP_LENGEXT; } - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct zyd_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; @@ -2319,7 +2324,7 @@ zyd_tx_data(struct zyd_softc *sc, struct mbuf *m0, struct ieee80211_node *ni) tap->wt_chan_freq = htole16(ic->ic_curchan->ic_freq); tap->wt_chan_flags = htole16(ic->ic_curchan->ic_flags); - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } m_copydata(m0, 0, m0->m_pkthdr.len, @@ -2348,81 +2353,81 @@ static void zyd_start(struct ifnet *ifp) { struct zyd_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct ether_header *eh; struct ieee80211_node *ni; - struct mbuf *m0; + struct mbuf *m; for (;;) { - IF_POLL(&ic->ic_mgtq, m0); - if (m0 != NULL) { - if (sc->tx_queued >= ZYD_TX_LIST_CNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IF_DEQUEUE(&ic->ic_mgtq, m0); - - ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - if (zyd_tx_mgt(sc, m0, ni) != 0) - break; - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; - IFQ_POLL(&ifp->if_snd, m0); - if (m0 == NULL) - break; - if (sc->tx_queued >= ZYD_TX_LIST_CNT) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IFQ_DEQUEUE(&ifp->if_snd, m0); - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - if (m0->m_len < sizeof(struct ether_header) && - !(m0 = m_pullup(m0, sizeof(struct ether_header)))) - continue; - - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - if (bpf_peers_present(ifp->if_bpf)) - bpf_mtap(ifp->if_bpf, m0); - if ((m0 = ieee80211_encap(ic, m0, ni)) == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - if (zyd_tx_data(sc, m0, ni) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + if (m == NULL) + break; + if (sc->tx_queued >= ZYD_TX_LIST_CNT) { + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + ni = (struct ieee80211_node *)m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; + } + if (zyd_tx_data(sc, m, ni) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; } sc->tx_timer = 5; - ic->ic_lastdata = ticks; callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); } } +static int +zyd_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; + struct zyd_softc *sc = ifp->if_softc; + + /* prevent management frames from being sent if we're not ready */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + m_freem(m); + ieee80211_free_node(ni); + return ENETDOWN; + } + if (sc->tx_queued >= ZYD_TX_LIST_CNT) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + m_freem(m); + ieee80211_free_node(ni); + return ENOBUFS; /* XXX */ + } + + ifp->if_opackets++; + + /* + * Legacy path; interpret frame contents to decide + * precisely how to send the frame. + * XXX raw path + */ + if (zyd_tx_mgt(sc, m, ni) != 0) + goto bad; + sc->tx_timer = 5; + callout_reset(&sc->sc_watchdog_ch, hz, zyd_watchdog, sc); + + return 0; +bad: + ifp->if_oerrors++; + ieee80211_free_node(ni); + return EIO; /* XXX */ +} + static void zyd_watchdog(void *arg) { struct zyd_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; if (sc->tx_timer > 0) { if (--sc->tx_timer == 0) { @@ -2439,11 +2444,11 @@ static int zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct zyd_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; ZYD_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: if (ifp->if_flags & IFF_UP) { @@ -2451,43 +2456,36 @@ zyd_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) if ((ifp->if_flags ^ sc->sc_if_flags) & (IFF_ALLMULTI | IFF_PROMISC)) zyd_set_multi(sc); - } else - zyd_init(sc); + } else { + zyd_init_locked(sc); + startall = 1; + } } else { if (ifp->if_drv_flags & IFF_DRV_RUNNING) zyd_stop(sc, 1); } sc->sc_if_flags = ifp->if_flags; break; - - case SIOCADDMULTI: - case SIOCDELMULTI: - if (ifp->if_drv_flags & IFF_DRV_RUNNING) - zyd_set_multi(sc); + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); break; - default: - error = ieee80211_ioctl(ic, cmd, data); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) == IFF_UP && - (ifp->if_drv_flags & IFF_DRV_RUNNING) == IFF_DRV_RUNNING) - zyd_init(sc); - error = 0; + error = ether_ioctl(ifp, cmd, data); + break; } - ZYD_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } static void -zyd_init(void *priv) +zyd_init_locked(struct zyd_softc *sc) { - struct zyd_softc *sc = priv; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int i, error; zyd_stop(sc, 0); @@ -2569,13 +2567,6 @@ zyd_init(void *priv) ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; ifp->if_drv_flags |= IFF_DRV_RUNNING; - - if (ic->ic_opmode != IEEE80211_M_MONITOR) { - if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - } else - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - return; fail: zyd_stop(sc, 1); @@ -2583,12 +2574,24 @@ fail: zyd_stop(sc, 1); } static void -zyd_stop(struct zyd_softc *sc, int disable) +zyd_init(void *priv) { + struct zyd_softc *sc = priv; struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); /* free all nodes */ + ZYD_LOCK(sc); + zyd_init_locked(sc); + ZYD_UNLOCK(sc); + + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vap's */ +} + +static void +zyd_stop(struct zyd_softc *sc, int disable) +{ + struct ifnet *ifp = sc->sc_ifp; sc->tx_timer = 0; ifp->if_drv_flags &= ~(IFF_DRV_RUNNING | IFF_DRV_OACTIVE); @@ -2661,43 +2664,11 @@ zyd_loadfirmware(struct zyd_softc *sc, u_char *fw, size_t size) } static void -zyd_iter_func(void *arg, struct ieee80211_node *ni) -{ - struct zyd_softc *sc = arg; - struct zyd_node *zn = (struct zyd_node *)ni; - - ieee80211_amrr_choose(&sc->amrr, ni, &zn->amn); -} - -static void -zyd_amrr_timeout(void *arg) -{ - struct zyd_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - - ZYD_LOCK(sc); - if (ic->ic_opmode == IEEE80211_M_STA) - zyd_iter_func(sc, ic->ic_bss); - else - ieee80211_iterate_nodes(&ic->ic_sta, zyd_iter_func, sc); - ZYD_UNLOCK(sc); - - callout_reset(&sc->sc_amrr_ch, hz, zyd_amrr_timeout, sc); -} - -static void zyd_newassoc(struct ieee80211_node *ni, int isnew) { - struct zyd_softc *sc = ni->ni_ic->ic_ifp->if_softc; - int i; - - ieee80211_amrr_node_init(&sc->amrr, &((struct zyd_node *)ni)->amn); + struct ieee80211vap *vap = ni->ni_vap; - /* set rate to some reasonable initial value */ - for (i = ni->ni_rates.rs_nrates - 1; - i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; - i--); - ni->ni_txrate = i; + ieee80211_amrr_node_init(&ZYD_VAP(vap)->amrr, &ZYD_NODE(ni)->amn, ni); } static void @@ -2740,18 +2711,20 @@ static void zyd_scantask(void *arg) { struct zyd_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; ZYD_LOCK(sc); switch (sc->sc_scan_action) { case ZYD_SCAN_START: + /* want broadcast address while scanning */ zyd_set_bssid(sc, ifp->if_broadcastaddr); break; case ZYD_SCAN_END: - zyd_set_bssid(sc, ic->ic_bss->ni_bssid); + /* restore previous bssid */ + zyd_set_bssid(sc, sc->sc_bssid); break; case ZYD_SET_CHANNEL: diff --git a/sys/dev/usb/if_zydreg.h b/sys/dev/usb/if_zydreg.h index fc736ae..4d9c8fd 100644 --- a/sys/dev/usb/if_zydreg.h +++ b/sys/dev/usb/if_zydreg.h @@ -1122,6 +1122,7 @@ struct zyd_node { struct ieee80211_node ni; /* must be the first */ struct ieee80211_amrr_node amn; }; +#define ZYD_NODE(ni) ((struct zyd_node *)(ni)) struct zyd_rx_radiotap_header { struct ieee80211_radiotap_header wr_ihdr; @@ -1173,12 +1174,18 @@ struct rq { STAILQ_ENTRY(rq) rq; }; +struct zyd_vap { + struct ieee80211vap vap; + int (*newstate)(struct ieee80211vap *, + enum ieee80211_state, int); + struct callout amrr_ch; + struct ieee80211_amrr amrr; +}; +#define ZYD_VAP(vap) ((struct zyd_vap *)(vap)) + struct zyd_softc { device_t sc_dev; struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); struct zyd_rf sc_rf; struct usb_task sc_task; @@ -1187,22 +1194,20 @@ struct zyd_softc { #define ZYD_SCAN_START 0 #define ZYD_SCAN_END 1 #define ZYD_SET_CHANNEL 2 + struct usb_task sc_mcasttask; usbd_device_handle sc_udev; usbd_interface_handle sc_iface; int sc_flags; int sc_if_flags; #define ZD1211_FWLOADED (1 << 0) - + uint8_t sc_bssid[IEEE80211_ADDR_LEN]; enum ieee80211_state sc_state; int sc_arg; struct mtx sc_mtx; - struct callout sc_amrr_ch; struct callout sc_watchdog_ch; - struct ieee80211_amrr amrr; - STAILQ_HEAD(rqh, rq) sc_rqh; uint16_t fwbase; @@ -1233,8 +1238,6 @@ struct zyd_softc { int tx_timer; - struct bpf_if *sc_drvbpf; - struct zyd_rx_radiotap_header sc_rxtap; int sc_rxtap_len; diff --git a/sys/dev/wi/if_wavelan_ieee.h b/sys/dev/wi/if_wavelan_ieee.h index 0a04bed..0061e63 100644 --- a/sys/dev/wi/if_wavelan_ieee.h +++ b/sys/dev/wi/if_wavelan_ieee.h @@ -241,10 +241,13 @@ struct wi_counters { #define WI_RID_CNFAUTHMODE 0xFC2A #define WI_RID_ROAMING_MODE 0xFC2D #define WI_RID_OWN_BEACON_INT 0xFC33 /* beacon xmit time for BSS creation */ +#define WI_RID_ENH_SECURITY 0xFC43 /* enhanced security (AP mode) */ #define WI_RID_CNF_DBM_ADJUST 0xFC46 #define WI_RID_DBM_ADJUST 0xFC46 /* RSSI - WI_RID_DBM_ADJUST ~ dBm */ +#define WI_RID_WPA_DATA 0xFC48 /* WPA IE */ #define WI_RID_BASIC_RATE 0xFCB3 #define WI_RID_SUPPORT_RATE 0xFCB4 +#define WI_RID_WPA_HANDLING 0xFCBB /* WPA handling procedures */ /* * Network parameters, dynamic configuration entities diff --git a/sys/dev/wi/if_wi.c b/sys/dev/wi/if_wi.c index 9ff16a4..d750ab1 100644 --- a/sys/dev/wi/if_wi.c +++ b/sys/dev/wi/if_wi.c @@ -1,5 +1,3 @@ -/* $NetBSD: wi.c,v 1.109 2003/01/09 08:52:19 dyoung Exp $ */ - /*- * Copyright (c) 1997, 1998, 1999 * Bill Paul . All rights reserved. @@ -64,11 +62,8 @@ #include __FBSDID("$FreeBSD$"); -#define WI_HERMES_AUTOINC_WAR /* Work around data write autoinc bug. */ #define WI_HERMES_STATS_WAR /* Work around stats counter bug. */ -#define NBPFILTER 1 - #include #include #include @@ -83,6 +78,7 @@ __FBSDID("$FreeBSD$"); #include #include #include +#include #include #include @@ -112,33 +108,41 @@ __FBSDID("$FreeBSD$"); #include #include +static struct ieee80211vap *wi_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void wi_vap_delete(struct ieee80211vap *vap); +static void wi_stop_locked(struct wi_softc *sc, int disable); static void wi_start_locked(struct ifnet *); static void wi_start(struct ifnet *); static int wi_start_tx(struct ifnet *ifp, struct wi_frame *frmhdr, struct mbuf *m0); static int wi_raw_xmit(struct ieee80211_node *, struct mbuf *, const struct ieee80211_bpf_params *); -static int wi_reset(struct ifnet *); +static int wi_newstate_sta(struct ieee80211vap *, enum ieee80211_state, int); +static int wi_newstate_hostap(struct ieee80211vap *, enum ieee80211_state, int); +static void wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, + int subtype, int rssi, int noise, u_int32_t rstamp); +static int wi_reset(struct wi_softc *); static void wi_watchdog(void *); static int wi_ioctl(struct ifnet *, u_long, caddr_t); -static int wi_media_change(struct ifnet *); static void wi_media_status(struct ifnet *, struct ifmediareq *); static void wi_rx_intr(struct wi_softc *); static void wi_tx_intr(struct wi_softc *); static void wi_tx_ex_intr(struct wi_softc *); -static void wi_info_intr(struct wi_softc *); -static int wi_key_alloc(struct ieee80211com *, const struct ieee80211_key *, - ieee80211_keyix *, ieee80211_keyix *); +static void wi_status_connected(void *, int); +static void wi_status_disconnected(void *, int); +static void wi_status_oor(void *, int); +static void wi_status_assoc_failed(void *, int); +static void wi_info_intr(struct wi_softc *); -#if 0 -static int wi_get_cfg(struct ifnet *, u_long, caddr_t); -static int wi_set_cfg(struct ifnet *, u_long, caddr_t); -#endif -static int wi_write_txrate(struct wi_softc *); -static int wi_write_wep(struct wi_softc *); +static int wi_write_txrate(struct wi_softc *, struct ieee80211vap *); +static int wi_write_wep(struct wi_softc *, struct ieee80211vap *); static int wi_write_multi(struct wi_softc *); +static void wi_update_mcast(struct ifnet *); static int wi_alloc_fid(struct wi_softc *, int, int *); static void wi_read_nicid(struct wi_softc *); static int wi_write_ssid(struct wi_softc *, int, u_int8_t *, int); @@ -150,33 +154,11 @@ static int wi_write_bap(struct wi_softc *, int, int, void *, int); static int wi_mwrite_bap(struct wi_softc *, int, int, struct mbuf *, int); static int wi_read_rid(struct wi_softc *, int, void *, int *); static int wi_write_rid(struct wi_softc *, int, void *, int); - -static int wi_newstate(struct ieee80211com *, enum ieee80211_state, int); - -static int wi_scan_ap(struct wi_softc *, u_int16_t, u_int16_t); -static void wi_scan_result(struct wi_softc *, int, int); - -static void wi_dump_pkt(struct wi_frame *, struct ieee80211_node *, int rssi); - -#if 0 -static int wi_get_debug(struct wi_softc *, struct wi_req *); -static int wi_set_debug(struct wi_softc *, struct wi_req *); -#endif - -/* support to download firmware for symbol CF card */ -static int wi_symbol_write_firm(struct wi_softc *, const void *, int, - const void *, int); -static int wi_symbol_set_hcr(struct wi_softc *, int); +static int wi_write_appie(struct wi_softc *, int, const struct ieee80211_appie *); static void wi_scan_start(struct ieee80211com *); -static void wi_scan_curchan(struct ieee80211com *, unsigned long); -static void wi_scan_mindwell(struct ieee80211com *); static void wi_scan_end(struct ieee80211com *); static void wi_set_channel(struct ieee80211com *); -static void wi_update_slot(struct ifnet *); -static struct ieee80211_node *wi_node_alloc(struct ieee80211_node_table *); -static int wi_ioctl_get(struct ifnet *ifp, u_long command, caddr_t data); -static int wi_ioctl_set(struct ifnet *ifp, u_long command, caddr_t data); static __inline int wi_write_val(struct wi_softc *sc, int rid, u_int16_t val) @@ -199,15 +181,9 @@ SYSCTL_INT(_hw_wi, OID_AUTO, txerate, CTLFLAG_RW, &wi_txerate, static int wi_debug = 0; SYSCTL_INT(_hw_wi, OID_AUTO, debug, CTLFLAG_RW, &wi_debug, 0, "control debugging printfs"); - #define DPRINTF(X) if (wi_debug) printf X -#define DPRINTF2(X) if (wi_debug > 1) printf X -#define IFF_DUMPPKTS(_ifp) \ - (((_ifp)->if_flags & (IFF_DEBUG|IFF_LINK2)) == (IFF_DEBUG|IFF_LINK2)) #else #define DPRINTF(X) -#define DPRINTF2(X) -#define IFF_DUMPPKTS(_ifp) 0 #endif #define WI_INTRS (WI_EV_RX | WI_EV_ALLOC | WI_EV_INFO) @@ -255,7 +231,7 @@ int wi_attach(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; struct ifnet *ifp; int i, nrates, buflen; u_int16_t val; @@ -266,13 +242,13 @@ wi_attach(device_t dev) }; int error; - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(dev, "can not if_alloc\n"); wi_free(dev); - return (ENOSPC); + return ENOSPC; } - ifp->if_softc = sc; + ic = ifp->if_l2com; /* * NB: no locking is needed here; don't put it here @@ -284,18 +260,40 @@ wi_attach(device_t dev) if (error) { device_printf(dev, "bus_setup_intr() failed! (%d)\n", error); wi_free(dev); - return (error); + return error; } - mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, - MTX_DEF | MTX_RECURSE); - callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); - sc->sc_firmware_type = WI_NOTYPE; sc->wi_cmd_count = 500; /* Reset the NIC. */ - if (wi_reset(ifp) != 0) + if (wi_reset(sc) != 0) { + wi_free(dev); return ENXIO; /* XXX */ + } + + /* Read NIC identification */ + wi_read_nicid(sc); + switch (sc->sc_firmware_type) { + case WI_LUCENT: + if (sc->sc_sta_firmware_ver < 60006) + goto reject; + break; + case WI_INTERSIL: + if (sc->sc_sta_firmware_ver < 800) + goto reject; + break; + default: + reject: + device_printf(dev, "Sorry, this card is not supported " + "(type %d, firmware ver %d)\n", + sc->sc_firmware_type, sc->sc_sta_firmware_ver); + wi_free(dev); + return EOPNOTSUPP; + } + + mtx_init(&sc->sc_mtx, device_get_nameunit(dev), MTX_NETWORK_LOCK, + MTX_DEF | MTX_RECURSE); + callout_init_mtx(&sc->sc_watchdog, &sc->sc_mtx, 0); /* * Read the station address. @@ -320,9 +318,7 @@ wi_attach(device_t dev) return (error); } - /* Read NIC identification */ - wi_read_nicid(sc); - + ifp->if_softc = sc; if_initname(ifp, device_get_name(dev), device_get_unit(dev)); ifp->if_flags = IFF_BROADCAST | IFF_SIMPLEX | IFF_MULTICAST; ifp->if_ioctl = wi_ioctl; @@ -335,11 +331,9 @@ wi_attach(device_t dev) ic->ic_ifp = ifp; ic->ic_phytype = IEEE80211_T_DS; ic->ic_opmode = IEEE80211_M_STA; - ic->ic_state = IEEE80211_S_INIT; ic->ic_caps = IEEE80211_C_PMGT - | IEEE80211_C_WEP /* everyone supports WEP */ + | IEEE80211_C_MONITOR ; - ic->ic_max_aid = WI_MAX_AID; /* * Query the card for available channels and setup the @@ -360,28 +354,7 @@ wi_attach(device_t dev) c->ic_freq = ieee80211_ieee2mhz(i, IEEE80211_CHAN_B); c->ic_flags = IEEE80211_CHAN_B; c->ic_ieee = i; - } - - /* - * Read the default channel from the NIC. This may vary - * depending on the country where the NIC was purchased, so - * we can't hard-code a default and expect it to work for - * everyone. - * - * If no channel is specified, let the 802.11 code select. - */ - buflen = sizeof(val); - if (wi_read_rid(sc, WI_RID_OWN_CHNL, &val, &buflen) == 0) { - val = le16toh(val); - ic->ic_bsschan = ieee80211_find_channel(ic, - ieee80211_ieee2mhz(val, IEEE80211_CHAN_B), - IEEE80211_CHAN_B); - if (ic->ic_bsschan == NULL) - ic->ic_bsschan = &ic->ic_channels[0]; - } else { - device_printf(dev, - "WI_RID_OWN_CHNL failed, using first channel!\n"); - ic->ic_bsschan = &ic->ic_channels[0]; + /* XXX txpowers? */ } /* @@ -390,31 +363,18 @@ wi_attach(device_t dev) switch (sc->sc_firmware_type) { case WI_LUCENT: sc->sc_ntxbuf = 1; - sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE; -#ifdef WI_HERMES_AUTOINC_WAR - /* XXX: not confirmed, but never seen for recent firmware */ - if (sc->sc_sta_firmware_ver < 40000) { - sc->sc_flags |= WI_FLAGS_BUG_AUTOINC; - } -#endif - if (sc->sc_sta_firmware_ver >= 60000) - sc->sc_flags |= WI_FLAGS_HAS_MOR; - if (sc->sc_sta_firmware_ver >= 60006) { - ic->ic_caps |= IEEE80211_C_IBSS; - ic->ic_caps |= IEEE80211_C_MONITOR; - } - sc->sc_ibss_port = htole16(1); + ic->ic_caps |= IEEE80211_C_IBSS; + sc->sc_ibss_port = WI_PORTTYPE_BSS; + sc->sc_monitor_port = WI_PORTTYPE_ADHOC; sc->sc_min_rssi = WI_LUCENT_MIN_RSSI; sc->sc_max_rssi = WI_LUCENT_MAX_RSSI; sc->sc_dbm_offset = WI_LUCENT_DBM_OFFSET; break; - case WI_INTERSIL: sc->sc_ntxbuf = WI_NTXBUF; - sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR; - sc->sc_flags |= WI_FLAGS_HAS_ROAMING; - sc->sc_flags |= WI_FLAGS_HAS_SYSSCALE; + sc->sc_flags |= WI_FLAGS_HAS_FRAGTHR + | WI_FLAGS_HAS_ROAMING; /* * Old firmware are slow, so give peace a chance. */ @@ -422,31 +382,26 @@ wi_attach(device_t dev) sc->wi_cmd_count = 5000; if (sc->sc_sta_firmware_ver > 10101) sc->sc_flags |= WI_FLAGS_HAS_DBMADJUST; - if (sc->sc_sta_firmware_ver >= 800) { - ic->ic_caps |= IEEE80211_C_IBSS; - ic->ic_caps |= IEEE80211_C_MONITOR; - } + ic->ic_caps |= IEEE80211_C_IBSS; /* * version 0.8.3 and newer are the only ones that are known * to currently work. Earlier versions can be made to work, - * at least according to the Linux driver. + * at least according to the Linux driver but we require + * monitor mode so this is irrelevant. */ - if (sc->sc_sta_firmware_ver >= 803) - ic->ic_caps |= IEEE80211_C_HOSTAP; - sc->sc_ibss_port = htole16(0); - - sc->sc_min_rssi = WI_PRISM_MIN_RSSI; - sc->sc_max_rssi = WI_PRISM_MAX_RSSI; - sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET; - break; - - case WI_SYMBOL: - sc->sc_ntxbuf = 1; - sc->sc_flags |= WI_FLAGS_HAS_DIVERSITY; - if (sc->sc_sta_firmware_ver >= 25000) - ic->ic_caps |= IEEE80211_C_IBSS; - sc->sc_ibss_port = htole16(4); + ic->ic_caps |= IEEE80211_C_HOSTAP; + if (sc->sc_sta_firmware_ver >= 10603) + sc->sc_flags |= WI_FLAGS_HAS_ENHSECURITY; + if (sc->sc_sta_firmware_ver >= 10700) { + /* + * 1.7.0+ have the necessary support for sta mode WPA. + */ + sc->sc_flags |= WI_FLAGS_HAS_WPASUPPORT; + ic->ic_caps |= IEEE80211_C_WPA; + } + sc->sc_ibss_port = WI_PORTTYPE_IBSS; + sc->sc_monitor_port = WI_PORTTYPE_APSILENT; sc->sc_min_rssi = WI_PRISM_MIN_RSSI; sc->sc_max_rssi = WI_PRISM_MAX_RSSI; sc->sc_dbm_offset = WI_PRISM_DBM_OFFSET; @@ -459,7 +414,7 @@ wi_attach(device_t dev) buflen = sizeof(val); if (wi_read_rid(sc, WI_RID_WEP_AVAIL, &val, &buflen) == 0 && val != htole16(0)) - ic->ic_caps |= IEEE80211_C_WEP; + ic->ic_cryptocaps |= IEEE80211_CRYPTO_WEP; /* Find supported rates. */ buflen = sizeof(ratebuf); @@ -482,48 +437,21 @@ wi_attach(device_t dev) sc->sc_dbm_offset = le16toh(val); } - sc->sc_max_datalen = 2304; - sc->sc_system_scale = 1; - sc->sc_cnfauthmode = IEEE80211_AUTH_OPEN; - sc->sc_roaming_mode = 1; - sc->wi_channel = IEEE80211_CHAN_ANYC; sc->sc_portnum = WI_DEFAULT_PORT; - sc->sc_authtype = WI_DEFAULT_AUTHTYPE; - - bzero(sc->sc_nodename, sizeof(sc->sc_nodename)); - sc->sc_nodelen = sizeof(WI_DEFAULT_NODENAME) - 1; - bcopy(WI_DEFAULT_NODENAME, sc->sc_nodename, sc->sc_nodelen); + TASK_INIT(&sc->sc_oor_task, 0, wi_status_oor, ic); - bzero(sc->sc_net_name, sizeof(sc->sc_net_name)); - bcopy(WI_DEFAULT_NETNAME, sc->sc_net_name, - sizeof(WI_DEFAULT_NETNAME) - 1); - - /* - * Call MI attach routine. - */ ieee80211_ifattach(ic); - /* override state transition method */ - sc->sc_newstate = ic->ic_newstate; - sc->sc_key_alloc = ic->ic_crypto.cs_key_alloc; - ic->ic_crypto.cs_key_alloc = wi_key_alloc; - ic->ic_newstate = wi_newstate; ic->ic_raw_xmit = wi_raw_xmit; - ic->ic_scan_start = wi_scan_start; - ic->ic_scan_curchan = wi_scan_curchan; - ic->ic_scan_mindwell = wi_scan_mindwell; ic->ic_scan_end = wi_scan_end; ic->ic_set_channel = wi_set_channel; - ic->ic_node_alloc = wi_node_alloc; - ic->ic_updateslot = wi_update_slot; - ic->ic_reset = wi_reset; - ieee80211_media_init(ic, wi_media_change, wi_media_status); + ic->ic_vap_create = wi_vap_create; + ic->ic_vap_delete = wi_vap_delete; + ic->ic_update_mcast = wi_update_mcast; -#if NBPFILTER > 0 - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof(struct ieee80211_frame) + sizeof(sc->sc_tx_th)); /* * Initialize constant fields. * XXX make header lengths a multiple of 32-bits so subsequent @@ -540,7 +468,6 @@ wi_attach(device_t dev) sc->sc_rx_th_len = roundup(sizeof(sc->sc_rx_th), sizeof(u_int32_t)); sc->sc_rx_th.wr_ihdr.it_len = htole16(sc->sc_rx_th_len); sc->sc_rx_th.wr_ihdr.it_present = htole32(WI_RX_RADIOTAP_PRESENT); -#endif if (bootverbose) ieee80211_announce(ic); @@ -553,19 +480,18 @@ wi_detach(device_t dev) { struct wi_softc *sc = device_get_softc(dev); struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; WI_LOCK(sc); /* check if device was removed */ sc->wi_gone |= !bus_child_present(dev); - wi_stop(ifp, 0); + wi_stop_locked(sc, 0); WI_UNLOCK(sc); - -#if NBPFILTER > 0 bpfdetach(ifp); -#endif - ieee80211_ifdetach(&sc->sc_ic); + ieee80211_ifdetach(ic); + bus_teardown_intr(dev, sc->irq, sc->wi_intrhand); if_free(sc->sc_ifp); wi_free(dev); @@ -573,60 +499,82 @@ wi_detach(device_t dev) return (0); } -#ifdef __NetBSD__ -int -wi_activate(struct device *self, enum devact act) +static struct ieee80211vap * +wi_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) { - struct wi_softc *sc = (struct wi_softc *)self; - int rv = 0, s; + struct wi_softc *sc = ic->ic_ifp->if_softc; + struct wi_vap *wvp; + struct ieee80211vap *vap; - s = splnet(); - switch (act) { - case DVACT_ACTIVATE: - rv = EOPNOTSUPP; - break; + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + wvp = (struct wi_vap *) malloc(sizeof(struct wi_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (wvp == NULL) + return NULL; - case DVACT_DEACTIVATE: - if_deactivate(sc->sc_ifp); - break; - } - splx(s); - return rv; -} + vap = &wvp->wv_vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); -void -wi_power(struct wi_softc *sc, int why) -{ - struct ifnet *ifp = sc->sc_ifp; - int s; + vap->iv_max_aid = WI_MAX_AID; - s = splnet(); - switch (why) { - case PWR_SUSPEND: - case PWR_STANDBY: - wi_stop(ifp, 1); + switch (opmode) { + case IEEE80211_M_STA: + sc->sc_porttype = WI_PORTTYPE_BSS; + wvp->wv_newstate = vap->iv_newstate; + vap->iv_newstate = wi_newstate_sta; + /* need to filter mgt frames to avoid confusing state machine */ + wvp->wv_recv_mgmt = vap->iv_recv_mgmt; + vap->iv_recv_mgmt = wi_recv_mgmt; break; - case PWR_RESUME: - if (ifp->if_flags & IFF_UP) { - wi_init(sc); - (void)wi_intr(sc); - } + case IEEE80211_M_IBSS: + sc->sc_porttype = sc->sc_ibss_port; + wvp->wv_newstate = vap->iv_newstate; + vap->iv_newstate = wi_newstate_sta; + break; + case IEEE80211_M_AHDEMO: + sc->sc_porttype = WI_PORTTYPE_ADHOC; + break; + case IEEE80211_M_HOSTAP: + sc->sc_porttype = WI_PORTTYPE_HOSTAP; + wvp->wv_newstate = vap->iv_newstate; + vap->iv_newstate = wi_newstate_hostap; + break; + case IEEE80211_M_MONITOR: + sc->sc_porttype = sc->sc_monitor_port; break; - case PWR_SOFTSUSPEND: - case PWR_SOFTSTANDBY: - case PWR_SOFTRESUME: + default: break; } - splx(s); + + TASK_INIT(&wvp->wv_connected_task, 0, wi_status_connected, vap); + TASK_INIT(&wvp->wv_disconnected_task, 0, wi_status_disconnected, vap); + TASK_INIT(&wvp->wv_assoc_failed_task, 0, wi_status_assoc_failed, vap); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, wi_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +wi_vap_delete(struct ieee80211vap *vap) +{ + struct wi_vap *wvp = WI_VAP(vap); + + ieee80211_vap_detach(vap); + free(wvp, M_80211_VAP); } -#endif /* __NetBSD__ */ void wi_shutdown(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - wi_stop(sc->sc_ifp, 1); + wi_stop(sc, 1); } void @@ -658,7 +606,6 @@ wi_intr(void *arg) if (status & WI_EV_INFO) wi_info_intr(sc); if ((ifp->if_drv_flags & IFF_DRV_OACTIVE) == 0 && - (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0 && !IFQ_DRV_IS_EMPTY(&ifp->if_snd)) wi_start_locked(ifp); @@ -670,341 +617,379 @@ wi_intr(void *arg) return; } -void -wi_init(void *arg) +static void +wi_enable(struct wi_softc *sc) { - struct wi_softc *sc = arg; - struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = &sc->sc_ic; - struct wi_joinreq join; - struct ieee80211_channel *chan; - int i; - int error = 0, wasenabled; + /* Enable interrupts */ + CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); + /* enable port */ + wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); + sc->sc_enabled = 1; +} +static int +wi_setup_locked(struct wi_softc *sc, int porttype, int mode, + uint8_t mac[IEEE80211_ADDR_LEN]) +{ + int i; - if (sc->wi_gone) - return; + wi_reset(sc); - if ((wasenabled = sc->sc_enabled)) - wi_stop(ifp, 1); + wi_write_val(sc, WI_RID_PORTTYPE, porttype); + wi_write_val(sc, WI_RID_CREATE_IBSS, mode); + wi_write_val(sc, WI_RID_MAX_DATALEN, 2304); + /* XXX IEEE80211_BPF_NOACK wants 0 */ + wi_write_val(sc, WI_RID_ALT_RETRY_CNT, 2); + if (sc->sc_flags & WI_FLAGS_HAS_ROAMING) + wi_write_val(sc, WI_RID_ROAMING_MODE, 3); /* NB: disabled */ - WI_LOCK(sc); - wi_reset(ifp); + wi_write_rid(sc, WI_RID_MAC_NODE, mac, IEEE80211_ADDR_LEN); - /* common 802.11 configuration */ - ic->ic_flags &= ~IEEE80211_F_IBSSON; - sc->sc_flags &= ~WI_FLAGS_OUTRANGE; - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_BSS); - break; - case IEEE80211_M_IBSS: - wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_ibss_port); - ic->ic_flags |= IEEE80211_F_IBSSON; - break; - case IEEE80211_M_AHDEMO: - wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); - break; - case IEEE80211_M_HOSTAP: - /* - * For PRISM cards, override the empty SSID, because in - * HostAP mode the controller will lock up otherwise. - */ - if (sc->sc_firmware_type == WI_INTERSIL && - ic->ic_des_ssid[0].len == 0) { - ic->ic_des_ssid[0].ssid[0] = ' '; - ic->ic_des_ssid[0].len = 1; - } - wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_HOSTAP); - break; - case IEEE80211_M_MONITOR: - switch (sc->sc_firmware_type) { - case WI_LUCENT: - wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_ADHOC); - break; - - case WI_INTERSIL: - wi_write_val(sc, WI_RID_PORTTYPE, WI_PORTTYPE_APSILENT); - break; + /* Allocate fids for the card */ + sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame); + for (i = 0; i < sc->sc_ntxbuf; i++) { + int error = wi_alloc_fid(sc, sc->sc_buflen, + &sc->sc_txd[i].d_fid); + if (error) { + device_printf(sc->sc_dev, + "tx buffer allocation failed (error %u)\n", + error); + return error; } - - wi_cmd(sc, WI_CMD_DEBUG | (WI_TEST_MONITOR << 8), 0, 0, 0); - break; - case IEEE80211_M_WDS: - /* XXXX */ - break; + sc->sc_txd[i].d_len = 0; } + sc->sc_txcur = sc->sc_txnext = 0; - /* Intersil interprets this RID as joining ESS even in IBSS mode */ - if (sc->sc_firmware_type == WI_LUCENT && - (ic->ic_flags & IEEE80211_F_IBSSON) && ic->ic_des_ssid[0].len > 0) - wi_write_val(sc, WI_RID_CREATE_IBSS, 1); - else - wi_write_val(sc, WI_RID_CREATE_IBSS, 0); - wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval); - wi_write_ssid(sc, WI_RID_DESIRED_SSID, ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - wi_write_val(sc, WI_RID_OWN_CHNL, - ieee80211_chan2ieee(ic, ic->ic_bsschan)); - wi_write_ssid(sc, WI_RID_OWN_SSID, ic->ic_des_ssid[0].ssid, - ic->ic_des_ssid[0].len); - - IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); - wi_write_rid(sc, WI_RID_MAC_NODE, ic->ic_myaddr, IEEE80211_ADDR_LEN); - - if (ic->ic_caps & IEEE80211_C_PMGT) - wi_write_val(sc, WI_RID_PM_ENABLED, - (ic->ic_flags & IEEE80211_F_PMGTON) ? 1 : 0); - - /* not yet common 802.11 configuration */ - wi_write_val(sc, WI_RID_MAX_DATALEN, sc->sc_max_datalen); - wi_write_val(sc, WI_RID_RTS_THRESH, ic->ic_rtsthreshold); - if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) - wi_write_val(sc, WI_RID_FRAG_THRESH, ic->ic_fragthreshold); - - /* driver specific 802.11 configuration */ - if (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) - wi_write_val(sc, WI_RID_SYSTEM_SCALE, sc->sc_system_scale); - if (sc->sc_flags & WI_FLAGS_HAS_ROAMING) - wi_write_val(sc, WI_RID_ROAMING_MODE, sc->sc_roaming_mode); - if (sc->sc_flags & WI_FLAGS_HAS_MOR) - wi_write_val(sc, WI_RID_MICROWAVE_OVEN, sc->sc_microwave_oven); - wi_write_txrate(sc); - wi_write_ssid(sc, WI_RID_NODENAME, sc->sc_nodename, sc->sc_nodelen); - wi_write_val(sc, WI_RID_ALT_RETRY_CNT, 0); /* for IEEE80211_BPF_NOACK */ - - if (ic->ic_opmode == IEEE80211_M_HOSTAP && - sc->sc_firmware_type == WI_INTERSIL) { - wi_write_val(sc, WI_RID_OWN_BEACON_INT, ic->ic_bintval); - wi_write_val(sc, WI_RID_BASIC_RATE, 0x03); /* 1, 2 */ - wi_write_val(sc, WI_RID_SUPPORT_RATE, 0x0f); /* 1, 2, 5.5, 11 */ - wi_write_val(sc, WI_RID_DTIM_PERIOD, ic->ic_dtim_period); - } + return 0; +} - /* - * Initialize promisc mode. - * Being in the Host-AP mode causes a great - * deal of pain if primisc mode is set. - * Therefore we avoid confusing the firmware - * and always reset promisc mode in Host-AP - * mode. Host-AP sees all the packets anyway. - */ - if (ic->ic_opmode != IEEE80211_M_HOSTAP && - (ifp->if_flags & IFF_PROMISC) != 0) { - wi_write_val(sc, WI_RID_PROMISC, 1); - } else { - wi_write_val(sc, WI_RID_PROMISC, 0); - } +static void +wi_init_locked(struct wi_softc *sc) +{ + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + int wasenabled; - /* Configure WEP. */ - if (ic->ic_caps & IEEE80211_C_WEP) { - sc->sc_cnfauthmode = ic->ic_bss->ni_authmode; - wi_write_wep(sc); - } else - sc->sc_encryption = 0; + WI_LOCK_ASSERT(sc); - /* Set multicast filter. */ - wi_write_multi(sc); + wasenabled = sc->sc_enabled; + if (wasenabled) + wi_stop_locked(sc, 1); - /* Allocate fids for the card */ - if (sc->sc_firmware_type != WI_SYMBOL || !wasenabled) { - sc->sc_buflen = IEEE80211_MAX_LEN + sizeof(struct wi_frame); - if (sc->sc_firmware_type == WI_SYMBOL) - sc->sc_buflen = 1585; /* XXX */ - for (i = 0; i < sc->sc_ntxbuf; i++) { - error = wi_alloc_fid(sc, sc->sc_buflen, - &sc->sc_txd[i].d_fid); - if (error) { - device_printf(sc->sc_dev, - "tx buffer allocation failed (error %u)\n", - error); - goto out; - } - sc->sc_txd[i].d_len = 0; - } + IEEE80211_ADDR_COPY(ic->ic_myaddr, IF_LLADDR(ifp)); + if (wi_setup_locked(sc, sc->sc_porttype, 3, ic->ic_myaddr) != 0) { + if_printf(ifp, "interface not running\n"); + wi_stop_locked(sc, 1); + return; } - sc->sc_txcur = sc->sc_txnext = 0; - - /* Enable desired port */ - wi_cmd(sc, WI_CMD_ENABLE | sc->sc_portnum, 0, 0, 0); - sc->sc_enabled = 1; ifp->if_drv_flags |= IFF_DRV_RUNNING; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - if (ic->ic_opmode == IEEE80211_M_AHDEMO || - ic->ic_opmode == IEEE80211_M_IBSS || - ic->ic_opmode == IEEE80211_M_MONITOR || - ic->ic_opmode == IEEE80211_M_HOSTAP) { - chan = (sc->wi_channel == IEEE80211_CHAN_ANYC) ? - ic->ic_curchan : sc->wi_channel; - ieee80211_create_ibss(ic, chan); - } - /* Enable interrupts */ - CSR_WRITE_2(sc, WI_INT_EN, WI_INTRS); - if (!wasenabled && - ic->ic_opmode == IEEE80211_M_HOSTAP && - sc->sc_firmware_type == WI_INTERSIL) { - /* XXX: some card need to be re-enabled for hostap */ - wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); - wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); - } + callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); - if (ic->ic_opmode == IEEE80211_M_STA && - ((ic->ic_flags & IEEE80211_F_DESBSSID) || - ic->ic_des_chan != IEEE80211_CHAN_ANYC)) { - memset(&join, 0, sizeof(join)); - if (ic->ic_flags & IEEE80211_F_DESBSSID) - IEEE80211_ADDR_COPY(&join.wi_bssid, ic->ic_des_bssid); - if (ic->ic_des_chan != IEEE80211_CHAN_ANYC) - join.wi_chan = htole16( - ieee80211_chan2ieee(ic, ic->ic_des_chan)); - /* Lucent firmware does not support the JOIN RID. */ - if (sc->sc_firmware_type != WI_LUCENT) - wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join)); - } + wi_enable(sc); /* Enable desired port */ +} - callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); +void +wi_init(void *arg) +{ + struct wi_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + WI_LOCK(sc); + wi_init_locked(sc); WI_UNLOCK(sc); - return; -out: - if (error) { - if_printf(ifp, "interface not running\n"); - wi_stop(ifp, 1); - } - WI_UNLOCK(sc); - DPRINTF(("wi_init: return %d\n", error)); - return; + + ieee80211_start_all(ic); } -void -wi_stop(struct ifnet *ifp, int disable) +static void +wi_stop_locked(struct wi_softc *sc, int disable) { - struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + WI_LOCK_ASSERT(sc); - DELAY(100000); - WI_LOCK(sc); if (sc->sc_enabled && !sc->wi_gone) { CSR_WRITE_2(sc, WI_INT_EN, 0); wi_cmd(sc, WI_CMD_DISABLE | sc->sc_portnum, 0, 0, 0); - if (disable) { -#ifdef __NetBSD__ - if (sc->sc_disable) - (*sc->sc_disable)(sc); -#endif + if (disable) sc->sc_enabled = 0; - } } else if (sc->wi_gone && disable) /* gone --> not enabled */ - sc->sc_enabled = 0; + sc->sc_enabled = 0; - callout_stop(&sc->sc_watchdog); /* XXX drain */ + callout_stop(&sc->sc_watchdog); sc->sc_tx_timer = 0; - sc->sc_scan_timer = 0; sc->sc_false_syns = 0; - sc->sc_naps = 0; + ifp->if_drv_flags &= ~(IFF_DRV_OACTIVE | IFF_DRV_RUNNING); +} +void +wi_stop(struct wi_softc *sc, int disable) +{ + WI_LOCK(sc); + wi_stop_locked(sc, disable); WI_UNLOCK(sc); } static void -wi_start_locked(struct ifnet *ifp) +wi_set_channel(struct ieee80211com *ic) { - struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni; - struct ieee80211_frame *wh; - struct ether_header *eh; - struct mbuf *m0; - struct wi_frame frmhdr; - int cur; + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; - WI_LOCK_ASSERT(sc); + DPRINTF(("%s: channel %d, %sscanning\n", __func__, + ieee80211_chan2ieee(ic, ic->ic_curchan), + ic->ic_flags & IEEE80211_F_SCAN ? "" : "!")); - if (sc->wi_gone) - return; - if (sc->sc_flags & WI_FLAGS_OUTRANGE) - return; + WI_LOCK(sc); + wi_write_val(sc, WI_RID_OWN_CHNL, + ieee80211_chan2ieee(ic, ic->ic_curchan)); - memset(&frmhdr, 0, sizeof(frmhdr)); - cur = sc->sc_txnext; - for (;;) { - IF_POLL(&ic->ic_mgtq, m0); - if (m0 != NULL) { - if (sc->sc_txd[cur].d_len != 0) { - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - IF_DEQUEUE(&ic->ic_mgtq, m0); - /* - * Hack! The referenced node pointer is in the - * rcvif field of the packet header. This is - * placed there by ieee80211_mgmt_output because - * we need to hold the reference with the frame - * and there's no other way (other than packet - * tags which we consider too expensive to use) - * to pass it along. - */ - ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; + sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = + htole16(ic->ic_curchan->ic_freq); + sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = + htole16(ic->ic_curchan->ic_flags); + WI_UNLOCK(sc); +} - m_copydata(m0, 4, ETHER_ADDR_LEN * 2, - (caddr_t)&frmhdr.wi_ehdr); - frmhdr.wi_ehdr.ether_type = 0; - wh = mtod(m0, struct ieee80211_frame *); - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - if (sc->sc_txd[cur].d_len != 0) { - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - if (m0->m_len < sizeof(struct ether_header) && - (m0 = m_pullup(m0, sizeof(struct ether_header))) == NULL) { - ifp->if_oerrors++; - continue; - } - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - continue; - } - ifp->if_opackets++; - m_copydata(m0, 0, ETHER_HDR_LEN, - (caddr_t)&frmhdr.wi_ehdr); -#if NBPFILTER > 0 - BPF_MTAP(ifp, m0); -#endif +static void +wi_scan_start(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; + struct ieee80211_scan_state *ss = ic->ic_scan; - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ifp->if_oerrors++; - ieee80211_free_node(ni); - continue; - } - wh = mtod(m0, struct ieee80211_frame *); + DPRINTF(("%s\n", __func__)); + + WI_LOCK(sc); + /* + * Switch device to monitor mode. + */ + wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_monitor_port); + if (sc->sc_firmware_type == WI_INTERSIL) { + wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); + wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); + } + /* force full dwell time to compensate for firmware overhead */ + ss->ss_mindwell = ss->ss_maxdwell = msecs_to_ticks(400); + WI_UNLOCK(sc); + +} + +static void +wi_scan_end(struct ieee80211com *ic) +{ + struct ifnet *ifp = ic->ic_ifp; + struct wi_softc *sc = ifp->if_softc; + + DPRINTF(("%s: restore port type %d\n", __func__, sc->sc_porttype)); + + WI_LOCK(sc); + wi_write_val(sc, WI_RID_PORTTYPE, sc->sc_porttype); + if (sc->sc_firmware_type == WI_INTERSIL) { + wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); + wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); + } + WI_UNLOCK(sc); +} + +static void +wi_recv_mgmt(struct ieee80211_node *ni, struct mbuf *m, + int subtype, int rssi, int noise, u_int32_t rstamp) +{ + struct ieee80211vap *vap = ni->ni_vap; + + switch (subtype) { + case IEEE80211_FC0_SUBTYPE_AUTH: + case IEEE80211_FC0_SUBTYPE_ASSOC_RESP: + case IEEE80211_FC0_SUBTYPE_REASSOC_RESP: + /* NB: filter frames that trigger state changes */ + return; + } + WI_VAP(vap)->wv_recv_mgmt(ni, m, subtype, rssi, noise, rstamp); +} + +static int +wi_newstate_sta(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; + struct ieee80211_node *bss; + struct wi_softc *sc = ifp->if_softc; + + DPRINTF(("%s: %s -> %s\n", __func__, + ieee80211_state_name[vap->iv_state], + ieee80211_state_name[nstate])); + + if (nstate == IEEE80211_S_AUTH) { + WI_LOCK(sc); + wi_setup_locked(sc, WI_PORTTYPE_BSS, 3, vap->iv_myaddr); + + if (vap->iv_flags & IEEE80211_F_PMGTON) { + wi_write_val(sc, WI_RID_MAX_SLEEP, ic->ic_lintval); + wi_write_val(sc, WI_RID_PM_ENABLED, 1); } -#if NBPFILTER > 0 - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); -#endif - frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX); - /* XXX check key for SWCRYPT instead of using operating mode */ - if ((wh->i_fc[1] & IEEE80211_FC1_WEP) && - (sc->sc_encryption & HOST_ENCRYPT)) { - struct ieee80211_key *k; + wi_write_val(sc, WI_RID_RTS_THRESH, vap->iv_rtsthreshold); + if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) + wi_write_val(sc, WI_RID_FRAG_THRESH, + vap->iv_fragthreshold); + wi_write_txrate(sc, vap); + + bss = vap->iv_bss; + wi_write_ssid(sc, WI_RID_DESIRED_SSID, bss->ni_essid, bss->ni_esslen); + wi_write_val(sc, WI_RID_OWN_CHNL, + ieee80211_chan2ieee(ic, bss->ni_chan)); + + /* Configure WEP. */ + if (ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP) + wi_write_wep(sc, vap); + else + sc->sc_encryption = 0; + + if ((sc->sc_flags & WI_FLAGS_HAS_WPASUPPORT) && + (vap->iv_flags & IEEE80211_F_WPA)) { + wi_write_val(sc, WI_RID_WPA_HANDLING, 1); + if (vap->iv_appie_wpa != NULL) + wi_write_appie(sc, WI_RID_WPA_DATA, + vap->iv_appie_wpa); + } + + wi_enable(sc); /* enable port */ + + /* Lucent firmware does not support the JOIN RID. */ + if (sc->sc_firmware_type == WI_INTERSIL) { + struct wi_joinreq join; + + memset(&join, 0, sizeof(join)); + IEEE80211_ADDR_COPY(&join.wi_bssid, bss->ni_bssid); + join.wi_chan = htole16( + ieee80211_chan2ieee(ic, bss->ni_chan)); + wi_write_rid(sc, WI_RID_JOIN_REQ, &join, sizeof(join)); + } + WI_UNLOCK(sc); + + /* + * NB: don't go through 802.11 layer, it'll send auth frame; + * instead we drive the state machine from the link status + * notification we get on association. + */ + vap->iv_state = nstate; + return EINPROGRESS; + } + return WI_VAP(vap)->wv_newstate(vap, nstate, arg); +} + +static int +wi_newstate_hostap(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) +{ + struct ieee80211com *ic = vap->iv_ic; + struct ifnet *ifp = ic->ic_ifp; + struct ieee80211_node *bss; + struct wi_softc *sc = ifp->if_softc; + int error; + + DPRINTF(("%s: %s -> %s\n", __func__, + ieee80211_state_name[vap->iv_state], + ieee80211_state_name[nstate])); + + error = WI_VAP(vap)->wv_newstate(vap, nstate, arg); + if (error == 0 && nstate == IEEE80211_S_RUN) { + WI_LOCK(sc); + wi_setup_locked(sc, WI_PORTTYPE_HOSTAP, 0, vap->iv_myaddr); + + bss = vap->iv_bss; + wi_write_ssid(sc, WI_RID_OWN_SSID, + bss->ni_essid, bss->ni_esslen); + wi_write_val(sc, WI_RID_OWN_CHNL, + ieee80211_chan2ieee(ic, bss->ni_chan)); + wi_write_val(sc, WI_RID_BASIC_RATE, 0x3); + wi_write_val(sc, WI_RID_SUPPORT_RATE, 0xf); + wi_write_txrate(sc, vap); - k = ieee80211_crypto_encap(ic, ni, m0); + wi_write_val(sc, WI_RID_OWN_BEACON_INT, bss->ni_intval); + wi_write_val(sc, WI_RID_DTIM_PERIOD, vap->iv_dtim_period); + + wi_write_val(sc, WI_RID_RTS_THRESH, vap->iv_rtsthreshold); + if (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) + wi_write_val(sc, WI_RID_FRAG_THRESH, + vap->iv_fragthreshold); + + if ((sc->sc_flags & WI_FLAGS_HAS_ENHSECURITY) && + (vap->iv_flags & IEEE80211_F_HIDESSID)) { + /* + * bit 0 means hide SSID in beacons, + * bit 1 means don't respond to bcast probe req + */ + wi_write_val(sc, WI_RID_ENH_SECURITY, 0x3); + } + + if ((sc->sc_flags & WI_FLAGS_HAS_WPASUPPORT) && + (vap->iv_flags & IEEE80211_F_WPA) && + vap->iv_appie_wpa != NULL) + wi_write_appie(sc, WI_RID_WPA_DATA, vap->iv_appie_wpa); + + wi_write_val(sc, WI_RID_PROMISC, 0); + + /* Configure WEP. */ + if (ic->ic_cryptocaps & IEEE80211_CRYPTO_WEP) + wi_write_wep(sc, vap); + else + sc->sc_encryption = 0; + + wi_enable(sc); /* enable port */ + WI_UNLOCK(sc); + } + return error; +} + +static void +wi_start_locked(struct ifnet *ifp) +{ + struct wi_softc *sc = ifp->if_softc; + struct ieee80211_node *ni; + struct ieee80211_frame *wh; + struct mbuf *m0; + struct ieee80211_key *k; + struct wi_frame frmhdr; + int cur; + + WI_LOCK_ASSERT(sc); + + if (sc->wi_gone) + return; + + memset(&frmhdr, 0, sizeof(frmhdr)); + cur = sc->sc_txnext; + for (;;) { + IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); + if (m0 == NULL) + break; + if (sc->sc_txd[cur].d_len != 0) { + IFQ_DRV_PREPEND(&ifp->if_snd, m0); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + /* NB: copy before 802.11 header is prepended */ + m_copydata(m0, 0, ETHER_HDR_LEN, + (caddr_t)&frmhdr.wi_ehdr); + + ni = (struct ieee80211_node *) m0->m_pkthdr.rcvif; + m0 = ieee80211_encap(ni, m0); + if (m0 == NULL) { + ifp->if_oerrors++; + ieee80211_free_node(ni); + continue; + } + + wh = mtod(m0, struct ieee80211_frame *); + frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX); + if (wh->i_fc[1] & IEEE80211_FC1_WEP) { + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { ieee80211_free_node(ni); m_freem(m0); @@ -1012,24 +997,23 @@ wi_start_locked(struct ifnet *ifp) } frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); } -#if NBPFILTER > 0 - if (bpf_peers_present(sc->sc_drvbpf)) { - sc->sc_tx_th.wt_rate = - ni->ni_rates.rs_rates[ni->ni_txrate]; - bpf_mtap2(sc->sc_drvbpf, - &sc->sc_tx_th, sc->sc_tx_th_len, m0); + + if (bpf_peers_present(ifp->if_bpf)) { + sc->sc_tx_th.wt_rate = ni->ni_txrate; + bpf_mtap2(ifp->if_bpf, + &sc->sc_tx_th, sc->sc_tx_th_len, m0); } -#endif + m_copydata(m0, 0, sizeof(struct ieee80211_frame), (caddr_t)&frmhdr.wi_whdr); m_adj(m0, sizeof(struct ieee80211_frame)); frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); - if (IFF_DUMPPKTS(ifp)) - wi_dump_pkt(&frmhdr, NULL, -1); ieee80211_free_node(ni); if (wi_start_tx(ifp, &frmhdr, m0)) continue; + sc->sc_txnext = cur = (cur + 1) % sc->sc_ntxbuf; + ifp->if_opackets++; } } @@ -1078,6 +1062,7 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, struct ieee80211com *ic = ni->ni_ic; struct ifnet *ifp = ic->ic_ifp; struct wi_softc *sc = ifp->if_softc; + struct ieee80211_key *k; struct ieee80211_frame *wh; struct wi_frame frmhdr; int cur; @@ -1089,11 +1074,6 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, rc = ENETDOWN; goto out; } - if (sc->sc_flags & WI_FLAGS_OUTRANGE) { - rc = ENETDOWN; - goto out; - } - memset(&frmhdr, 0, sizeof(frmhdr)); cur = sc->sc_txnext; if (sc->sc_txd[cur].d_len != 0) { @@ -1108,42 +1088,26 @@ wi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m0, frmhdr.wi_ehdr.ether_type = 0; wh = mtod(m0, struct ieee80211_frame *); -#if NBPFILTER > 0 - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); -#endif frmhdr.wi_tx_ctl = htole16(WI_ENC_TX_802_11|WI_TXCNTL_TX_EX); if (params && (params->ibp_flags & IEEE80211_BPF_NOACK)) frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_ALTRTRY); - /* XXX check key for SWCRYPT instead of using operating mode */ if ((wh->i_fc[1] & IEEE80211_FC1_WEP) && - (sc->sc_encryption & HOST_ENCRYPT)) { - if (!params || - (params && (params->ibp_flags & IEEE80211_BPF_CRYPTO))) { - struct ieee80211_key *k; - - k = ieee80211_crypto_encap(ic, ni, m0); - if (k == NULL) { - rc = ENOMEM; - goto out; - } - frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); + (!params || (params && (params->ibp_flags & IEEE80211_BPF_CRYPTO)))) { + k = ieee80211_crypto_encap(ni, m0); + if (k == NULL) { + rc = ENOMEM; + goto out; } + frmhdr.wi_tx_ctl |= htole16(WI_TXCNTL_NOCRYPT); } -#if NBPFILTER > 0 - if (bpf_peers_present(sc->sc_drvbpf)) { - sc->sc_tx_th.wt_rate = - ni->ni_rates.rs_rates[ni->ni_txrate]; - bpf_mtap2(sc->sc_drvbpf, - &sc->sc_tx_th, sc->sc_tx_th_len, m0); + if (bpf_peers_present(ifp->if_bpf)) { + sc->sc_tx_th.wt_rate = ni->ni_txrate; + bpf_mtap2(ifp->if_bpf, &sc->sc_tx_th, sc->sc_tx_th_len, m0); } -#endif m_copydata(m0, 0, sizeof(struct ieee80211_frame), (caddr_t)&frmhdr.wi_whdr); m_adj(m0, sizeof(struct ieee80211_frame)); frmhdr.wi_dat_len = htole16(m0->m_pkthdr.len); - if (IFF_DUMPPKTS(ifp)) - wi_dump_pkt(&frmhdr, NULL, -1); if (wi_start_tx(ifp, &frmhdr, m0) < 0) { m0 = NULL; rc = EIO; @@ -1162,32 +1126,21 @@ out: } static int -wi_reset(struct ifnet *ifp) +wi_reset(struct wi_softc *sc) { - struct wi_softc *sc = ifp->if_softc; #define WI_INIT_TRIES 3 - int i; - int error = 0; - int tries; - - /* Symbol firmware cannot be initialized more than once */ - if (sc->sc_firmware_type == WI_SYMBOL && sc->sc_reset) - return (0); - if (sc->sc_firmware_type == WI_SYMBOL) - tries = 1; - else - tries = WI_INIT_TRIES; + int i, error = 0; - for (i = 0; i < tries; i++) { - if ((error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0)) == 0) + for (i = 0; i < WI_INIT_TRIES; i++) { + error = wi_cmd(sc, WI_CMD_INI, 0, 0, 0); + if (error == 0) break; DELAY(WI_DELAY * 1000); } sc->sc_reset = 1; - - if (i == tries) { - if_printf(ifp, "init failed\n"); - return (error); + if (i == WI_INIT_TRIES) { + if_printf(sc->sc_ifp, "reset failed\n"); + return error; } CSR_WRITE_2(sc, WI_INT_EN, 0); @@ -1196,7 +1149,7 @@ wi_reset(struct ifnet *ifp) /* Calibrate timer. */ wi_write_val(sc, WI_RID_TICK_TIME, 8); - return (0); + return 0; #undef WI_INIT_TRIES } @@ -1206,28 +1159,17 @@ wi_watchdog(void *arg) struct wi_softc *sc = arg; struct ifnet *ifp = sc->sc_ifp; + WI_LOCK_ASSERT(sc); + if (!sc->sc_enabled) return; - if (sc->sc_tx_timer) { - if (--sc->sc_tx_timer == 0) { - if_printf(ifp, "device timeout\n"); - ifp->if_oerrors++; - wi_init(ifp->if_softc); - return; - } - } - - if (sc->sc_scan_timer) { - if (--sc->sc_scan_timer <= WI_SCAN_WAIT - WI_SCAN_INQWAIT && - sc->sc_firmware_type == WI_INTERSIL) { - DPRINTF(("wi_watchdog: inquire scan\n")); - wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); - } + if (sc->sc_tx_timer && --sc->sc_tx_timer == 0) { + if_printf(ifp, "device timeout\n"); + ifp->if_oerrors++; + wi_init_locked(ifp->if_softc); + return; } - - /* TODO: rate control */ - callout_reset(&sc->sc_watchdog, hz, wi_watchdog, sc); } @@ -1235,17 +1177,11 @@ static int wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; - struct thread *td = curthread; -#if 0 - struct ifreq *ifr = (struct ifreq *)data; - struct wi_req wreq; -#endif - - if (sc->wi_gone) - return (ENODEV); + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; + WI_LOCK(sc); switch (cmd) { case SIOCSIFFLAGS: /* @@ -1253,234 +1189,54 @@ wi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) * changing is the promisc flag, try to short-circuit a call to * wi_init() by just setting PROMISC in the hardware. */ - WI_LOCK(sc); if (ifp->if_flags & IFF_UP) { if (ic->ic_opmode != IEEE80211_M_HOSTAP && ifp->if_drv_flags & IFF_DRV_RUNNING) { - if (ifp->if_flags & IFF_PROMISC && - !(sc->sc_if_flags & IFF_PROMISC)) { - wi_write_val(sc, WI_RID_PROMISC, 1); - } else if (!(ifp->if_flags & IFF_PROMISC) && - sc->sc_if_flags & IFF_PROMISC) { - wi_write_val(sc, WI_RID_PROMISC, 0); + if ((ifp->if_flags ^ sc->sc_if_flags) & IFF_PROMISC) { + wi_write_val(sc, WI_RID_PROMISC, + (ifp->if_flags & IFF_PROMISC) != 0); } else { - wi_init(sc); + wi_init_locked(sc); + startall = 1; } } else { - wi_init(sc); + wi_init_locked(sc); + startall = 1; } } else { - if (ifp->if_drv_flags & IFF_DRV_RUNNING) { - wi_stop(ifp, 1); - } + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + wi_stop_locked(sc, 1); sc->wi_gone = 0; } sc->sc_if_flags = ifp->if_flags; - WI_UNLOCK(sc); - error = 0; - break; - case SIOCADDMULTI: - case SIOCDELMULTI: - WI_LOCK(sc); - error = wi_write_multi(sc); - WI_UNLOCK(sc); break; -#if 0 - case SIOCGIFGENERIC: - WI_LOCK(sc); - error = wi_get_cfg(ifp, cmd, data); - WI_UNLOCK(sc); + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); break; - case SIOCSIFGENERIC: - error = priv_check(td, PRIV_DRIVER); - if (error == 0) - error = wi_set_cfg(ifp, cmd, data); - break; - case SIOCGPRISM2DEBUG: - error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); - if (error) - break; - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING) || - sc->sc_firmware_type == WI_LUCENT) { - error = EIO; - break; - } - error = wi_get_debug(sc, &wreq); - if (error == 0) - error = copyout(&wreq, ifr->ifr_data, sizeof(wreq)); - break; - case SIOCSPRISM2DEBUG: - if ((error = priv_check(td, PRIV_DRIVER))) - return (error); - error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); - if (error) - break; - WI_LOCK(sc); - error = wi_set_debug(sc, &wreq); - WI_UNLOCK(sc); - break; -#endif - case SIOCG80211: - error = wi_ioctl_get(ifp, cmd, data); - break; - case SIOCS80211: - error = priv_check(td, PRIV_NET80211_MANAGE); - if (error) - break; - error = wi_ioctl_set(ifp, cmd, data); - - - break; default: - error = ieee80211_ioctl(ic, cmd, data); - WI_LOCK(sc); - if (error == ENETRESET) { - if (sc->sc_enabled) - wi_init(sc); /* XXX no error return */ - error = 0; - } - WI_UNLOCK(sc); - break; - } - return (error); -} - -static int -wi_ioctl_get(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - int error; - struct wi_softc *sc; - struct ieee80211req *ireq; - struct ieee80211com *ic; - - - sc = ifp->if_softc; - ic = &sc->sc_ic; - ireq = (struct ieee80211req *) data; - - switch (ireq->i_type) { - case IEEE80211_IOC_STATIONNAME: - ireq->i_len = sc->sc_nodelen + 1; - error = copyout(sc->sc_nodename, ireq->i_data, - ireq->i_len); - break; - default: - error = ieee80211_ioctl(ic, cmd, data); - WI_LOCK(sc); - if (error == ENETRESET) { - if (sc->sc_enabled) - wi_init(sc); /* XXX no error return */ - error = 0; - } - WI_UNLOCK(sc); - - break; - } - - return (error); -} - -static int -wi_ioctl_set(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - int error; - struct wi_softc *sc; - struct ieee80211req *ireq; - u_int8_t nodename[IEEE80211_NWID_LEN]; - - sc = ifp->if_softc; - ireq = (struct ieee80211req *) data; - switch (ireq->i_type) { - case IEEE80211_IOC_STATIONNAME: - if (ireq->i_val != 0 || - ireq->i_len > IEEE80211_NWID_LEN) { - error = EINVAL; - break; - } - memset(nodename, 0, IEEE80211_NWID_LEN); - error = copyin(ireq->i_data, nodename, ireq->i_len); - if (error) - break; - WI_LOCK(sc); - if (sc->sc_enabled) { - error = wi_write_ssid(sc, WI_RID_NODENAME, - nodename, ireq->i_len); - } - if (error == 0) { - memcpy(sc->sc_nodename, nodename, - IEEE80211_NWID_LEN); - sc->sc_nodelen = ireq->i_len; - } - WI_UNLOCK(sc); - - break; - default: - error = ieee80211_ioctl(&sc->sc_ic, cmd, data); - WI_LOCK(sc); - if (error == ENETRESET) { - if (sc->sc_enabled) - wi_init(sc); /* XXX no error return */ - error = 0; - } - WI_UNLOCK(sc); + error = ether_ioctl(ifp, cmd, data); break; } + WI_UNLOCK(sc); - return (error); -} - -static struct ieee80211_node * -wi_node_alloc(struct ieee80211_node_table *nt) -{ - struct wi_node *rn; - - rn = malloc(sizeof (struct wi_node), M_80211_NODE, - M_NOWAIT | M_ZERO); - - return (rn != NULL) ? &rn->ni : NULL; -} - -static int -wi_media_change(struct ifnet *ifp) -{ - struct wi_softc *sc = ifp->if_softc; - int error; - - error = ieee80211_media_change(ifp); - if (error == ENETRESET) { - if (sc->sc_enabled) - wi_init(sc); /* XXX no error return */ - error = 0; - } + if (startall) + ieee80211_start_all(ic); return error; } static void wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) { - struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ifp->if_softc; + struct ieee80211com *ic = vap->iv_ic; + struct wi_softc *sc = ic->ic_ifp->if_softc; u_int16_t val; int rate, len; - if (sc->wi_gone) { /* hardware gone (e.g. ejected) */ - imr->ifm_active = IFM_IEEE80211 | IFM_NONE; - imr->ifm_status = 0; - return; - } - - imr->ifm_status = IFM_AVALID; - imr->ifm_active = IFM_IEEE80211; - if (!sc->sc_enabled) { /* port !enabled, have no status */ - imr->ifm_active |= IFM_NONE; - imr->ifm_status = IFM_AVALID; - return; - } - if (ic->ic_state == IEEE80211_S_RUN && - (sc->sc_flags & WI_FLAGS_OUTRANGE) == 0) - imr->ifm_status |= IFM_ACTIVE; len = sizeof(val); - if (wi_read_rid(sc, WI_RID_CUR_TX_RATE, &val, &len) == 0 && + if (sc->sc_enabled && + wi_read_rid(sc, WI_RID_CUR_TX_RATE, &val, &len) == 0 && len == sizeof(val)) { /* convert to 802.11 rate */ val = le16toh(val); @@ -1494,36 +1250,18 @@ wi_media_status(struct ifnet *ifp, struct ifmediareq *imr) else if (rate == 8*2) rate = 22; /* 11Mbps */ } - } else - rate = 0; - imr->ifm_active |= ieee80211_rate2media(ic, rate, IEEE80211_MODE_11B); - switch (ic->ic_opmode) { - case IEEE80211_M_STA: - break; - case IEEE80211_M_IBSS: - imr->ifm_active |= IFM_IEEE80211_ADHOC; - break; - case IEEE80211_M_AHDEMO: - imr->ifm_active |= IFM_IEEE80211_ADHOC | IFM_FLAG0; - break; - case IEEE80211_M_HOSTAP: - imr->ifm_active |= IFM_IEEE80211_HOSTAP; - break; - case IEEE80211_M_MONITOR: - imr->ifm_active |= IFM_IEEE80211_MONITOR; - break; - case IEEE80211_M_WDS: - /* XXXX */ - break; + vap->iv_bss->ni_txrate = rate; } + ieee80211_media_status(ifp, imr); } static void wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) { - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct ieee80211_node *ni = vap->iv_bss; if (IEEE80211_ADDR_EQ(new_bssid, ni->ni_bssid)) return; @@ -1544,102 +1282,20 @@ wi_sync_bssid(struct wi_softc *sc, u_int8_t new_bssid[IEEE80211_ADDR_LEN]) #if 0 /* * XXX hack; we should create a new node with the new bssid - * and replace the existing ic_bss with it but since we don't - * process management frames to collect state we cheat by - * reusing the existing node as we know wi_newstate will be - * called and it will overwrite the node state. - */ - ieee80211_sta_join(ic, ieee80211_ref_node(ni)); -#endif -} - -static void -wi_rx_monitor(struct wi_softc *sc, int fid) -{ - struct ifnet *ifp = sc->sc_ifp; - struct wi_frame *rx_frame; - struct mbuf *m; - int datlen, hdrlen; - - /* first allocate mbuf for packet storage */ - m = m_getcl(M_DONTWAIT, MT_DATA, 0); - if (m == NULL) { - ifp->if_ierrors++; - return; - } - - m->m_pkthdr.rcvif = ifp; - - /* now read wi_frame first so we know how much data to read */ - if (wi_read_bap(sc, fid, 0, mtod(m, caddr_t), sizeof(*rx_frame))) { - ifp->if_ierrors++; - goto done; - } - - rx_frame = mtod(m, struct wi_frame *); - - switch ((rx_frame->wi_status & WI_STAT_MAC_PORT) >> 8) { - case 7: - switch (rx_frame->wi_whdr.i_fc[0] & IEEE80211_FC0_TYPE_MASK) { - case IEEE80211_FC0_TYPE_DATA: - hdrlen = WI_DATA_HDRLEN; - datlen = rx_frame->wi_dat_len + WI_FCS_LEN; - break; - case IEEE80211_FC0_TYPE_MGT: - hdrlen = WI_MGMT_HDRLEN; - datlen = rx_frame->wi_dat_len + WI_FCS_LEN; - break; - case IEEE80211_FC0_TYPE_CTL: - /* - * prism2 cards don't pass control packets - * down properly or consistently, so we'll only - * pass down the header. - */ - hdrlen = WI_CTL_HDRLEN; - datlen = 0; - break; - default: - if_printf(ifp, "received packet of unknown type " - "on port 7\n"); - ifp->if_ierrors++; - goto done; - } - break; - case 0: - hdrlen = WI_DATA_HDRLEN; - datlen = rx_frame->wi_dat_len + WI_FCS_LEN; - break; - default: - if_printf(ifp, "received packet on invalid " - "port (wi_status=0x%x)\n", rx_frame->wi_status); - ifp->if_ierrors++; - goto done; - } - - if (hdrlen + datlen + 2 > MCLBYTES) { - if_printf(ifp, "oversized packet received " - "(wi_dat_len=%d, wi_status=0x%x)\n", - datlen, rx_frame->wi_status); - ifp->if_ierrors++; - goto done; - } - - if (wi_read_bap(sc, fid, hdrlen, mtod(m, caddr_t) + hdrlen, - datlen + 2) == 0) { - m->m_pkthdr.len = m->m_len = hdrlen + datlen; - ifp->if_ipackets++; - BPF_MTAP(ifp, m); /* Handle BPF listeners. */ - } else - ifp->if_ierrors++; -done: - m_freem(m); + * and replace the existing ic_bss with it but since we don't + * process management frames to collect state we cheat by + * reusing the existing node as we know wi_newstate will be + * called and it will overwrite the node state. + */ + ieee80211_sta_join(ic, ieee80211_ref_node(ni)); +#endif } -static void +static __noinline void wi_rx_intr(struct wi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wi_frame frmhdr; struct mbuf *m; struct ieee80211_frame *wh; @@ -1651,16 +1307,6 @@ wi_rx_intr(struct wi_softc *sc) fid = CSR_READ_2(sc, WI_RX_FID); - if (sc->wi_debug.wi_monitor) { - /* - * If we are in monitor mode just - * read the data from the device. - */ - wi_rx_monitor(sc, fid); - CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - return; - } - /* First read in the frame header */ if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr))) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); @@ -1669,9 +1315,6 @@ wi_rx_intr(struct wi_softc *sc) return; } - if (IFF_DUMPPKTS(ifp)) - wi_dump_pkt(&frmhdr, NULL, frmhdr.wi_rx_signal); - /* * Drop undecryptable or packets with receive errors here */ @@ -1703,24 +1346,16 @@ wi_rx_intr(struct wi_softc *sc) len = 0; } - MGETHDR(m, M_DONTWAIT, MT_DATA); + if (off + len > MHLEN) + m = m_getcl(M_DONTWAIT, MT_DATA, M_PKTHDR); + else + m = m_gethdr(M_DONTWAIT, MT_DATA); if (m == NULL) { CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); ifp->if_ierrors++; DPRINTF(("wi_rx_intr: MGET failed\n")); return; } - if (off + len > MHLEN) { - MCLGET(m, M_DONTWAIT); - if ((m->m_flags & M_EXT) == 0) { - CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); - m_freem(m); - ifp->if_ierrors++; - DPRINTF(("wi_rx_intr: MCLGET failed\n")); - return; - } - } - m->m_data += off - sizeof(struct ieee80211_frame); memcpy(m->m_data, &frmhdr.wi_whdr, sizeof(struct ieee80211_frame)); wi_read_bap(sc, fid, sizeof(frmhdr), @@ -1730,8 +1365,7 @@ wi_rx_intr(struct wi_softc *sc) CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_RX); -#if NBPFILTER > 0 - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { /* XXX replace divide by table */ sc->sc_rx_th.wr_rate = frmhdr.wi_rx_rate / 5; sc->sc_rx_th.wr_antsignal = frmhdr.wi_rx_signal; @@ -1739,49 +1373,30 @@ wi_rx_intr(struct wi_softc *sc) sc->sc_rx_th.wr_flags = 0; if (frmhdr.wi_status & WI_STAT_PCF) sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_CFP; - /* XXX IEEE80211_RADIOTAP_F_WEP */ - bpf_mtap2(sc->sc_drvbpf, - &sc->sc_rx_th, sc->sc_rx_th_len, m); - } -#endif - wh = mtod(m, struct ieee80211_frame *); - if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - /* - * WEP is decrypted by hardware and the IV - * is stripped. Clear WEP bit so we don't - * try to process it in ieee80211_input. - * XXX fix for TKIP, et. al. - */ - wh->i_fc[1] &= ~IEEE80211_FC1_WEP; + if (m->m_flags & M_WEP) + sc->sc_rx_th.wr_flags |= IEEE80211_RADIOTAP_F_WEP; + bpf_mtap2(ifp->if_bpf, &sc->sc_rx_th, sc->sc_rx_th_len, m); } /* synchronize driver's BSSID with firmware's BSSID */ + wh = mtod(m, struct ieee80211_frame *); dir = wh->i_fc[1] & IEEE80211_FC1_DIR_MASK; if (ic->ic_opmode == IEEE80211_M_IBSS && dir == IEEE80211_FC1_DIR_NODS) wi_sync_bssid(sc, wh->i_addr3); WI_UNLOCK(sc); - /* - * Locate the node for sender, track state, and - * then pass this node (referenced) up to the 802.11 - * layer for its use. - */ - ni = ieee80211_find_rxnode(ic, (struct ieee80211_frame_min *) wh); - /* - * Send frame up for processing. - */ - ieee80211_input(ic, m, ni, rssi, -95/*XXXXwi_rx_silence?*/, rstamp); - /* - * The frame may have caused the node to be marked for - * reclamation (e.g. in response to a DEAUTH message) - * so use free_node here instead of unref_node. - */ - ieee80211_free_node(ni); + + ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + (void) ieee80211_input(ni, m, rssi, -95/*XXX*/, rstamp); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, rssi, -95/*XXX*/, rstamp); WI_LOCK(sc); } -static void +static __noinline void wi_tx_ex_intr(struct wi_softc *sc) { struct ifnet *ifp = sc->sc_ifp; @@ -1792,7 +1407,6 @@ wi_tx_ex_intr(struct wi_softc *sc) /* Read in the frame header */ if (wi_read_bap(sc, fid, 0, &frmhdr, sizeof(frmhdr)) == 0) { u_int16_t status = le16toh(frmhdr.wi_status); - /* * Spontaneous station disconnects appear as xmit * errors. Don't announce them and/or count them @@ -1825,7 +1439,7 @@ wi_tx_ex_intr(struct wi_softc *sc) CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_TX_EXC); } -static void +static __noinline void wi_tx_intr(struct wi_softc *sc) { struct ifnet *ifp = sc->sc_ifp; @@ -1860,10 +1474,52 @@ wi_tx_intr(struct wi_softc *sc) } static void +wi_status_connected(void *arg, int pending) +{ + struct ieee80211vap *vap = arg; + struct ieee80211com *ic = vap->iv_ic; + + IEEE80211_LOCK(ic); + WI_VAP(vap)->wv_newstate(vap, IEEE80211_S_RUN, 0); + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, IEEE80211_S_RUN, 0); + IEEE80211_UNLOCK(ic); +} + +static void +wi_status_disconnected(void *arg, int pending) +{ + struct ieee80211vap *vap = arg; + + if (vap->iv_state == IEEE80211_S_RUN) { + vap->iv_stats.is_rx_deauth++; + ieee80211_new_state(vap, IEEE80211_S_SCAN, 0); + } +} + +static void +wi_status_oor(void *arg, int pending) +{ + struct ieee80211com *ic = arg; + + ieee80211_beacon_miss(ic); +} + +static void +wi_status_assoc_failed(void *arg, int pending) +{ + struct ieee80211vap *vap = arg; + + ieee80211_new_state(vap, IEEE80211_S_SCAN, IEEE80211_SCAN_FAIL_TIMEOUT); +} + +static __noinline void wi_info_intr(struct wi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + struct wi_vap *wvp = WI_VAP(vap); int i, fid, len, off; u_int16_t ltbuf[2]; u_int16_t stat; @@ -1873,42 +1529,35 @@ wi_info_intr(struct wi_softc *sc) wi_read_bap(sc, fid, 0, ltbuf, sizeof(ltbuf)); switch (le16toh(ltbuf[1])) { - case WI_INFO_LINK_STAT: wi_read_bap(sc, fid, sizeof(ltbuf), &stat, sizeof(stat)); DPRINTF(("wi_info_intr: LINK_STAT 0x%x\n", le16toh(stat))); switch (le16toh(stat)) { case WI_INFO_LINK_STAT_CONNECTED: - sc->sc_flags &= ~WI_FLAGS_OUTRANGE; - if (ic->ic_state == IEEE80211_S_RUN && - ic->ic_opmode != IEEE80211_M_IBSS) + if (vap->iv_state == IEEE80211_S_RUN && + vap->iv_opmode != IEEE80211_M_IBSS) break; - /* FALLTHROUGH */ + /* fall thru... */ case WI_INFO_LINK_STAT_AP_CHG: - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); + taskqueue_enqueue(taskqueue_swi, &wvp->wv_connected_task); break; case WI_INFO_LINK_STAT_AP_INR: - sc->sc_flags &= ~WI_FLAGS_OUTRANGE; + break; + case WI_INFO_LINK_STAT_DISCONNECTED: + /* we dropped off the net; e.g. due to deauth/disassoc */ + taskqueue_enqueue(taskqueue_swi, &wvp->wv_disconnected_task); break; case WI_INFO_LINK_STAT_AP_OOR: - if (sc->sc_firmware_type == WI_SYMBOL && - sc->sc_scan_timer > 0) { - if (wi_cmd(sc, WI_CMD_INQUIRE, - WI_INFO_HOST_SCAN_RESULTS, 0, 0) != 0) - sc->sc_scan_timer = 0; - break; - } - if (ic->ic_opmode == IEEE80211_M_STA) - sc->sc_flags |= WI_FLAGS_OUTRANGE; + /* XXX does this need to be per-vap? */ + taskqueue_enqueue(taskqueue_swi, &sc->sc_oor_task); break; - case WI_INFO_LINK_STAT_DISCONNECTED: case WI_INFO_LINK_STAT_ASSOC_FAILED: - if (ic->ic_opmode == IEEE80211_M_STA) - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); + if (vap->iv_opmode == IEEE80211_M_STA) + taskqueue_enqueue(taskqueue_swi, + &wvp->wv_assoc_failed_task); break; } break; - case WI_INFO_COUNTERS: /* some card versions have a larger stats structure */ len = min(le16toh(ltbuf[0]) - 1, sizeof(sc->sc_stats) / 4); @@ -1926,13 +1575,6 @@ wi_info_intr(struct wi_softc *sc) sc->sc_stats.wi_tx_multi_retries + sc->sc_stats.wi_tx_retry_limit; break; - - case WI_INFO_SCAN_RESULTS: - case WI_INFO_HOST_SCAN_RESULTS: - wi_scan_result(sc, fid, le16toh(ltbuf[0])); - ieee80211_scan_done(ic); - break; - default: DPRINTF(("wi_info_intr: got fid %x type %x len %d\n", fid, le16toh(ltbuf[1]), le16toh(ltbuf[0]))); @@ -1973,6 +1615,12 @@ allmulti: } static void +wi_update_mcast(struct ifnet *ifp) +{ + wi_write_multi(ifp->if_softc); +} + +static void wi_read_nicid(struct wi_softc *sc) { struct wi_card_ident *id; @@ -2058,507 +1706,42 @@ wi_write_ssid(struct wi_softc *sc, int rid, u_int8_t *buf, int buflen) if (buflen > IEEE80211_NWID_LEN) return ENOBUFS; memset(&ssid, 0, sizeof(ssid)); - ssid.wi_len = htole16(buflen); - memcpy(ssid.wi_ssid, buf, buflen); - return wi_write_rid(sc, rid, &ssid, sizeof(ssid)); -} - -#if 0 -static int -wi_get_cfg(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct ifreq *ifr = (struct ifreq *)data; - struct wi_req wreq; - struct wi_scan_res *res; - size_t reslen; - int len, n, error, mif, val, off, i; - - error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); - if (error) - return error; - len = (wreq.wi_len - 1) * 2; - if (len < sizeof(u_int16_t)) - return ENOSPC; - if (len > sizeof(wreq.wi_val)) - len = sizeof(wreq.wi_val); - - switch (wreq.wi_type) { - - case WI_RID_IFACE_STATS: - memcpy(wreq.wi_val, &sc->sc_stats, sizeof(sc->sc_stats)); - if (len < sizeof(sc->sc_stats)) - error = ENOSPC; - else - len = sizeof(sc->sc_stats); - break; - - case WI_RID_ENCRYPTION: - case WI_RID_TX_CRYPT_KEY: - case WI_RID_DEFLT_CRYPT_KEYS: - case WI_RID_TX_RATE: - return ieee80211_ioctl(ic, cmd, data); - - case WI_RID_MICROWAVE_OVEN: - if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_MOR)) { - error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, - &len); - break; - } - wreq.wi_val[0] = htole16(sc->sc_microwave_oven); - len = sizeof(u_int16_t); - break; - - case WI_RID_DBM_ADJUST: - if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_DBMADJUST)) { - error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, - &len); - break; - } - wreq.wi_val[0] = htole16(sc->sc_dbm_offset); - len = sizeof(u_int16_t); - break; - - case WI_RID_ROAMING_MODE: - if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_ROAMING)) { - error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, - &len); - break; - } - wreq.wi_val[0] = htole16(sc->sc_roaming_mode); - len = sizeof(u_int16_t); - break; - - case WI_RID_SYSTEM_SCALE: - if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE)) { - error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, - &len); - break; - } - wreq.wi_val[0] = htole16(sc->sc_system_scale); - len = sizeof(u_int16_t); - break; - - case WI_RID_FRAG_THRESH: - if (sc->sc_enabled && (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR)) { - error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, - &len); - break; - } - wreq.wi_val[0] = htole16(ic->ic_fragthreshold); - len = sizeof(u_int16_t); - break; - - case WI_RID_READ_APS: - if (ic->ic_opmode == IEEE80211_M_HOSTAP) - return ieee80211_ioctl(ic, cmd, data); - if (sc->sc_scan_timer > 0) { - error = EINPROGRESS; - break; - } - n = sc->sc_naps; - if (len < sizeof(n)) { - error = ENOSPC; - break; - } - if (len < sizeof(n) + sizeof(struct wi_apinfo) * n) - n = (len - sizeof(n)) / sizeof(struct wi_apinfo); - len = sizeof(n) + sizeof(struct wi_apinfo) * n; - memcpy(wreq.wi_val, &n, sizeof(n)); - memcpy((caddr_t)wreq.wi_val + sizeof(n), sc->sc_aps, - sizeof(struct wi_apinfo) * n); - break; - - case WI_RID_PRISM2: - wreq.wi_val[0] = sc->sc_firmware_type != WI_LUCENT; - len = sizeof(u_int16_t); - break; - - case WI_RID_MIF: - mif = wreq.wi_val[0]; - error = wi_cmd(sc, WI_CMD_READMIF, mif, 0, 0); - val = CSR_READ_2(sc, WI_RESP0); - wreq.wi_val[0] = val; - len = sizeof(u_int16_t); - break; - - case WI_RID_ZERO_CACHE: - case WI_RID_PROCFRAME: /* ignore for compatibility */ - /* XXX ??? */ - break; - - case WI_RID_READ_CACHE: - return ieee80211_ioctl(ic, cmd, data); - - case WI_RID_SCAN_RES: /* compatibility interface */ - if (ic->ic_opmode == IEEE80211_M_HOSTAP) - return ieee80211_ioctl(ic, cmd, data); - if (sc->sc_scan_timer > 0) { - error = EINPROGRESS; - break; - } - n = sc->sc_naps; - if (sc->sc_firmware_type == WI_LUCENT) { - off = 0; - reslen = WI_WAVELAN_RES_SIZE; - } else { - off = sizeof(struct wi_scan_p2_hdr); - reslen = WI_PRISM2_RES_SIZE; - } - if (len < off + reslen * n) - n = (len - off) / reslen; - len = off + reslen * n; - if (off != 0) { - struct wi_scan_p2_hdr *p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; - /* - * Prepend Prism-specific header. - */ - if (len < sizeof(struct wi_scan_p2_hdr)) { - error = ENOSPC; - break; - } - p2 = (struct wi_scan_p2_hdr *)wreq.wi_val; - p2->wi_rsvd = 0; - p2->wi_reason = n; /* XXX */ - } - for (i = 0; i < n; i++, off += reslen) { - const struct wi_apinfo *ap = &sc->sc_aps[i]; - - res = (struct wi_scan_res *)((char *)wreq.wi_val + off); - res->wi_chan = ap->channel; - res->wi_noise = ap->noise; - res->wi_signal = ap->signal; - IEEE80211_ADDR_COPY(res->wi_bssid, ap->bssid); - res->wi_interval = ap->interval; - res->wi_capinfo = ap->capinfo; - res->wi_ssid_len = ap->namelen; - memcpy(res->wi_ssid, ap->name, - IEEE80211_NWID_LEN); - if (sc->sc_firmware_type != WI_LUCENT) { - /* XXX not saved from Prism cards */ - memset(res->wi_srates, 0, - sizeof(res->wi_srates)); - res->wi_rate = ap->rate; - res->wi_rsvd = 0; - } - } - break; - - default: - if (sc->sc_enabled) { - error = wi_read_rid(sc, wreq.wi_type, wreq.wi_val, - &len); - break; - } - switch (wreq.wi_type) { - case WI_RID_MAX_DATALEN: - wreq.wi_val[0] = htole16(sc->sc_max_datalen); - len = sizeof(u_int16_t); - break; - case WI_RID_RTS_THRESH: - wreq.wi_val[0] = htole16(ic->ic_rtsthreshold); - len = sizeof(u_int16_t); - break; - case WI_RID_CNFAUTHMODE: - wreq.wi_val[0] = htole16(sc->sc_cnfauthmode); - len = sizeof(u_int16_t); - break; - case WI_RID_NODENAME: - if (len < sc->sc_nodelen + sizeof(u_int16_t)) { - error = ENOSPC; - break; - } - len = sc->sc_nodelen + sizeof(u_int16_t); - wreq.wi_val[0] = htole16((sc->sc_nodelen + 1) / 2); - memcpy(&wreq.wi_val[1], sc->sc_nodename, - sc->sc_nodelen); - break; - default: - return ieee80211_ioctl(ic, cmd, data); - } - break; - } - if (error) - return error; - wreq.wi_len = (len + 1) / 2 + 1; - return copyout(&wreq, ifr->ifr_data, (wreq.wi_len + 1) * 2); -} - -static int -wi_set_cfg(struct ifnet *ifp, u_long cmd, caddr_t data) -{ - struct wi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - struct ifreq *ifr = (struct ifreq *)data; - struct wi_req wreq; - struct mbuf *m; - int i, len, error, mif, val; - struct ieee80211_rateset *rs; - - error = copyin(ifr->ifr_data, &wreq, sizeof(wreq)); - if (error) - return error; - len = wreq.wi_len ? (wreq.wi_len - 1) * 2 : 0; - switch (wreq.wi_type) { - case WI_RID_DBM_ADJUST: - return ENODEV; - - case WI_RID_NODENAME: - if (le16toh(wreq.wi_val[0]) * 2 > len || - le16toh(wreq.wi_val[0]) > sizeof(sc->sc_nodename)) { - error = ENOSPC; - break; - } - WI_LOCK(sc); - if (sc->sc_enabled) - error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, - len); - if (error == 0) { - sc->sc_nodelen = le16toh(wreq.wi_val[0]) * 2; - memcpy(sc->sc_nodename, &wreq.wi_val[1], - sc->sc_nodelen); - } - WI_UNLOCK(sc); - break; - - case WI_RID_MICROWAVE_OVEN: - case WI_RID_ROAMING_MODE: - case WI_RID_SYSTEM_SCALE: - case WI_RID_FRAG_THRESH: - /* XXX unlocked reads */ - if (wreq.wi_type == WI_RID_MICROWAVE_OVEN && - (sc->sc_flags & WI_FLAGS_HAS_MOR) == 0) - break; - if (wreq.wi_type == WI_RID_ROAMING_MODE && - (sc->sc_flags & WI_FLAGS_HAS_ROAMING) == 0) - break; - if (wreq.wi_type == WI_RID_SYSTEM_SCALE && - (sc->sc_flags & WI_FLAGS_HAS_SYSSCALE) == 0) - break; - if (wreq.wi_type == WI_RID_FRAG_THRESH && - (sc->sc_flags & WI_FLAGS_HAS_FRAGTHR) == 0) - break; - /* FALLTHROUGH */ - case WI_RID_RTS_THRESH: - case WI_RID_CNFAUTHMODE: - case WI_RID_MAX_DATALEN: - WI_LOCK(sc); - if (sc->sc_enabled) { - error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, - sizeof(u_int16_t)); - if (error != 0) { - WI_UNLOCK(sc); - break; - } - } - switch (wreq.wi_type) { - case WI_RID_FRAG_THRESH: - ic->ic_fragthreshold = le16toh(wreq.wi_val[0]); - break; - case WI_RID_RTS_THRESH: - ic->ic_rtsthreshold = le16toh(wreq.wi_val[0]); - break; - case WI_RID_MICROWAVE_OVEN: - sc->sc_microwave_oven = le16toh(wreq.wi_val[0]); - break; - case WI_RID_ROAMING_MODE: - sc->sc_roaming_mode = le16toh(wreq.wi_val[0]); - break; - case WI_RID_SYSTEM_SCALE: - sc->sc_system_scale = le16toh(wreq.wi_val[0]); - break; - case WI_RID_CNFAUTHMODE: - sc->sc_cnfauthmode = le16toh(wreq.wi_val[0]); - break; - case WI_RID_MAX_DATALEN: - sc->sc_max_datalen = le16toh(wreq.wi_val[0]); - break; - } - WI_UNLOCK(sc); - break; - - case WI_RID_TX_RATE: - WI_LOCK(sc); - switch (le16toh(wreq.wi_val[0])) { - case 3: - ic->ic_fixed_rate = IEEE80211_FIXED_RATE_NONE; - break; - default: - rs = &ic->ic_sup_rates[IEEE80211_MODE_11B]; - for (i = 0; i < rs->rs_nrates; i++) { - if ((rs->rs_rates[i] & IEEE80211_RATE_VAL) - / 2 == le16toh(wreq.wi_val[0])) - break; - } - if (i == rs->rs_nrates) { - WI_UNLOCK(sc); - return EINVAL; - } - ic->ic_fixed_rate = rs->rs_rates[i] & IEEE80211_RATE_VAL; - } - if (sc->sc_enabled) - error = wi_write_txrate(sc); - WI_UNLOCK(sc); - break; - - case WI_RID_SCAN_APS: - WI_LOCK(sc); - if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP) - error = wi_scan_ap(sc, 0x3fff, 0x000f); - WI_UNLOCK(sc); - break; - - case WI_RID_SCAN_REQ: /* compatibility interface */ - WI_LOCK(sc); - if (sc->sc_enabled && ic->ic_opmode != IEEE80211_M_HOSTAP) - error = wi_scan_ap(sc, wreq.wi_val[0], wreq.wi_val[1]); - WI_UNLOCK(sc); - break; - - case WI_RID_MGMT_XMIT: - WI_LOCK(sc); - if (!sc->sc_enabled) - error = ENETDOWN; - else if (ic->ic_mgtq.ifq_len > 5) - error = EAGAIN; - else { - /* NB: m_devget uses M_DONTWAIT so can hold the lock */ - /* XXX wi_len looks in u_int8_t, not in u_int16_t */ - m = m_devget((char *)&wreq.wi_val, wreq.wi_len, 0, - ifp, NULL); - if (m != NULL) - IF_ENQUEUE(&ic->ic_mgtq, m); - else - error = ENOMEM; - } - WI_UNLOCK(sc); - break; - - case WI_RID_MIF: - mif = wreq.wi_val[0]; - val = wreq.wi_val[1]; - WI_LOCK(sc); - error = wi_cmd(sc, WI_CMD_WRITEMIF, mif, val, 0); - WI_UNLOCK(sc); - break; - - case WI_RID_PROCFRAME: /* ignore for compatibility */ - break; - - case WI_RID_OWN_SSID: - if (le16toh(wreq.wi_val[0]) * 2 > len || - le16toh(wreq.wi_val[0]) > IEEE80211_NWID_LEN) { - error = ENOSPC; - break; - } - WI_LOCK(sc); - memset(ic->ic_des_ssid[0].ssid, 0, IEEE80211_NWID_LEN); - ic->ic_des_ssid[0].len = le16toh(wreq.wi_val[0]) * 2; - memcpy(ic->ic_des_ssid[0].ssid, &wreq.wi_val[1], - ic->ic_des_ssid[0].len); - if (sc->sc_enabled) - wi_init(sc); /* XXX no error return */ - WI_UNLOCK(sc); - break; - - default: - WI_LOCK(sc); - if (sc->sc_enabled) - error = wi_write_rid(sc, wreq.wi_type, wreq.wi_val, - len); - if (error == 0) { - /* XXX ieee80211_ioctl does a copyin */ - error = ieee80211_ioctl(ic, cmd, data); - if (error == ENETRESET) { - if (sc->sc_enabled) - wi_init(sc); - error = 0; - } - } - WI_UNLOCK(sc); - break; - } - return error; -} -#endif - -static int -wi_write_txrate(struct wi_softc *sc) -{ - struct ieee80211com *ic = &sc->sc_ic; - int i; - u_int16_t rate; - - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) - rate = 0; /* auto */ - else - rate = ic->ic_fixed_rate / 2; - - /* rate: 0, 1, 2, 5, 11 */ - - switch (sc->sc_firmware_type) { - case WI_LUCENT: - switch (rate) { - case 0: /* auto == 11mbps auto */ - rate = 3; - break; - /* case 1, 2 map to 1, 2*/ - case 5: /* 5.5Mbps -> 4 */ - rate = 4; - break; - case 11: /* 11mbps -> 5 */ - rate = 5; - break; - default: - break; - } - break; - default: - /* Choose a bit according to this table. - * - * bit | data rate - * ----+------------------- - * 0 | 1Mbps - * 1 | 2Mbps - * 2 | 5.5Mbps - * 3 | 11Mbps - */ - for (i = 8; i > 0; i >>= 1) { - if (rate >= i) - break; - } - if (i == 0) - rate = 0xf; /* auto */ - else - rate = i; - break; - } - return wi_write_val(sc, WI_RID_TX_RATE, rate); + ssid.wi_len = htole16(buflen); + memcpy(ssid.wi_ssid, buf, buflen); + return wi_write_rid(sc, rid, &ssid, sizeof(ssid)); } static int -wi_key_alloc(struct ieee80211com *ic, const struct ieee80211_key *k, - ieee80211_keyix *keyix, ieee80211_keyix *rxkeyix) +wi_write_txrate(struct wi_softc *sc, struct ieee80211vap *vap) { - struct wi_softc *sc = ic->ic_ifp->if_softc; - - /* - * When doing host encryption of outbound frames fail requests - * for keys that are not marked w/ the SWCRYPT flag so the - * net80211 layer falls back to s/w crypto. Note that we also - * fixup existing keys below to handle mode changes. - */ - if ((sc->sc_encryption & HOST_ENCRYPT) && - (k->wk_flags & IEEE80211_KEY_SWCRYPT) == 0) - return 0; - return sc->sc_key_alloc(ic, k, keyix, rxkeyix); + static const uint16_t lucent_rates[12] = { + [ 0] = 3, /* auto */ + [ 1] = 1, /* 1Mb/s */ + [ 2] = 2, /* 2Mb/s */ + [ 5] = 4, /* 5.5Mb/s */ + [11] = 5 /* 11Mb/s */ + }; + static const uint16_t intersil_rates[12] = { + [ 0] = 0xf, /* auto */ + [ 1] = 0, /* 1Mb/s */ + [ 2] = 1, /* 2Mb/s */ + [ 5] = 2, /* 5.5Mb/s */ + [11] = 3, /* 11Mb/s */ + }; + const uint16_t *rates = sc->sc_firmware_type == WI_LUCENT ? + lucent_rates : intersil_rates; + struct ieee80211com *ic = vap->iv_ic; + const struct ieee80211_txparam *tp; + + tp = &vap->iv_txparms[ieee80211_chan2mode(ic->ic_bsschan)]; + return wi_write_val(sc, WI_RID_TX_RATE, + (tp->ucastrate == IEEE80211_FIXED_RATE_NONE ? + rates[0] : rates[tp->ucastrate / 2])); } static int -wi_write_wep(struct wi_softc *sc) +wi_write_wep(struct wi_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; int error = 0; int i, keylen; u_int16_t val; @@ -2566,20 +1749,20 @@ wi_write_wep(struct wi_softc *sc) switch (sc->sc_firmware_type) { case WI_LUCENT: - val = (ic->ic_flags & IEEE80211_F_PRIVACY) ? 1 : 0; + val = (vap->iv_flags & IEEE80211_F_PRIVACY) ? 1 : 0; error = wi_write_val(sc, WI_RID_ENCRYPTION, val); if (error) break; - if ((ic->ic_flags & IEEE80211_F_PRIVACY) == 0) + if ((vap->iv_flags & IEEE80211_F_PRIVACY) == 0) break; - error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, ic->ic_def_txkey); + error = wi_write_val(sc, WI_RID_TX_CRYPT_KEY, vap->iv_def_txkey); if (error) break; memset(wkey, 0, sizeof(wkey)); for (i = 0; i < IEEE80211_WEP_NKID; i++) { - keylen = ic->ic_nw_keys[i].wk_keylen; + keylen = vap->iv_nw_keys[i].wk_keylen; wkey[i].wi_keylen = htole16(keylen); - memcpy(wkey[i].wi_keydat, ic->ic_nw_keys[i].wk_key, + memcpy(wkey[i].wi_keydat, vap->iv_nw_keys[i].wk_key, keylen); } error = wi_write_rid(sc, WI_RID_DEFLT_CRYPT_KEYS, @@ -2588,8 +1771,8 @@ wi_write_wep(struct wi_softc *sc) break; case WI_INTERSIL: - case WI_SYMBOL: - if (ic->ic_flags & IEEE80211_F_PRIVACY) { + val = HOST_ENCRYPT | HOST_DECRYPT; + if (vap->iv_flags & IEEE80211_F_PRIVACY) { /* * ONLY HWB3163 EVAL-CARD Firmware version * less than 0.8 variant2 @@ -2599,25 +1782,15 @@ wi_write_wep(struct wi_softc *sc) * It is under investigation for details. * (ichiro@netbsd.org) */ - if (sc->sc_firmware_type == WI_INTERSIL && - sc->sc_sta_firmware_ver < 802 ) { + if (sc->sc_sta_firmware_ver < 802 ) { /* firm ver < 0.8 variant 2 */ wi_write_val(sc, WI_RID_PROMISC, 1); } wi_write_val(sc, WI_RID_CNFAUTHMODE, - sc->sc_cnfauthmode); - /* XXX should honor IEEE80211_F_DROPUNENC */ - val = PRIVACY_INVOKED | EXCLUDE_UNENCRYPTED; - /* - * Encryption firmware has a bug for HostAP mode. - */ - if (sc->sc_firmware_type == WI_INTERSIL && - ic->ic_opmode == IEEE80211_M_HOSTAP) - val |= HOST_ENCRYPT; + vap->iv_bss->ni_authmode); + val |= PRIVACY_INVOKED; } else { - wi_write_val(sc, WI_RID_CNFAUTHMODE, - IEEE80211_AUTH_OPEN); - val = HOST_ENCRYPT | HOST_DECRYPT; + wi_write_val(sc, WI_RID_CNFAUTHMODE, IEEE80211_AUTH_OPEN); } error = wi_write_val(sc, WI_RID_P2_ENCRYPTION, val); if (error) @@ -2625,55 +1798,17 @@ wi_write_wep(struct wi_softc *sc) sc->sc_encryption = val; if ((val & PRIVACY_INVOKED) == 0) break; - error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY, - ic->ic_def_txkey); - if (error) - break; - if (val & HOST_DECRYPT) - break; - /* - * It seems that the firmware accept 104bit key only if - * all the keys have 104bit length. We get the length of - * the transmit key and use it for all other keys. - * Perhaps we should use software WEP for such situation. - */ - if (ic->ic_def_txkey != IEEE80211_KEYIX_NONE) - keylen = ic->ic_nw_keys[ic->ic_def_txkey].wk_keylen; - else /* XXX should not hapen */ - keylen = IEEE80211_WEP_KEYLEN; - if (keylen > IEEE80211_WEP_KEYLEN) - keylen = 13; /* 104bit keys */ - else - keylen = IEEE80211_WEP_KEYLEN; - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - error = wi_write_rid(sc, WI_RID_P2_CRYPT_KEY0 + i, - ic->ic_nw_keys[i].wk_key, keylen); - if (error) - break; - } + error = wi_write_val(sc, WI_RID_P2_TX_CRYPT_KEY, vap->iv_def_txkey); break; } - /* - * XXX horrible hack; insure pre-existing keys are - * setup properly to do s/w crypto. - */ - for (i = 0; i < IEEE80211_WEP_NKID; i++) { - struct ieee80211_key *k = &ic->ic_nw_keys[i]; - if (k->wk_flags & IEEE80211_KEY_XMIT) { - if (sc->sc_encryption & HOST_ENCRYPT) - k->wk_flags |= IEEE80211_KEY_SWCRYPT; - else - k->wk_flags &= ~IEEE80211_KEY_SWCRYPT; - } - } return error; } static int wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2) { - int i, s = 0; - + int i, s = 0; + if (sc->wi_gone) return (ENODEV); @@ -2684,7 +1819,8 @@ wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2) DELAY(1*1000); /* 1ms */ } if (i == 0) { - device_printf(sc->sc_dev, "wi_cmd: busy bit won't clear.\n" ); + device_printf(sc->sc_dev, "%s: busy bit won't clear, cmd 0x%x\n", + __func__, cmd); sc->wi_gone = 1; return(ETIMEDOUT); } @@ -2717,8 +1853,8 @@ wi_cmd(struct wi_softc *sc, int cmd, int val0, int val1, int val2) } if (i == WI_TIMEOUT) { - device_printf(sc->sc_dev, - "timeout in wi_cmd 0x%04x; event status 0x%04x\n", cmd, s); + device_printf(sc->sc_dev, "%s: timeout on cmd 0x%04x; " + "event status 0x%04x\n", __func__, cmd, s); if (s == 0xffff) sc->wi_gone = 1; return(ETIMEDOUT); @@ -2739,8 +1875,8 @@ wi_seek_bap(struct wi_softc *sc, int id, int off) if ((status & WI_OFF_BUSY) == 0) break; if (i == WI_TIMEOUT) { - device_printf(sc->sc_dev, "timeout in wi_seek to %x/%x\n", - id, off); + device_printf(sc->sc_dev, "%s: timeout, id %x off %x\n", + __func__, id, off); sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ if (status == 0xffff) sc->wi_gone = 1; @@ -2749,7 +1885,8 @@ wi_seek_bap(struct wi_softc *sc, int id, int off) DELAY(1); } if (status & WI_OFF_ERR) { - device_printf(sc->sc_dev, "failed in wi_seek to %x/%x\n", id, off); + device_printf(sc->sc_dev, "%s: error, id %x off %x\n", + __func__, id, off); sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ return EIO; } @@ -2787,9 +1924,6 @@ wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) if (buflen == 0) return 0; -#ifdef WI_HERMES_AUTOINC_WAR - again: -#endif if (id != sc->sc_bap_id || off != sc->sc_bap_off) { if ((error = wi_seek_bap(sc, id, off)) != 0) return error; @@ -2800,33 +1934,6 @@ wi_write_bap(struct wi_softc *sc, int id, int off, void *buf, int buflen) CSR_WRITE_2(sc, WI_DATA0, ptr[i]); sc->sc_bap_off += cnt * 2; -#ifdef WI_HERMES_AUTOINC_WAR - /* - * According to the comments in the HCF Light code, there is a bug - * in the Hermes (or possibly in certain Hermes firmware revisions) - * where the chip's internal autoincrement counter gets thrown off - * during data writes: the autoincrement is missed, causing one - * data word to be overwritten and subsequent words to be written to - * the wrong memory locations. The end result is that we could end - * up transmitting bogus frames without realizing it. The workaround - * for this is to write a couple of extra guard words after the end - * of the transfer, then attempt to read then back. If we fail to - * locate the guard words where we expect them, we preform the - * transfer over again. - */ - if ((sc->sc_flags & WI_FLAGS_BUG_AUTOINC) && (id & 0xf000) == 0) { - CSR_WRITE_2(sc, WI_DATA0, 0x1234); - CSR_WRITE_2(sc, WI_DATA0, 0x5678); - wi_seek_bap(sc, id, sc->sc_bap_off); - sc->sc_bap_off = WI_OFF_ERR; /* invalidate */ - if (CSR_READ_2(sc, WI_DATA0) != 0x1234 || - CSR_READ_2(sc, WI_DATA0) != 0x5678) { - device_printf(sc->sc_dev, - "detect auto increment bug, try again\n"); - goto again; - } - } -#endif return 0; } @@ -2863,8 +1970,8 @@ wi_alloc_fid(struct wi_softc *sc, int len, int *idp) int i; if (wi_cmd(sc, WI_CMD_ALLOC_MEM, len, 0, 0)) { - device_printf(sc->sc_dev, "failed to allocate %d bytes on NIC\n", - len); + device_printf(sc->sc_dev, "%s: failed to allocate %d bytes on NIC\n", + __func__, len); return ENOMEM; } @@ -2874,7 +1981,7 @@ wi_alloc_fid(struct wi_softc *sc, int len, int *idp) DELAY(1); } if (i == WI_TIMEOUT) { - device_printf(sc->sc_dev, "timeout in alloc\n"); + device_printf(sc->sc_dev, "%s: timeout in alloc\n", __func__); return ETIMEDOUT; } *idp = CSR_READ_2(sc, WI_ALLOC_FID); @@ -2923,251 +2030,33 @@ wi_write_rid(struct wi_softc *sc, int rid, void *buf, int buflen) ltbuf[1] = htole16(rid); error = wi_write_bap(sc, rid, 0, ltbuf, sizeof(ltbuf)); - if (error) + if (error) { + device_printf(sc->sc_dev, "%s: bap0 write failure, rid 0x%x\n", + __func__, rid); return error; + } error = wi_write_bap(sc, rid, sizeof(ltbuf), buf, buflen); - if (error) + if (error) { + device_printf(sc->sc_dev, "%s: bap1 write failure, rid 0x%x\n", + __func__, rid); return error; + } return wi_cmd(sc, WI_CMD_ACCESS | WI_ACCESS_WRITE, rid, 0, 0); } static int -wi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) -{ - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; - struct ieee80211_node *ni; - int buflen; - u_int16_t val; - struct wi_ssid ssid; - u_int8_t old_bssid[IEEE80211_ADDR_LEN]; - - DPRINTF(("%s: %s -> %s\n", __func__, - ieee80211_state_name[ic->ic_state], - ieee80211_state_name[nstate])); - - /* - * Internal to the driver the INIT and RUN states are used - * so bypass the net80211 state machine for other states. - * Beware however that this requires use to net80211 state - * management that otherwise would be handled for us. - */ - switch (nstate) { - case IEEE80211_S_INIT: - sc->sc_flags &= ~WI_FLAGS_OUTRANGE; - return (*sc->sc_newstate)(ic, nstate, arg); - - case IEEE80211_S_SCAN: - return (*sc->sc_newstate)(ic, nstate, arg); - - case IEEE80211_S_AUTH: - case IEEE80211_S_ASSOC: - ic->ic_state = nstate; /* NB: skip normal ieee80211 handling */ - break; - - case IEEE80211_S_RUN: - ni = ic->ic_bss; - sc->sc_flags &= ~WI_FLAGS_OUTRANGE; - buflen = IEEE80211_ADDR_LEN; - IEEE80211_ADDR_COPY(old_bssid, ni->ni_bssid); - wi_read_rid(sc, WI_RID_CURRENT_BSSID, ni->ni_bssid, &buflen); - IEEE80211_ADDR_COPY(ni->ni_macaddr, ni->ni_bssid); - buflen = sizeof(val); - wi_read_rid(sc, WI_RID_CURRENT_CHAN, &val, &buflen); - ni->ni_chan = ieee80211_find_channel(ic, - ieee80211_ieee2mhz(val, IEEE80211_CHAN_B), - IEEE80211_CHAN_B); - if (ni->ni_chan == NULL) - ni->ni_chan = &ic->ic_channels[0]; - ic->ic_curchan = ic->ic_bsschan = ni->ni_chan; -#if NBPFILTER > 0 - sc->sc_tx_th.wt_chan_freq = sc->sc_rx_th.wr_chan_freq = - htole16(ni->ni_chan->ic_freq); - sc->sc_tx_th.wt_chan_flags = sc->sc_rx_th.wr_chan_flags = - htole16(ni->ni_chan->ic_flags); -#endif - /* - * XXX hack; unceremoniously clear - * IEEE80211_F_DROPUNENC when operating with - * wep enabled so we don't drop unencoded frames - * at the 802.11 layer. This is necessary because - * we must strip the WEP bit from the 802.11 header - * before passing frames to ieee80211_input because - * the card has already stripped the WEP crypto - * header from the packet. - */ - if (ic->ic_flags & IEEE80211_F_PRIVACY) - ic->ic_flags &= ~IEEE80211_F_DROPUNENC; - if (ic->ic_opmode != IEEE80211_M_HOSTAP) { - /* XXX check return value */ - buflen = sizeof(ssid); - wi_read_rid(sc, WI_RID_CURRENT_SSID, &ssid, &buflen); - ni->ni_esslen = le16toh(ssid.wi_len); - if (ni->ni_esslen > IEEE80211_NWID_LEN) - ni->ni_esslen = IEEE80211_NWID_LEN; /*XXX*/ - memcpy(ni->ni_essid, ssid.wi_ssid, ni->ni_esslen); - } - return (*sc->sc_newstate)(ic, nstate, arg); - default: - break; - } - return 0; -} - -static int -wi_scan_ap(struct wi_softc *sc, u_int16_t chanmask, u_int16_t txrate) -{ - int error = 0; - u_int16_t val[2]; - - if (!sc->sc_enabled) - return ENXIO; - switch (sc->sc_firmware_type) { - case WI_LUCENT: - (void)wi_cmd(sc, WI_CMD_INQUIRE, WI_INFO_SCAN_RESULTS, 0, 0); - break; - case WI_INTERSIL: - val[0] = htole16(chanmask); /* channel */ - val[1] = htole16(txrate); /* tx rate */ - error = wi_write_rid(sc, WI_RID_SCAN_REQ, val, sizeof(val)); - break; - case WI_SYMBOL: - /* - * XXX only supported on 3.x ? - */ - val[0] = BSCAN_BCAST | BSCAN_ONETIME; - error = wi_write_rid(sc, WI_RID_BCAST_SCAN_REQ, - val, sizeof(val[0])); - break; - } - if (error == 0) { - sc->sc_scan_timer = WI_SCAN_WAIT; - DPRINTF(("wi_scan_ap: start scanning, " - "chamask 0x%x txrate 0x%x\n", chanmask, txrate)); - } - return error; -} - -static void -wi_scan_result(struct wi_softc *sc, int fid, int cnt) -{ -#define N(a) (sizeof (a) / sizeof (a[0])) - int i, naps, off, szbuf; - struct wi_scan_header ws_hdr; /* Prism2 header */ - struct wi_scan_data_p2 ws_dat; /* Prism2 scantable*/ - struct wi_apinfo *ap; - struct ieee80211_scanparams sp; - struct ieee80211_frame wh; - static long rstamp; - struct ieee80211com *ic; - uint8_t ssid[2+IEEE80211_NWID_LEN]; - - ic = &sc->sc_ic; - rstamp++; - memset(&sp, 0, sizeof(sp)); - - off = sizeof(u_int16_t) * 2; - memset(&ws_hdr, 0, sizeof(ws_hdr)); - switch (sc->sc_firmware_type) { - case WI_INTERSIL: - wi_read_bap(sc, fid, off, &ws_hdr, sizeof(ws_hdr)); - off += sizeof(ws_hdr); - szbuf = sizeof(struct wi_scan_data_p2); - break; - case WI_SYMBOL: - szbuf = sizeof(struct wi_scan_data_p2) + 6; - break; - case WI_LUCENT: - szbuf = sizeof(struct wi_scan_data); - break; - default: - device_printf(sc->sc_dev, - "wi_scan_result: unknown firmware type %u\n", - sc->sc_firmware_type); - naps = 0; - goto done; - } - naps = (cnt * 2 + 2 - off) / szbuf; - if (naps > N(sc->sc_aps)) - naps = N(sc->sc_aps); - sc->sc_naps = naps; - /* Read Data */ - ap = sc->sc_aps; - memset(&ws_dat, 0, sizeof(ws_dat)); - - for (i = 0; i < naps; i++, ap++) { - uint8_t rates[2 + IEEE80211_RATE_MAXSIZE]; - uint16_t *bssid; - wi_read_bap(sc, fid, off, &ws_dat, - (sizeof(ws_dat) < szbuf ? sizeof(ws_dat) : szbuf)); - DPRINTF2(("wi_scan_result: #%d: off %d bssid %s\n", i, off, - ether_sprintf(ws_dat.wi_bssid))); - - off += szbuf; - ap->scanreason = le16toh(ws_hdr.wi_reason); - memcpy(ap->bssid, ws_dat.wi_bssid, sizeof(ap->bssid)); - - bssid = (uint16_t *)&ap->bssid; - if (bssid[0] == 0 && bssid[1] == 0 && bssid[2] == 0) - break; - - memcpy(wh.i_addr2, ws_dat.wi_bssid, sizeof(ap->bssid)); - memcpy(wh.i_addr3, ws_dat.wi_bssid, sizeof(ap->bssid)); - ap->channel = le16toh(ws_dat.wi_chid); - ap->signal = le16toh(ws_dat.wi_signal); - ap->noise = le16toh(ws_dat.wi_noise); - ap->quality = ap->signal - ap->noise; - sp.capinfo = ap->capinfo = le16toh(ws_dat.wi_capinfo); - sp.bintval = ap->interval = le16toh(ws_dat.wi_interval); - ap->rate = le16toh(ws_dat.wi_rate); - rates[1] = 1; - rates[2] = (uint8_t)ap->rate / 5; - ap->namelen = le16toh(ws_dat.wi_namelen); - if (ap->namelen > sizeof(ap->name)) - ap->namelen = sizeof(ap->name); - memcpy(ap->name, ws_dat.wi_name, ap->namelen); - sp.ssid = (uint8_t *)&ssid[0]; - memcpy(sp.ssid + 2, ap->name, ap->namelen); - sp.ssid[1] = ap->namelen; - sp.bchan = ap->channel; - sp.curchan = ieee80211_find_channel(ic, - ieee80211_ieee2mhz(ap->channel, IEEE80211_CHAN_B), - IEEE80211_CHAN_B); - if (sp.curchan == NULL) - sp.curchan = &ic->ic_channels[0]; - sp.rates = &rates[0]; - sp.tstamp = (uint8_t *)&rstamp; - DPRINTF(("calling add_scan, bssid %s chan %d signal %d\n", - ether_sprintf(ws_dat.wi_bssid), ap->channel, ap->signal)); - ieee80211_add_scan(ic, &sp, &wh, 0, ap->signal, ap->noise, rstamp); - } -done: - /* Done scanning */ - sc->sc_scan_timer = 0; - DPRINTF(("wi_scan_result: scan complete: ap %d\n", naps)); -#undef N -} - -static void -wi_dump_pkt(struct wi_frame *wh, struct ieee80211_node *ni, int rssi) +wi_write_appie(struct wi_softc *sc, int rid, const struct ieee80211_appie *ie) { - if (ni != NULL) - ieee80211_dump_pkt(ni->ni_ic, - (u_int8_t *) &wh->wi_whdr, sizeof(wh->wi_whdr), - ni->ni_rates.rs_rates[ni->ni_txrate] & IEEE80211_RATE_VAL, - rssi); - printf(" status 0x%x rx_tstamp1 %u rx_tstamp0 0x%u rx_silence %u\n", - le16toh(wh->wi_status), le16toh(wh->wi_rx_tstamp1), - le16toh(wh->wi_rx_tstamp0), wh->wi_rx_silence); - printf(" rx_signal %u rx_rate %u rx_flow %u\n", - wh->wi_rx_signal, wh->wi_rx_rate, wh->wi_rx_flow); - printf(" tx_rtry %u tx_rate %u tx_ctl 0x%x dat_len %u\n", - wh->wi_tx_rtry, wh->wi_tx_rate, - le16toh(wh->wi_tx_ctl), le16toh(wh->wi_dat_len)); - printf(" ehdr dst %6D src %6D type 0x%x\n", - wh->wi_ehdr.ether_dhost, ":", wh->wi_ehdr.ether_shost, ":", - wh->wi_ehdr.ether_type); + /* NB: 42 bytes is probably ok to have on the stack */ + char buf[sizeof(uint16_t) + 40]; + + if (ie->ie_len > 40) + return EINVAL; + /* NB: firmware requires 16-bit ie length before ie data */ + *(uint16_t *) buf = htole16(ie->ie_len); + memcpy(buf + sizeof(uint16_t), ie->ie_data, ie->ie_len); + return wi_write_rid(sc, rid, buf, ie->ie_len + sizeof(uint16_t)); } int @@ -3180,9 +2069,9 @@ wi_alloc(device_t dev, int rid) sc->iobase = bus_alloc_resource(dev, SYS_RES_IOPORT, &sc->iobase_rid, 0, ~0, (1 << 6), rman_make_alignment_flags(1 << 6) | RF_ACTIVE); - if (!sc->iobase) { + if (sc->iobase == NULL) { device_printf(dev, "No I/O space?!\n"); - return (ENXIO); + return ENXIO; } sc->wi_io_addr = rman_get_start(sc->iobase); @@ -3192,32 +2081,28 @@ wi_alloc(device_t dev, int rid) sc->mem_rid = rid; sc->mem = bus_alloc_resource_any(dev, SYS_RES_MEMORY, &sc->mem_rid, RF_ACTIVE); - - if (!sc->mem) { + if (sc->mem == NULL) { device_printf(dev, "No Mem space on prism2.5?\n"); - return (ENXIO); + return ENXIO; } sc->wi_btag = rman_get_bustag(sc->mem); sc->wi_bhandle = rman_get_bushandle(sc->mem); } - sc->irq_rid = 0; sc->irq = bus_alloc_resource_any(dev, SYS_RES_IRQ, &sc->irq_rid, RF_ACTIVE | ((sc->wi_bus_type == WI_BUS_PCCARD) ? 0 : RF_SHAREABLE)); - - if (!sc->irq) { + if (sc->irq == NULL) { wi_free(dev); device_printf(dev, "No irq?!\n"); - return (ENXIO); + return ENXIO; } sc->sc_dev = dev; sc->sc_unit = device_get_unit(dev); - - return (0); + return 0; } void @@ -3237,356 +2122,4 @@ wi_free(device_t dev) bus_release_resource(dev, SYS_RES_MEMORY, sc->mem_rid, sc->mem); sc->mem = NULL; } - - return; -} - -#if 0 -static int -wi_get_debug(struct wi_softc *sc, struct wi_req *wreq) -{ - int error = 0; - - wreq->wi_len = 1; - - switch (wreq->wi_type) { - case WI_DEBUG_SLEEP: - wreq->wi_len++; - wreq->wi_val[0] = sc->wi_debug.wi_sleep; - break; - case WI_DEBUG_DELAYSUPP: - wreq->wi_len++; - wreq->wi_val[0] = sc->wi_debug.wi_delaysupp; - break; - case WI_DEBUG_TXSUPP: - wreq->wi_len++; - wreq->wi_val[0] = sc->wi_debug.wi_txsupp; - break; - case WI_DEBUG_MONITOR: - wreq->wi_len++; - wreq->wi_val[0] = sc->wi_debug.wi_monitor; - break; - case WI_DEBUG_LEDTEST: - wreq->wi_len += 3; - wreq->wi_val[0] = sc->wi_debug.wi_ledtest; - wreq->wi_val[1] = sc->wi_debug.wi_ledtest_param0; - wreq->wi_val[2] = sc->wi_debug.wi_ledtest_param1; - break; - case WI_DEBUG_CONTTX: - wreq->wi_len += 2; - wreq->wi_val[0] = sc->wi_debug.wi_conttx; - wreq->wi_val[1] = sc->wi_debug.wi_conttx_param0; - break; - case WI_DEBUG_CONTRX: - wreq->wi_len++; - wreq->wi_val[0] = sc->wi_debug.wi_contrx; - break; - case WI_DEBUG_SIGSTATE: - wreq->wi_len += 2; - wreq->wi_val[0] = sc->wi_debug.wi_sigstate; - wreq->wi_val[1] = sc->wi_debug.wi_sigstate_param0; - break; - case WI_DEBUG_CONFBITS: - wreq->wi_len += 2; - wreq->wi_val[0] = sc->wi_debug.wi_confbits; - wreq->wi_val[1] = sc->wi_debug.wi_confbits_param0; - break; - default: - error = EIO; - break; - } - - return (error); -} - -static int -wi_set_debug(struct wi_softc *sc, struct wi_req *wreq) -{ - int error = 0; - u_int16_t cmd, param0 = 0, param1 = 0; - - switch (wreq->wi_type) { - case WI_DEBUG_RESET: - case WI_DEBUG_INIT: - case WI_DEBUG_CALENABLE: - break; - case WI_DEBUG_SLEEP: - sc->wi_debug.wi_sleep = 1; - break; - case WI_DEBUG_WAKE: - sc->wi_debug.wi_sleep = 0; - break; - case WI_DEBUG_CHAN: - param0 = wreq->wi_val[0]; - break; - case WI_DEBUG_DELAYSUPP: - sc->wi_debug.wi_delaysupp = 1; - break; - case WI_DEBUG_TXSUPP: - sc->wi_debug.wi_txsupp = 1; - break; - case WI_DEBUG_MONITOR: - sc->wi_debug.wi_monitor = 1; - break; - case WI_DEBUG_LEDTEST: - param0 = wreq->wi_val[0]; - param1 = wreq->wi_val[1]; - sc->wi_debug.wi_ledtest = 1; - sc->wi_debug.wi_ledtest_param0 = param0; - sc->wi_debug.wi_ledtest_param1 = param1; - break; - case WI_DEBUG_CONTTX: - param0 = wreq->wi_val[0]; - sc->wi_debug.wi_conttx = 1; - sc->wi_debug.wi_conttx_param0 = param0; - break; - case WI_DEBUG_STOPTEST: - sc->wi_debug.wi_delaysupp = 0; - sc->wi_debug.wi_txsupp = 0; - sc->wi_debug.wi_monitor = 0; - sc->wi_debug.wi_ledtest = 0; - sc->wi_debug.wi_ledtest_param0 = 0; - sc->wi_debug.wi_ledtest_param1 = 0; - sc->wi_debug.wi_conttx = 0; - sc->wi_debug.wi_conttx_param0 = 0; - sc->wi_debug.wi_contrx = 0; - sc->wi_debug.wi_sigstate = 0; - sc->wi_debug.wi_sigstate_param0 = 0; - break; - case WI_DEBUG_CONTRX: - sc->wi_debug.wi_contrx = 1; - break; - case WI_DEBUG_SIGSTATE: - param0 = wreq->wi_val[0]; - sc->wi_debug.wi_sigstate = 1; - sc->wi_debug.wi_sigstate_param0 = param0; - break; - case WI_DEBUG_CONFBITS: - param0 = wreq->wi_val[0]; - param1 = wreq->wi_val[1]; - sc->wi_debug.wi_confbits = param0; - sc->wi_debug.wi_confbits_param0 = param1; - break; - default: - error = EIO; - break; - } - - if (error) - return (error); - - cmd = WI_CMD_DEBUG | (wreq->wi_type << 8); - error = wi_cmd(sc, cmd, param0, param1, 0); - - return (error); -} -#endif - -/* - * Special routines to download firmware for Symbol CF card. - * XXX: This should be modified generic into any PRISM-2 based card. - */ - -#define WI_SBCF_PDIADDR 0x3100 - -/* unaligned load little endian */ -#define GETLE32(p) ((p)[0] | ((p)[1]<<8) | ((p)[2]<<16) | ((p)[3]<<24)) -#define GETLE16(p) ((p)[0] | ((p)[1]<<8)) - -int -wi_symbol_load_firm(struct wi_softc *sc, const void *primsym, int primlen, - const void *secsym, int seclen) -{ - uint8_t ebuf[256]; - int i; - - /* load primary code and run it */ - wi_symbol_set_hcr(sc, WI_HCR_EEHOLD); - if (wi_symbol_write_firm(sc, primsym, primlen, NULL, 0)) - return EIO; - wi_symbol_set_hcr(sc, WI_HCR_RUN); - for (i = 0; ; i++) { - if (i == 10) - return ETIMEDOUT; - tsleep(sc, PWAIT, "wiinit", 1); - if (CSR_READ_2(sc, WI_CNTL) == WI_CNTL_AUX_ENA_STAT) - break; - /* write the magic key value to unlock aux port */ - CSR_WRITE_2(sc, WI_PARAM0, WI_AUX_KEY0); - CSR_WRITE_2(sc, WI_PARAM1, WI_AUX_KEY1); - CSR_WRITE_2(sc, WI_PARAM2, WI_AUX_KEY2); - CSR_WRITE_2(sc, WI_CNTL, WI_CNTL_AUX_ENA_CNTL); - } - - /* issue read EEPROM command: XXX copied from wi_cmd() */ - CSR_WRITE_2(sc, WI_PARAM0, 0); - CSR_WRITE_2(sc, WI_PARAM1, 0); - CSR_WRITE_2(sc, WI_PARAM2, 0); - CSR_WRITE_2(sc, WI_COMMAND, WI_CMD_READEE); - for (i = 0; i < WI_TIMEOUT; i++) { - if (CSR_READ_2(sc, WI_EVENT_STAT) & WI_EV_CMD) - break; - DELAY(1); - } - CSR_WRITE_2(sc, WI_EVENT_ACK, WI_EV_CMD); - - CSR_WRITE_2(sc, WI_AUX_PAGE, WI_SBCF_PDIADDR / WI_AUX_PGSZ); - CSR_WRITE_2(sc, WI_AUX_OFFSET, WI_SBCF_PDIADDR % WI_AUX_PGSZ); - CSR_READ_MULTI_STREAM_2(sc, WI_AUX_DATA, - (uint16_t *)ebuf, sizeof(ebuf) / 2); - if (GETLE16(ebuf) > sizeof(ebuf)) - return EIO; - if (wi_symbol_write_firm(sc, secsym, seclen, ebuf + 4, GETLE16(ebuf))) - return EIO; - return 0; -} - -static int -wi_symbol_write_firm(struct wi_softc *sc, const void *buf, int buflen, - const void *ebuf, int ebuflen) -{ - const uint8_t *p, *ep, *q, *eq; - char *tp; - uint32_t addr, id, eid; - int i, len, elen, nblk, pdrlen; - - /* - * Parse the header of the firmware image. - */ - p = buf; - ep = p + buflen; - while (p < ep && *p++ != ' '); /* FILE: */ - while (p < ep && *p++ != ' '); /* filename */ - while (p < ep && *p++ != ' '); /* type of the firmware */ - nblk = strtoul(p, &tp, 10); - p = tp; - pdrlen = strtoul(p + 1, &tp, 10); - p = tp; - while (p < ep && *p++ != 0x1a); /* skip rest of header */ - - /* - * Block records: address[4], length[2], data[length]; - */ - for (i = 0; i < nblk; i++) { - addr = GETLE32(p); p += 4; - len = GETLE16(p); p += 2; - CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ); - CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ); - CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA, - (const uint16_t *)p, len / 2); - p += len; - } - - /* - * PDR: id[4], address[4], length[4]; - */ - for (i = 0; i < pdrlen; ) { - id = GETLE32(p); p += 4; i += 4; - addr = GETLE32(p); p += 4; i += 4; - len = GETLE32(p); p += 4; i += 4; - /* replace PDR entry with the values from EEPROM, if any */ - for (q = ebuf, eq = q + ebuflen; q < eq; q += elen * 2) { - elen = GETLE16(q); q += 2; - eid = GETLE16(q); q += 2; - elen--; /* elen includes eid */ - if (eid == 0) - break; - if (eid != id) - continue; - CSR_WRITE_2(sc, WI_AUX_PAGE, addr / WI_AUX_PGSZ); - CSR_WRITE_2(sc, WI_AUX_OFFSET, addr % WI_AUX_PGSZ); - CSR_WRITE_MULTI_STREAM_2(sc, WI_AUX_DATA, - (const uint16_t *)q, len / 2); - break; - } - } - return 0; -} - -static int -wi_symbol_set_hcr(struct wi_softc *sc, int mode) -{ - uint16_t hcr; - - CSR_WRITE_2(sc, WI_COR, WI_COR_RESET); - tsleep(sc, PWAIT, "wiinit", 1); - hcr = CSR_READ_2(sc, WI_HCR); - hcr = (hcr & WI_HCR_4WIRE) | (mode & ~WI_HCR_4WIRE); - CSR_WRITE_2(sc, WI_HCR, hcr); - tsleep(sc, PWAIT, "wiinit", 1); - CSR_WRITE_2(sc, WI_COR, WI_COR_IOMODE); - tsleep(sc, PWAIT, "wiinit", 1); - return 0; -} - -/* - * This function can be called by ieee80211_set_shortslottime(). Refer to - * IEEE Std 802.11-1999 pp. 85 to know how these values are computed. - */ -static void -wi_update_slot(struct ifnet *ifp) -{ - DPRINTF(("wi update slot unimplemented\n")); -} - -static void -wi_set_channel(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; - - WI_LOCK(sc); - if (sc->sc_enabled && !(sc->sc_flags & WI_FLAGS_SCANNING)) { - DPRINTF(("wi_set_channel: %d (%dMHz)\n", - ieee80211_chan2ieee(ic, ic->ic_curchan), - ic->ic_curchan->ic_freq)); - - sc->wi_channel = ic->ic_curchan; - wi_write_val(sc, WI_RID_OWN_CHNL, - ieee80211_chan2ieee(ic, ic->ic_curchan)); - - if (ic->ic_opmode == IEEE80211_M_HOSTAP && - sc->sc_firmware_type == WI_INTERSIL) { - /* XXX: some cards need to be re-enabled */ - wi_cmd(sc, WI_CMD_DISABLE | WI_PORT0, 0, 0, 0); - wi_cmd(sc, WI_CMD_ENABLE | WI_PORT0, 0, 0, 0); - } - } - WI_UNLOCK(sc); -} - -static void -wi_scan_start(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; - - WI_LOCK(sc); - sc->sc_flags |= WI_FLAGS_SCANNING; - wi_scan_ap(sc, 0x3fff, 0x000f); - WI_UNLOCK(sc); - -} - -static void -wi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) -{ - /* The firmware is not capable of scanning a single channel */ -} - -static void -wi_scan_mindwell(struct ieee80211com *ic) -{ - /* NB: don't try to abort scan; wait for firmware to finish */ -} - -static void -wi_scan_end(struct ieee80211com *ic) -{ - struct ifnet *ifp = ic->ic_ifp; - struct wi_softc *sc = ifp->if_softc; - - WI_LOCK(sc); - sc->sc_flags &= ~WI_FLAGS_SCANNING; - WI_UNLOCK(sc); } diff --git a/sys/dev/wi/if_wi_pccard.c b/sys/dev/wi/if_wi_pccard.c index 53f067b..ad1b508 100644 --- a/sys/dev/wi/if_wi_pccard.c +++ b/sys/dev/wi/if_wi_pccard.c @@ -71,9 +71,6 @@ __FBSDID("$FreeBSD$"); #include #include #include -#ifdef WI_SYMBOL_FIRMWARE -#include -#endif #include "card_if.h" #include "pccarddevs.h" @@ -152,7 +149,6 @@ static const struct pccard_product wi_pccard_products[] = { PCMCIA_CARD(SIEMENS, SS1021), PCMCIA_CARD(SIMPLETECH, SPECTRUM24_ALT), PCMCIA_CARD(SOCKET, LP_WLAN_CF), - PCMCIA_CARD(SYMBOL, LA4100), PCMCIA_CARD(TDK, LAK_CD011WL), { NULL } }; @@ -167,64 +163,39 @@ wi_pccard_probe(device_t dev) /* Make sure we're a network driver */ error = pccard_get_function(dev, &fcn); if (error != 0) - return (error); + return error; if (fcn != PCCARD_FUNCTION_NETWORK) - return (ENXIO); + return ENXIO; - if ((pp = pccard_product_lookup(dev, wi_pccard_products, - sizeof(wi_pccard_products[0]), NULL)) != NULL) { + pp = pccard_product_lookup(dev, wi_pccard_products, + sizeof(wi_pccard_products[0]), NULL); + if (pp != NULL) { if (pp->pp_name != NULL) device_set_desc(dev, pp->pp_name); - return (0); + return 0; } - return (ENXIO); + return ENXIO; } - static int wi_pccard_attach(device_t dev) { struct wi_softc *sc; - int error; - uint32_t vendor, product; + int error; sc = device_get_softc(dev); sc->wi_gone = 0; sc->wi_bus_type = WI_BUS_PCCARD; error = wi_alloc(dev, 0); - if (error) - return (error); - - /* Make sure interrupts are disabled. */ - CSR_WRITE_2(sc, WI_INT_EN, 0); - CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); - - /* - * The cute little Symbol LA4100-series CF cards need to have - * code downloaded to them. - */ - pccard_get_vendor(dev, &vendor); - pccard_get_product(dev, &product); - if (vendor == PCMCIA_VENDOR_SYMBOL && - product == PCMCIA_PRODUCT_SYMBOL_LA4100) { -#ifdef WI_SYMBOL_FIRMWARE - if (wi_symbol_load_firm(device_get_softc(dev), - spectrum24t_primsym, sizeof(spectrum24t_primsym), - spectrum24t_secsym, sizeof(spectrum24t_secsym))) { - device_printf(dev, "couldn't load firmware\n"); - return (ENXIO); - } -#else - device_printf(dev, - "Symbol LA4100 needs 'option WI_SYMBOL_FIRMWARE'\n"); - wi_free(dev); - return (ENXIO); -#endif + if (error == 0) { + /* Make sure interrupts are disabled. */ + CSR_WRITE_2(sc, WI_INT_EN, 0); + CSR_WRITE_2(sc, WI_EVENT_ACK, 0xFFFF); + + error = wi_attach(dev); + if (error != 0) + wi_free(dev); } - pccard_get_ether(dev, sc->sc_hintmacaddr); - error = wi_attach(dev); - if (error != 0) - wi_free(dev); - return (error); + return error; } diff --git a/sys/dev/wi/if_wi_pci.c b/sys/dev/wi/if_wi_pci.c index fa67a6b..cfbe4dc 100644 --- a/sys/dev/wi/if_wi_pci.c +++ b/sys/dev/wi/if_wi_pci.c @@ -246,10 +246,8 @@ static int wi_pci_suspend(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; - wi_stop(ifp, 1); + wi_stop(sc, 1); return (0); } @@ -258,8 +256,7 @@ static int wi_pci_resume(device_t dev) { struct wi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; if (sc->wi_bus_type != WI_BUS_PCI_NATIVE) return (0); diff --git a/sys/dev/wi/if_wivar.h b/sys/dev/wi/if_wivar.h index 88238a3..a3e9e66 100644 --- a/sys/dev/wi/if_wivar.h +++ b/sys/dev/wi/if_wivar.h @@ -34,11 +34,6 @@ * $FreeBSD$ */ -#if 0 -#define WICACHE /* turn on signal strength cache code */ -#define MAXWICACHE 10 -#endif - /* * Encryption controls. We can enable or disable encryption as * well as specify up to 4 encryption keys. We can also specify @@ -61,17 +56,26 @@ #define WI_MAX_AID 256 /* max stations for ap operation */ +struct wi_vap { + struct ieee80211vap wv_vap; + struct ieee80211_beacon_offsets wv_bo; + struct task wv_connected_task; + struct task wv_disconnected_task; + struct task wv_assoc_failed_task; + + void (*wv_recv_mgmt)(struct ieee80211_node *, + struct mbuf *, int, int, int, u_int32_t); + int (*wv_newstate)(struct ieee80211vap *, + enum ieee80211_state, int); +}; +#define WI_VAP(vap) ((struct wi_vap *)(vap)) + struct wi_softc { struct ifnet *sc_ifp; - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, - enum ieee80211_state, int); - int (*sc_key_alloc)(struct ieee80211com *, - const struct ieee80211_key *, - ieee80211_keyix *, ieee80211_keyix *); device_t sc_dev; struct mtx sc_mtx; struct callout sc_watchdog; + struct task sc_oor_task; int sc_unit; int wi_gone; int sc_enabled; @@ -104,33 +108,21 @@ struct wi_softc { int wi_io_addr; int wi_cmd_count; - struct bpf_if *sc_drvbpf; int sc_flags; int sc_if_flags; int sc_bap_id; int sc_bap_off; - - u_int16_t sc_procframe; + + int sc_porttype; u_int16_t sc_portnum; + u_int16_t sc_encryption; + u_int16_t sc_monitor_port; /* RSSI interpretation */ u_int16_t sc_min_rssi; /* clamp sc_min_rssi < RSSI */ u_int16_t sc_max_rssi; /* clamp RSSI < sc_max_rssi */ u_int16_t sc_dbm_offset; /* dBm ~ RSSI - sc_dbm_offset */ - u_int16_t sc_max_datalen; - u_int16_t sc_system_scale; - u_int16_t sc_cnfauthmode; - u_int16_t sc_roaming_mode; - u_int16_t sc_microwave_oven; - u_int16_t sc_authtype; - u_int16_t sc_encryption; - - int sc_nodelen; - char sc_nodename[IEEE80211_NWID_LEN]; - char sc_net_name[IEEE80211_NWID_LEN]; - uint8_t sc_hintmacaddr[IEEE80211_ADDR_LEN]; - int sc_buflen; /* TX buffer size */ int sc_ntxbuf; #define WI_NTXBUF 3 @@ -141,74 +133,29 @@ struct wi_softc { int sc_txnext; /* index of next TX */ int sc_txcur; /* index of current TX*/ int sc_tx_timer; - int sc_scan_timer; struct wi_counters sc_stats; u_int16_t sc_ibss_port; -#define WI_MAXAPINFO 30 - struct wi_apinfo sc_aps[WI_MAXAPINFO]; - int sc_naps; - - struct { - u_int16_t wi_sleep; - u_int16_t wi_delaysupp; - u_int16_t wi_txsupp; - u_int16_t wi_monitor; - u_int16_t wi_ledtest; - u_int16_t wi_ledtest_param0; - u_int16_t wi_ledtest_param1; - u_int16_t wi_conttx; - u_int16_t wi_conttx_param0; - u_int16_t wi_contrx; - u_int16_t wi_sigstate; - u_int16_t wi_sigstate_param0; - u_int16_t wi_confbits; - u_int16_t wi_confbits_param0; - } wi_debug; - struct timeval sc_last_syn; int sc_false_syns; u_int16_t sc_txbuf[IEEE80211_MAX_LEN/2]; - union { - struct wi_tx_radiotap_header th; - u_int8_t pad[64]; - } u_tx_rt; + struct wi_tx_radiotap_header sc_tx_th; int sc_tx_th_len; - union { - struct wi_rx_radiotap_header th; - u_int8_t pad[64]; - } u_rx_rt; + struct wi_rx_radiotap_header sc_rx_th; int sc_rx_th_len; }; -#define sc_tx_th u_tx_rt.th -#define sc_rx_th u_rx_rt.th /* maximum consecutive false change-of-BSSID indications */ #define WI_MAX_FALSE_SYNS 10 -#define WI_SCAN_INQWAIT 3 /* wait sec before inquire */ -#define WI_SCAN_WAIT 5 /* maximum scan wait */ - -#define WI_FLAGS_ATTACHED 0x0001 -#define WI_FLAGS_INITIALIZED 0x0002 -#define WI_FLAGS_OUTRANGE 0x0004 -#define WI_FLAGS_HAS_MOR 0x0010 +#define WI_FLAGS_HAS_ENHSECURITY 0x0001 +#define WI_FLAGS_HAS_WPASUPPORT 0x0002 #define WI_FLAGS_HAS_ROAMING 0x0020 -#define WI_FLAGS_HAS_DIVERSITY 0x0040 -#define WI_FLAGS_HAS_SYSSCALE 0x0080 -#define WI_FLAGS_BUG_AUTOINC 0x0100 #define WI_FLAGS_HAS_FRAGTHR 0x0200 #define WI_FLAGS_HAS_DBMADJUST 0x0400 -#define WI_FLAGS_SCANNING 0x0800 - - -/* driver-specific node state */ -struct wi_node { - struct ieee80211_node ni; /* base class */ -}; struct wi_card_ident { u_int16_t card_id; @@ -240,5 +187,4 @@ extern devclass_t wi_devclass; void wi_init(void *); void wi_intr(void *); int wi_mgmt_xmit(struct wi_softc *, caddr_t, int); -void wi_stop(struct ifnet *, int); -int wi_symbol_load_firm(struct wi_softc *, const void *, int, const void *, int); +void wi_stop(struct wi_softc *, int); diff --git a/sys/dev/wi/spectrum24t_cf.h b/sys/dev/wi/spectrum24t_cf.h deleted file mode 100644 index ce053fa..0000000 --- a/sys/dev/wi/spectrum24t_cf.h +++ /dev/null @@ -1,4327 +0,0 @@ -/* $NetBSD$ */ -/* $FreeBSD$ */ - -/*- - * Copyright (c) 2001 Symbol Technologies Inc. -- http://www.symbol.com - * All rights reserved. - * - * Redistribution and use in source and binary forms are permitted provided - * that the following conditions are met: - * 1. Redistribution of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistribution in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * 3. The name of the author may not be used to endorse or promote products - * derived from this software without specific prior written permission - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``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 AUTHOR 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. - */ - -/* - * Firmware for Symbol Wireless Networker Spectrum24t CF card. - * Automatically generated from EPRIMSYM and ESECSYM: - * T3.10-04,F3.10-04,01/17/2002 - */ - -#ifndef _FIRMWARE_WI_SPECTRUM24T_CF_H_ -#define _FIRMWARE_WI_SPECTRUM24T_CF_H_ - -const u_int8_t spectrum24t_primsym[] = { -0x46,0x49,0x4c,0x45,0x3a,0x20,0x45,0x50,0x52,0x49,0x4d,0x53,0x59,0x4d,0x2c,0x54, -0x33,0x2e,0x31,0x30,0x2d,0x30,0x34,0x2c,0x46,0x33,0x2e,0x31,0x30,0x2d,0x30,0x34, -0x2c,0x30,0x31,0x2f,0x31,0x37,0x2f,0x32,0x30,0x30,0x32,0x20,0x50,0x52,0x49,0x4d, -0x41,0x52,0x59,0x20,0x33,0x20,0x37,0x32,0x20,0x33,0x36,0x20,0x34,0x30,0x0a,0x1a, -0xfe,0x17,0x7e,0x00,0x02,0x00,0xff,0xff,0x00,0x00,0x7e,0x00,0xfe,0x0f,0x00,0x64, -0x90,0xff,0x00,0xf7,0x20,0xfe,0x00,0x64,0x91,0xff,0x01,0xf7,0x20,0xfe,0x00,0x64, -0x92,0xff,0x02,0xf7,0x20,0xfe,0x00,0x64,0x93,0xff,0x03,0xf7,0x20,0xfe,0x00,0x64, -0x94,0xff,0x04,0xf7,0x20,0xfe,0x00,0x64,0x95,0xff,0x05,0xf7,0x20,0xfe,0x00,0x64, -0x96,0xff,0x06,0xf7,0x20,0xfe,0x00,0x64,0x97,0xff,0x07,0x04,0x30,0x44,0x04,0xa8, -0xff,0xff,0x11,0x03,0x00,0x60,0xf6,0x78,0xff,0xff,0x87,0xff,0x8a,0xff,0x98,0xff, -0x20,0xfe,0x44,0x41,0x00,0x64,0x64,0x40,0x10,0x2b,0x04,0x64,0x40,0x51,0x00,0x64, -0x40,0x50,0x00,0x64,0x40,0x40,0x99,0xff,0x08,0x60,0x2a,0x62,0x04,0x60,0xff,0x64, -0xa2,0xdb,0x04,0x60,0xff,0xe5,0xff,0xff,0xff,0xff,0x98,0xff,0x08,0x60,0x28,0x62, -0x28,0x60,0x10,0x64,0xa2,0xdb,0x28,0x60,0x31,0x40,0x04,0x26,0xa8,0x60,0x99,0xff, -0x10,0xe4,0xff,0xff,0xff,0xff,0x98,0xff,0x55,0x60,0xfc,0xe0,0xa0,0xfe,0xa1,0xfe, -0xa2,0xfe,0xa3,0xfe,0xa4,0xfe,0xa5,0xfe,0xa6,0xfe,0xa7,0xfe,0xa8,0xfe,0xa9,0xfe, -0xaa,0xfe,0xab,0xfe,0xac,0xfe,0xad,0xfe,0xae,0xfe,0xaf,0xfe,0xb0,0xfe,0xb1,0xfe, -0xb2,0xfe,0xb3,0xfe,0xb4,0xfe,0xb5,0xfe,0xb6,0xfe,0xb7,0xfe,0xb8,0xfe,0xb9,0xfe, -0xba,0xfe,0xbb,0xfe,0xbc,0xfe,0xbd,0xfe,0xbe,0xfe,0xbf,0xfe,0x99,0xff,0x18,0xec, -0x0e,0xe3,0x12,0xe3,0x1d,0xe3,0x22,0xe3,0x2a,0xe3,0x32,0xe3,0x3a,0xe3,0x10,0xed, -0x42,0xe3,0x4a,0xe3,0x52,0xe3,0x5a,0xe3,0x62,0xe3,0x68,0xe3,0x70,0xe3,0x7a,0xe3, -0x04,0xee,0x82,0xe3,0x8a,0xe3,0x92,0xe3,0x9a,0xe3,0xa2,0xe3,0xaa,0xe3,0xb2,0xe3, -0xba,0xe3,0x21,0x60,0x7d,0xe7,0x68,0x60,0x7d,0xe7,0x10,0x60,0x7d,0xe7,0x7d,0xe7, -0xf0,0x60,0x7d,0xe7,0xa5,0x60,0x7d,0xe7,0x7d,0xe7,0x36,0x60,0x7d,0xe7,0x6d,0x60, -0x7d,0xe7,0x98,0x60,0x7d,0xe7,0x39,0x60,0x7d,0xe7,0x3f,0x60,0x7d,0xe7,0x42,0x60, -0x7d,0xe7,0x0c,0x60,0x7d,0xe7,0xc2,0x60,0x7d,0xe7,0x7d,0xe7,0xa5,0x60,0x7d,0xe7, -0x7d,0xe7,0x36,0x60,0x7d,0xe7,0x01,0x60,0x7d,0xe7,0xad,0x60,0x7d,0xe7,0x7d,0xe7, -0x37,0x60,0x7d,0xe7,0x42,0x60,0x7d,0xe7,0x0e,0x60,0x7d,0xe7,0xc2,0x60,0x7d,0xe7, -0x07,0x60,0x80,0xe7,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0x80,0xe7,0xff,0xff,0xff,0xff,0x06,0xe3,0xff,0xff,0x98,0xff,0x30,0x44, -0x00,0xa8,0xff,0xff,0x09,0x02,0x08,0x60,0x00,0x64,0xc8,0x81,0x3e,0x63,0x00,0x64, -0x59,0xdb,0xfe,0x1f,0x04,0x60,0x41,0x76,0x00,0x60,0x3e,0x63,0xff,0x60,0xfe,0x61, -0xfc,0x60,0x00,0x66,0x09,0x60,0xc2,0x64,0x58,0xd0,0x59,0xd9,0xfd,0x1f,0x05,0x60, -0x08,0x63,0x08,0x60,0xfe,0x61,0xfc,0x60,0x00,0x66,0x0a,0x60,0x02,0x64,0x58,0xd0, -0x59,0xd9,0xfd,0x1f,0x58,0x4f,0x2e,0x00,0x58,0x4f,0x14,0x00,0x30,0x44,0x00,0xa8, -0x00,0x64,0x03,0x03,0x0f,0xfb,0xd4,0xfe,0x00,0x00,0x63,0xff,0xff,0xff,0x65,0xff, -0xff,0xff,0x58,0x4f,0x41,0x00,0x01,0x60,0x9c,0x78,0xff,0xff,0x98,0xff,0x00,0xe1, -0xa1,0xff,0xfc,0x00,0x00,0x60,0x7c,0x63,0x0e,0x60,0x80,0x64,0xe0,0x87,0x15,0xfb, -0x04,0x61,0x60,0x46,0xdc,0x84,0x00,0xfa,0xcd,0x81,0x01,0xfc,0xfa,0x02,0x00,0x64, -0x00,0xfa,0x80,0x60,0x00,0x65,0xb7,0x83,0x01,0xfc,0x15,0xf5,0x3c,0x63,0x01,0xfc, -0x2f,0x58,0xff,0xff,0x00,0x60,0x7e,0x63,0xfe,0x60,0x00,0x65,0x45,0x4b,0xdc,0x60, -0xfe,0x61,0xfc,0x60,0x00,0x65,0x0f,0x60,0x0c,0x64,0x65,0x46,0x58,0xd0,0x2b,0x46, -0x59,0xd8,0xfb,0x1f,0x7e,0x63,0x40,0xa1,0x40,0xa1,0x65,0x46,0x58,0xd0,0x2b,0x46, -0x59,0xd8,0xfb,0x1f,0x7e,0x63,0x40,0xa1,0x40,0xa1,0x65,0x46,0x58,0xd0,0x2b,0x46, -0x59,0xd8,0xfb,0x1f,0x2f,0x58,0xff,0xff,0x04,0xee,0x0d,0x60,0x26,0x63,0x0e,0x60, -0x0a,0x65,0xbd,0xd1,0xff,0xff,0x64,0x48,0x64,0x47,0x00,0x7f,0x60,0x41,0x80,0xbc, -0x60,0x4a,0xff,0xff,0xff,0xff,0x01,0x16,0xfe,0x00,0xff,0xff,0xff,0xff,0xd7,0x80, -0xff,0xff,0xef,0x02,0x68,0x40,0x99,0xff,0x3e,0x44,0xfc,0xb4,0x01,0xbc,0x00,0x7f, -0x40,0x5e,0x98,0xff,0x0d,0x63,0x01,0x60,0x58,0x4e,0x70,0x78,0xff,0xff,0x99,0xff, -0x3e,0x44,0xfc,0xb4,0x00,0x7f,0x40,0x5e,0x98,0xff,0x0d,0x63,0x01,0x60,0x58,0x4e, -0x70,0x78,0xff,0xff,0x00,0xee,0x88,0xec,0x00,0xed,0x2f,0x58,0xff,0xff,0xff,0xff, -0xfe,0x1f,0x2e,0x58,0xff,0xff,0x98,0xff,0x00,0xe1,0x30,0x44,0x01,0xa8,0x02,0xa8, -0x05,0x03,0x05,0x03,0x83,0xff,0x8d,0xff,0x00,0x64,0x40,0x40,0x43,0xe1,0x00,0x60, -0x91,0x65,0x78,0x44,0xc4,0x98,0xff,0xff,0x98,0xff,0x88,0xe2,0x00,0xe1,0x30,0x44, -0x02,0xa8,0x01,0xa8,0x0b,0x03,0x06,0x03,0x85,0xff,0x88,0xff,0xeb,0x60,0x19,0xe2, -0x00,0x60,0x90,0xe2,0x40,0xe1,0x04,0x60,0x00,0x71,0x8d,0xe2,0x01,0x60,0x3e,0x65, -0x78,0x44,0xc4,0x98,0xff,0xff,0x0a,0xe1,0xa3,0xff,0xae,0xff,0xff,0xff,0xff,0xff, -0xae,0xff,0x01,0x60,0x63,0x65,0x78,0x44,0xc4,0x98,0xff,0xff,0xaa,0xff,0x08,0x60, -0x14,0x64,0xa0,0xd1,0x04,0x60,0x41,0x76,0x3f,0x60,0xff,0x64,0xa0,0x83,0x08,0x60, -0x14,0x64,0xa0,0xdd,0x64,0x44,0x80,0x2b,0x1d,0x00,0x50,0xfe,0x08,0x60,0x02,0x64, -0xa0,0xd1,0xfe,0x60,0x01,0x64,0xd0,0x80,0x08,0x60,0x04,0x64,0xa0,0xd1,0xdc,0x60, -0x23,0x64,0xd0,0x80,0x08,0x60,0x06,0x64,0xa0,0xd1,0xba,0x60,0x45,0x64,0xd0,0x80, -0x63,0x47,0x01,0x01,0x07,0x00,0xc0,0xbf,0x60,0x43,0x08,0x60,0x14,0x64,0xa0,0xdd, -0x04,0x60,0x01,0x76,0x41,0x00,0xab,0xff,0xff,0xff,0xff,0xff,0xab,0xff,0x3c,0x00, -0xa9,0xff,0x77,0x44,0x60,0x57,0x40,0x4a,0x2a,0x44,0x10,0xb0,0x20,0x44,0x04,0x03, -0xfd,0xb4,0x01,0xb0,0x40,0x40,0x01,0x02,0x2f,0x00,0xfe,0xb4,0x40,0x40,0xa8,0xff, -0x20,0x44,0x02,0xb0,0x60,0x41,0x08,0x60,0x00,0x64,0xa0,0xd1,0x61,0x44,0x03,0x03, -0x01,0xbc,0x40,0x40,0x1e,0x00,0x02,0xbc,0x40,0x40,0x64,0x44,0x3f,0xb4,0x0b,0xa8, -0xff,0xff,0x06,0x02,0x64,0x44,0x80,0xb0,0xff,0xff,0x02,0x03,0x01,0x64,0x13,0xfb, -0x0f,0xf9,0x08,0x60,0x02,0x64,0xa0,0xd1,0x10,0xf9,0x08,0x60,0x04,0x64,0xa0,0xd1, -0xd4,0xfe,0x11,0xf9,0x08,0x60,0x06,0x64,0xa0,0xd1,0x12,0xf9,0xae,0xff,0xff,0xff, -0xae,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xa1,0xff,0xff,0xff,0xba,0x3f,0x75,0x44, -0x01,0x26,0x08,0xf7,0xff,0xff,0xff,0xff,0x02,0x26,0x09,0xf7,0xff,0xff,0xff,0xff, -0x04,0x26,0x0a,0xf7,0xff,0xff,0xff,0xff,0x08,0x26,0x0b,0xf7,0xff,0xff,0xff,0xff, -0x40,0x26,0xa7,0xff,0xe9,0x00,0x0f,0x60,0xfe,0x65,0x08,0x60,0x1c,0x64,0xa0,0xd3, -0xff,0xff,0x24,0x86,0x80,0x67,0x60,0x5c,0x08,0x60,0x1c,0x64,0xa0,0xd9,0x08,0x60, -0x18,0x64,0xa0,0xd3,0x15,0xf3,0x40,0x45,0xfc,0x2b,0x02,0x00,0x40,0x45,0x05,0x00, -0x02,0x60,0x58,0x4f,0xb2,0x78,0xff,0xff,0x07,0x02,0x58,0x4f,0x4a,0x00,0x04,0x05, -0x66,0x50,0x65,0x52,0x61,0x51,0x0a,0x00,0x40,0x67,0x26,0x45,0xb4,0x84,0x40,0x46, -0x15,0xf5,0x06,0xf0,0x80,0x60,0x64,0x50,0x20,0x52,0x7e,0x71,0x99,0xff,0xac,0xff, -0x98,0xff,0x26,0x5c,0x08,0x60,0x1c,0x64,0xa0,0xd9,0xb6,0x00,0x0f,0x60,0xfe,0x65, -0x08,0x60,0x1e,0x64,0xa0,0xd3,0xff,0xff,0x24,0x86,0x80,0x67,0x60,0x5c,0x08,0x60, -0x1e,0x64,0xa0,0xd9,0x08,0x60,0x1a,0x64,0xa0,0xd3,0x15,0xf3,0x40,0x45,0xfc,0x2b, -0x02,0x00,0x40,0x45,0x03,0x00,0x58,0x4f,0x3c,0x00,0x08,0x02,0x58,0x4f,0x19,0x00, -0x8e,0xff,0x04,0x05,0x66,0x50,0x65,0x52,0x61,0x51,0x0a,0x00,0x40,0x67,0x26,0x45, -0xb4,0x84,0x40,0x46,0x15,0xf5,0x06,0xf0,0x80,0x60,0x64,0x50,0x20,0x52,0x7e,0x71, -0x8d,0xff,0x99,0xff,0xad,0xff,0x98,0xff,0x26,0x5c,0x08,0x60,0x1e,0x64,0xa0,0xd9, -0xcc,0x00,0x25,0x46,0x26,0x41,0x44,0x63,0x01,0xf2,0xff,0xff,0xff,0xb5,0xd5,0x81, -0xff,0xff,0x07,0x04,0x00,0xf2,0x04,0x63,0x00,0xa8,0x60,0x46,0xf5,0x02,0x42,0xfe, -0x0e,0x00,0x61,0x44,0xc5,0x81,0x63,0x45,0xc5,0x81,0x60,0x45,0x00,0x64,0xd4,0x84, -0x01,0xf2,0xf0,0x85,0xf0,0x80,0x65,0x44,0xf8,0x85,0xff,0xff,0x02,0xfe,0x2f,0x58, -0xff,0xff,0x25,0x44,0x1a,0xf1,0x1b,0xf1,0xd0,0x80,0xd0,0x80,0x0e,0x04,0x08,0x06, -0x1c,0xf1,0x1d,0xf1,0xd0,0x80,0xd0,0x80,0x08,0x04,0x02,0x06,0x48,0xfe,0x05,0x00, -0x25,0x46,0x01,0xf0,0x03,0x67,0xa0,0x85,0x94,0x80,0x2f,0x58,0xff,0xff,0x84,0xe2, -0x04,0x60,0x00,0x71,0x8d,0xe2,0x1e,0xf3,0x14,0xf3,0x00,0xbd,0xcc,0x83,0x08,0x03, -0x14,0xfd,0x06,0x02,0x65,0x44,0x14,0xfb,0x89,0xff,0x80,0x60,0x00,0x75,0x88,0xff, -0xa1,0xff,0xff,0xff,0xbc,0x3f,0x7f,0x67,0x01,0x61,0x23,0x58,0xff,0xff,0x0f,0xf3, -0x10,0xf1,0x40,0x44,0x44,0x45,0x11,0xf1,0x12,0xf1,0x44,0x46,0x44,0x47,0x3f,0xb4, -0x0b,0xa8,0xff,0xff,0x06,0x02,0x24,0x44,0x80,0xb0,0xff,0xff,0x02,0x03,0x00,0x67, -0x08,0x00,0x24,0x44,0x3f,0xb4,0xe0,0x85,0x09,0x60,0x00,0x64,0x44,0xd7,0x58,0x43, -0xff,0xff,0x61,0x43,0x60,0x45,0x24,0x44,0x3f,0xb4,0xb4,0x9c,0xff,0x27,0x01,0x00, -0x03,0x00,0x08,0x60,0x0a,0x64,0xa0,0xdd,0x08,0x60,0x08,0x64,0xa0,0xd9,0x10,0x75, -0xa1,0xff,0xff,0xff,0xbe,0x3f,0xb4,0xfe,0xff,0xff,0xd1,0x05,0xb5,0xfe,0xb6,0xfe, -0xb7,0xfe,0xf6,0x00,0x08,0x60,0x28,0x62,0x12,0x60,0x34,0x64,0xa2,0xdb,0x24,0x45, -0x01,0x27,0x3d,0x00,0x7f,0x60,0xc0,0x64,0xa4,0x80,0x7f,0x67,0x02,0x61,0x40,0x02, -0x20,0x44,0x20,0xb0,0xdf,0xb4,0x1b,0x03,0x40,0x40,0xfc,0x60,0x00,0x66,0x00,0x60, -0x16,0x64,0x60,0x41,0x08,0x63,0x58,0xd0,0x59,0xd9,0xfd,0x1f,0x00,0x60,0x26,0x64, -0x60,0x41,0x08,0x63,0x58,0xd0,0x59,0xd9,0xfd,0x1f,0x02,0x64,0x40,0x50,0x63,0xff, -0xff,0xff,0x65,0xff,0xff,0xff,0x04,0x64,0x40,0x50,0x67,0xff,0xff,0xff,0xfc,0x60, -0x00,0x66,0x17,0x60,0xfe,0x63,0xbd,0xd0,0xc0,0x60,0xde,0x64,0xd0,0x80,0xdb,0x83, -0x0e,0x02,0x20,0x44,0x10,0xbc,0x40,0x40,0x02,0x64,0x40,0x50,0x63,0xff,0xff,0xff, -0x65,0xff,0xff,0xff,0x00,0x64,0x40,0x50,0x0c,0x60,0x01,0x78,0xff,0xff,0x08,0x60, -0x00,0x64,0xc8,0x81,0x3e,0x63,0x00,0x64,0x59,0xdb,0xfe,0x1f,0x04,0x60,0x41,0x76, -0x23,0x58,0xff,0xff,0x7e,0x60,0xc0,0x64,0x24,0x45,0xa4,0x80,0x7f,0x67,0x02,0x61, -0x23,0x02,0x25,0x45,0xfc,0x2b,0x1e,0x00,0x0c,0x60,0x70,0x63,0x0e,0x61,0x24,0x44, -0x01,0x27,0x10,0x00,0xbd,0xd3,0xa3,0xd1,0xd4,0x80,0xcd,0x81,0x08,0x24,0x64,0x58, -0x08,0xa3,0xf8,0x02,0x04,0x61,0x15,0xf5,0x00,0x64,0x22,0xfa,0x25,0x44,0x5a,0xda, -0x00,0x67,0x0a,0x00,0xbd,0xd3,0xbe,0xd1,0xd4,0x80,0xcd,0x81,0x08,0x24,0x64,0x58, -0x08,0xa3,0xf8,0x02,0x7f,0x67,0x04,0x61,0x23,0x58,0xff,0xff,0xbf,0xd3,0xff,0xff, -0x62,0x43,0xbf,0xd1,0xf8,0xa3,0xa3,0xd1,0x64,0x43,0x60,0x41,0x15,0xf5,0xe8,0x84, -0xdc,0x84,0x22,0xfa,0x5a,0xd8,0x62,0x44,0xbd,0xd1,0xc9,0x81,0x58,0xd8,0xfc,0x02, -0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x22,0xf2,0xbf,0xd1,0xff,0xff, -0x62,0x43,0xcc,0x84,0xe0,0x85,0x0b,0x06,0xbf,0xd1,0x64,0x41,0xd5,0x80,0x64,0x43, -0x01,0x06,0x65,0x41,0x46,0x64,0x58,0xd0,0xc9,0x81,0xbd,0xd9,0xfc,0x02,0x00,0x67, -0x00,0x61,0x23,0x58,0xff,0xff,0xfc,0x60,0x00,0x64,0x40,0x4b,0x4b,0xd3,0x15,0xf5, -0x60,0x41,0xd8,0x84,0xe8,0x84,0x22,0xfa,0x25,0x44,0x23,0xfa,0xbf,0xd3,0x66,0x45, -0x48,0x63,0xc8,0x84,0x2b,0x46,0x58,0xd0,0x65,0x46,0xc9,0x81,0xbd,0xd8,0xfa,0x02, -0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x00,0x64,0x40,0x45,0x02,0x60,0x00,0x64, -0x40,0x46,0x77,0x60,0xfc,0xe0,0x99,0xff,0x00,0xec,0x02,0xe3,0xd8,0xe3,0x0a,0xe1, -0x2f,0x60,0xfe,0x62,0x04,0x60,0x58,0x4e,0x7b,0x78,0xff,0xff,0x25,0x44,0x60,0x47, -0x01,0xb4,0xe0,0x85,0xa0,0x7e,0xb4,0x84,0x04,0x60,0x58,0x4e,0xa4,0x78,0xff,0xff, -0x25,0x44,0x04,0x60,0x58,0x4e,0xa4,0x78,0xff,0xff,0x08,0x61,0x61,0x5c,0x5a,0xd1, -0xff,0xff,0x64,0x47,0x04,0x60,0x58,0x4e,0xa4,0x78,0xff,0xff,0x2c,0x02,0x64,0x44, -0x04,0x60,0x58,0x4e,0xa4,0x78,0xff,0xff,0x26,0x02,0xcd,0x81,0xff,0xff,0xef,0x02, -0x04,0x60,0x58,0x4e,0x89,0x78,0xff,0xff,0x03,0x60,0xe8,0x7a,0x2d,0xe2,0xa1,0xff, -0xff,0xff,0x24,0xe2,0x04,0x60,0x58,0x4e,0x7b,0x78,0xff,0xff,0xa1,0x7e,0x04,0x60, -0x58,0x4e,0xa4,0x78,0xff,0xff,0xf0,0x02,0x04,0x60,0x58,0x4e,0x97,0x78,0xff,0xff, -0x04,0x60,0x58,0x4e,0x89,0x78,0xff,0xff,0x26,0x45,0x25,0x44,0x10,0xa4,0xd4,0x80, -0x40,0x45,0xb8,0x02,0x28,0xe2,0xff,0x60,0xff,0x64,0xa2,0xdb,0x55,0x60,0xfc,0xe0, -0x98,0xff,0x8d,0xe2,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x77,0x60,0xfc,0xe0, -0x99,0xff,0x00,0xec,0x02,0xe3,0xd8,0xe3,0x04,0x60,0x58,0x4e,0x97,0x78,0xff,0xff, -0x04,0x60,0x58,0x4e,0x7b,0x78,0xff,0xff,0xa0,0x7e,0x04,0x60,0x58,0x4e,0xa4,0x78, -0xff,0xff,0x00,0x7e,0x04,0x60,0x58,0x4e,0xa4,0x78,0xff,0xff,0x04,0x60,0x58,0x4e, -0x7b,0x78,0xff,0xff,0xa1,0x7e,0x04,0x60,0x58,0x4e,0xa4,0x78,0xff,0xff,0x2f,0x60, -0xfe,0x62,0x01,0x60,0x00,0x61,0x61,0x5c,0x04,0x60,0x58,0x4e,0xc7,0x78,0xff,0xff, -0x60,0x47,0x60,0x45,0x04,0x60,0x58,0x4e,0xc7,0x78,0xff,0xff,0xb4,0x84,0xcd,0x81, -0x5a,0xdb,0xf2,0x02,0x04,0x60,0x58,0x4e,0x89,0x78,0xff,0xff,0xff,0xff,0x04,0x60, -0x58,0x4e,0x97,0x78,0xff,0xff,0x55,0x60,0xfc,0xe0,0x98,0xff,0x00,0x67,0x00,0x61, -0x23,0x58,0xff,0xff,0x01,0x60,0x02,0xe3,0xff,0xff,0xff,0xff,0x01,0xec,0xff,0xff, -0xff,0xff,0x01,0x60,0x06,0xe3,0xff,0xff,0xff,0xff,0x00,0xec,0x2e,0x58,0xff,0xff, -0x01,0x60,0x06,0xe3,0xff,0xff,0xff,0xff,0x01,0xec,0xff,0xff,0xff,0xff,0x01,0x60, -0x02,0xe3,0xff,0xff,0xff,0xff,0x00,0xec,0x2e,0x58,0xff,0xff,0x09,0x63,0x01,0xec, -0xff,0xff,0xff,0xff,0x3f,0x40,0x08,0x26,0x04,0x00,0x00,0xec,0xcf,0x83,0xff,0xff, -0xf6,0x02,0x2e,0x58,0xff,0xff,0x0e,0x63,0x60,0x40,0x80,0x2a,0x03,0x00,0x01,0x60, -0x02,0xe3,0x02,0x00,0x01,0x60,0x06,0xe3,0x01,0xec,0xe0,0x84,0xff,0xff,0xff,0xff, -0xff,0xff,0x00,0xec,0xf1,0x1f,0x01,0x60,0x02,0xe3,0xff,0xff,0xff,0xff,0x3f,0x40, -0x08,0x26,0x08,0x00,0x01,0xec,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xec, -0x00,0x64,0x01,0x00,0x01,0x64,0x00,0xbc,0x2e,0x58,0xff,0xff,0x0e,0x63,0xe0,0x84, -0x3f,0x40,0x08,0x26,0xdc,0x84,0x01,0xec,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0x00,0xec,0xf5,0x1f,0xff,0xff,0x01,0x60,0x06,0xe3,0xff,0xff,0x01,0xec,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xec,0x01,0x60,0x02,0xe3,0x00,0x7f,0x2e,0x58, -0xff,0xff,0xff,0x00,0xff,0x00,0xff,0x00,0x74,0x01,0xff,0x00,0x85,0x01,0xff,0x00, -0x18,0x02,0xe8,0x01,0xd9,0x01,0xa7,0x01,0xd4,0x01,0xdc,0x01,0xc8,0x02,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x0a,0x00, -0x00,0x00,0x13,0x03,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0xdc,0x02,0x63,0x03,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0x37,0x04,0xd5,0x03,0xdc,0x02,0xda,0x03,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02,0xdc,0x02, -0xdc,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x7e,0x00,0x08,0x11,0x00,0xf8,0x7f,0x00,0xfe,0x07,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff, -0xff,0xff,0xff,0xff,0x00,0x00,0xc1,0xc0,0x81,0xc1,0x40,0x01,0x01,0xc3,0xc0,0x03, -0x80,0x02,0x41,0xc2,0x01,0xc6,0xc0,0x06,0x80,0x07,0x41,0xc7,0x00,0x05,0xc1,0xc5, -0x81,0xc4,0x40,0x04,0x01,0xcc,0xc0,0x0c,0x80,0x0d,0x41,0xcd,0x00,0x0f,0xc1,0xcf, -0x81,0xce,0x40,0x0e,0x00,0x0a,0xc1,0xca,0x81,0xcb,0x40,0x0b,0x01,0xc9,0xc0,0x09, -0x80,0x08,0x41,0xc8,0x01,0xd8,0xc0,0x18,0x80,0x19,0x41,0xd9,0x00,0x1b,0xc1,0xdb, -0x81,0xda,0x40,0x1a,0x00,0x1e,0xc1,0xde,0x81,0xdf,0x40,0x1f,0x01,0xdd,0xc0,0x1d, -0x80,0x1c,0x41,0xdc,0x00,0x14,0xc1,0xd4,0x81,0xd5,0x40,0x15,0x01,0xd7,0xc0,0x17, -0x80,0x16,0x41,0xd6,0x01,0xd2,0xc0,0x12,0x80,0x13,0x41,0xd3,0x00,0x11,0xc1,0xd1, -0x81,0xd0,0x40,0x10,0x01,0xf0,0xc0,0x30,0x80,0x31,0x41,0xf1,0x00,0x33,0xc1,0xf3, -0x81,0xf2,0x40,0x32,0x00,0x36,0xc1,0xf6,0x81,0xf7,0x40,0x37,0x01,0xf5,0xc0,0x35, -0x80,0x34,0x41,0xf4,0x00,0x3c,0xc1,0xfc,0x81,0xfd,0x40,0x3d,0x01,0xff,0xc0,0x3f, -0x80,0x3e,0x41,0xfe,0x01,0xfa,0xc0,0x3a,0x80,0x3b,0x41,0xfb,0x00,0x39,0xc1,0xf9, -0x81,0xf8,0x40,0x38,0x00,0x28,0xc1,0xe8,0x81,0xe9,0x40,0x29,0x01,0xeb,0xc0,0x2b, -0x80,0x2a,0x41,0xea,0x01,0xee,0xc0,0x2e,0x80,0x2f,0x41,0xef,0x00,0x2d,0xc1,0xed, -0x81,0xec,0x40,0x2c,0x01,0xe4,0xc0,0x24,0x80,0x25,0x41,0xe5,0x00,0x27,0xc1,0xe7, -0x81,0xe6,0x40,0x26,0x00,0x22,0xc1,0xe2,0x81,0xe3,0x40,0x23,0x01,0xe1,0xc0,0x21, -0x80,0x20,0x41,0xe0,0x01,0xa0,0xc0,0x60,0x80,0x61,0x41,0xa1,0x00,0x63,0xc1,0xa3, -0x81,0xa2,0x40,0x62,0x00,0x66,0xc1,0xa6,0x81,0xa7,0x40,0x67,0x01,0xa5,0xc0,0x65, -0x80,0x64,0x41,0xa4,0x00,0x6c,0xc1,0xac,0x81,0xad,0x40,0x6d,0x01,0xaf,0xc0,0x6f, -0x80,0x6e,0x41,0xae,0x01,0xaa,0xc0,0x6a,0x80,0x6b,0x41,0xab,0x00,0x69,0xc1,0xa9, -0x81,0xa8,0x40,0x68,0x00,0x78,0xc1,0xb8,0x81,0xb9,0x40,0x79,0x01,0xbb,0xc0,0x7b, -0x80,0x7a,0x41,0xba,0x01,0xbe,0xc0,0x7e,0x80,0x7f,0x41,0xbf,0x00,0x7d,0xc1,0xbd, -0x81,0xbc,0x40,0x7c,0x01,0xb4,0xc0,0x74,0x80,0x75,0x41,0xb5,0x00,0x77,0xc1,0xb7, -0x81,0xb6,0x40,0x76,0x00,0x72,0xc1,0xb2,0x81,0xb3,0x40,0x73,0x01,0xb1,0xc0,0x71, -0x80,0x70,0x41,0xb0,0x00,0x50,0xc1,0x90,0x81,0x91,0x40,0x51,0x01,0x93,0xc0,0x53, -0x80,0x52,0x41,0x92,0x01,0x96,0xc0,0x56,0x80,0x57,0x41,0x97,0x00,0x55,0xc1,0x95, -0x81,0x94,0x40,0x54,0x01,0x9c,0xc0,0x5c,0x80,0x5d,0x41,0x9d,0x00,0x5f,0xc1,0x9f, -0x81,0x9e,0x40,0x5e,0x00,0x5a,0xc1,0x9a,0x81,0x9b,0x40,0x5b,0x01,0x99,0xc0,0x59, -0x80,0x58,0x41,0x98,0x01,0x88,0xc0,0x48,0x80,0x49,0x41,0x89,0x00,0x4b,0xc1,0x8b, -0x81,0x8a,0x40,0x4a,0x00,0x4e,0xc1,0x8e,0x81,0x8f,0x40,0x4f,0x01,0x8d,0xc0,0x4d, -0x80,0x4c,0x41,0x8c,0x00,0x44,0xc1,0x84,0x81,0x85,0x40,0x45,0x01,0x87,0xc0,0x47, -0x80,0x46,0x41,0x86,0x01,0x82,0xc0,0x42,0x80,0x43,0x41,0x83,0x00,0x41,0xc1,0x81, -0x81,0x80,0x40,0x40,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x63,0x03,0xff,0xff,0xbc,0x03,0x8b,0x03,0xdc,0x10,0x0e,0x00,0xfe,0xff,0xbc,0x03, -0x8b,0x03,0xda,0x10,0x02,0x00,0x00,0xfd,0xbc,0x03,0x8b,0x03,0x8e,0x10,0x02,0x00, -0x01,0xfd,0xbc,0x03,0x8b,0x03,0x90,0x10,0x06,0x00,0x02,0xfd,0xbc,0x03,0x8b,0x03, -0xaa,0x10,0x08,0x00,0x03,0xfd,0xbc,0x03,0x8b,0x03,0xb2,0x10,0x0a,0x00,0x04,0xfd, -0xbc,0x03,0x8b,0x03,0xc6,0x10,0x0a,0x00,0x05,0xfd,0xbc,0x03,0x8b,0x03,0xea,0x10, -0x0c,0x00,0x06,0xfd,0xbc,0x03,0x8b,0x03,0xf8,0x10,0x0c,0x00,0x0a,0xfd,0xbc,0x03, -0x8b,0x03,0x96,0x10,0x0c,0x00,0x0b,0xfd,0xbc,0x03,0x8b,0x03,0xa2,0x10,0x08,0x00, -0x0c,0xfd,0xbc,0x03,0x8b,0x03,0xbc,0x10,0x0a,0x00,0x0d,0xfd,0xbc,0x03,0x8b,0x03, -0xd0,0x10,0x0a,0x00,0xe0,0xfc,0x8f,0x03,0xa5,0x03,0x3c,0x00,0x02,0x00,0x09,0x00, -0x06,0x00,0x74,0x01,0x0e,0x00,0x18,0x02,0x10,0x00,0xe8,0x01,0x12,0x00,0xd9,0x01, -0x14,0x00,0xa7,0x01,0x16,0x00,0xd4,0x01,0x18,0x00,0xdc,0x01,0x1a,0x00,0xc8,0x02, -0x0a,0x00,0x85,0x01,0x00,0x01,0x80,0x00,0x00,0x02,0x01,0x04,0x38,0x06,0x80,0x08, -0x03,0x0a,0x04,0x0c,0x04,0x0e,0x00,0x10,0x00,0x12,0xc8,0x14,0x13,0x16,0x00,0x18, -0x00,0x1a,0x00,0x1c,0x5c,0x1e,0xc1,0x20,0x1e,0x22,0x54,0x24,0x07,0x26,0x6a,0x28, -0x12,0x2a,0x00,0x2c,0x00,0x2e,0x1c,0x30,0x20,0x32,0x82,0x34,0x08,0x36,0x7a,0x38, -0xca,0x3a,0x24,0x3c,0xd6,0x3e,0x00,0x40,0x00,0x42,0x00,0x44,0x7f,0x46,0x8b,0x48, -0x0f,0x4a,0x06,0x4c,0x0a,0x4e,0x0f,0x50,0x20,0x52,0x20,0x54,0x10,0x56,0x10,0x58, -0x20,0x5a,0xee,0x5c,0x1a,0x5e,0x26,0x60,0x5b,0x62,0x00,0x04,0x00,0x2c,0x0c,0x2e, -0x01,0x2c,0x10,0x2e,0x02,0x2c,0x14,0x2e,0x03,0x2c,0x18,0x2e,0x04,0x2c,0x1c,0x2e, -0x05,0x2c,0x20,0x2e,0x06,0x2c,0x24,0x2e,0x07,0x2c,0x28,0x2e,0x08,0x2c,0x2e,0x2e, -0x09,0x2c,0x34,0x2e,0x0a,0x2c,0x38,0x2e,0x0b,0x2c,0x3c,0x2e,0x0c,0x2c,0x3f,0x2e, -0x0d,0x2c,0x43,0x2e,0x0e,0x2c,0x46,0x2e,0x0f,0x2c,0x48,0x2e,0x10,0x2c,0x4b,0x2e, -0x11,0x2c,0x50,0x2e,0x12,0x2c,0x55,0x2e,0x13,0x2c,0x5a,0x2e,0x14,0x2c,0x63,0x2e, -0x15,0x2c,0x6d,0x2e,0x16,0x2c,0x76,0x2e,0x17,0x2c,0x7f,0x2e,0x18,0x2c,0x7f,0x2e, -0x19,0x2c,0x7f,0x2e,0x1a,0x2c,0x7f,0x2e,0x1b,0x2c,0x7f,0x2e,0x1c,0x2c,0x7f,0x2e, -0x1d,0x2c,0x7f,0x2e,0x1e,0x2c,0x7f,0x2e,0x1f,0x2c,0x7f,0x2e,0xff,0xff,0x0e,0xf1, -0x02,0x60,0x5f,0x64,0xc0,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0e,0xf1, -0x02,0x60,0x2c,0x64,0xc0,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x45,0xff, -0x0e,0xf1,0x02,0x60,0x15,0x64,0xc0,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xf7, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47,0xff, -0x0e,0xf1,0x02,0x60,0x15,0x64,0xc0,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0x40,0xff, -0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x41,0xff, -0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x42,0xff, -0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x43,0xff, -0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x44,0xff, -0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x45,0xff, -0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x0d,0xf7, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xfe,0x0f,0x7e,0x00, -0x0a,0x01,0xff,0xff,0x47,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xb0,0xfe,0xb1,0xfe,0xb2,0xfe,0xb3,0xfe,0xff,0x00,0xff,0xff, -0xff,0xff,0xff,0xff,0x0e,0xf1,0x03,0x60,0x0c,0x64,0xc0,0x98,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xb8,0xfe,0xb9,0xfe,0xba,0xfe,0xbb,0xfe,0xff,0x00,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0x20,0x4e,0x60,0x00,0x00,0x00,0x00,0x40,0x39,0x39,0x53,0x41,0x30,0x31, -0x30,0x30,0x30,0x30,0x30,0x30,0x00,0x80,0x01,0x00,0x00,0x00,0x00,0x00,0x17,0x00, -0x02,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x03,0x00,0x01,0x00,0x01,0x00,0x01,0x00, -0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x01,0x00, -0x01,0x00,0x01,0x00,0x00,0x00,0x02,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x00,0x00, -0x50,0x72,0x69,0x6d,0x61,0x72,0x79,0x20,0x46,0x27,0x73,0x20,0x20,0x00,0x46,0x33, -0x2e,0x31,0x30,0x2d,0x30,0x34,0x00,0x00,0x00,0x00,0x00,0x00,0x30,0x31,0x2f,0x31, -0x37,0x2f,0x32,0x30,0x30,0x32,0x00,0x00,0x00,0x00,0x01,0x80,0xff,0xff,0xff,0xff, -0xdc,0x10,0x7e,0x00,0x0e,0x00,0x00,0x00,0x03,0x00,0x00,0x00,0x96,0x10,0x7e,0x00, -0x0c,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x26,0x0e,0x7e,0x00,0x02,0x00,0x00,0x00, -0x06,0x00,0x00,0x00,0xbc,0x10,0x7e,0x00,0x0a,0x00,0x00,0x00,0x07,0x00,0x00,0x00, -0xd0,0x10,0x7e,0x00,0x0a,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0xa2,0x10,0x7e,0x00, -0x08,0x00,0x00,0x00,0xfe,0x17,0x7e,0x00,0x02,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0xf8,0x7f,0x00,0xfe,0x07,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00, -0x08,0x11,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x01,0x00,0x17,0x00,0x02,0x00, -0x02,0x00,0x01,0x00,0x06,0x00,0x02,0x00,0x00,0x00,0x03,0x00,0x02,0x00,0x01,0x00, -0x01,0x00,0x06,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00, -0x7f,0xff -}; - -const u_int8_t spectrum24t_secsym[] = { -0x46,0x49,0x4c,0x45,0x3a,0x20,0x45,0x53,0x45,0x43,0x53,0x59,0x4d,0x2c,0x54,0x33, -0x2e,0x31,0x30,0x2d,0x30,0x34,0x2c,0x46,0x33,0x2e,0x31,0x30,0x2d,0x30,0x34,0x2c, -0x30,0x31,0x2f,0x31,0x37,0x2f,0x32,0x30,0x30,0x32,0x20,0x53,0x45,0x43,0x4f,0x4e, -0x44,0x41,0x52,0x59,0x20,0x32,0x32,0x20,0x32,0x34,0x30,0x20,0x31,0x32,0x20,0x35, -0x34,0x20,0x0a,0x1a,0xfe,0x17,0x7e,0x00,0xf2,0x0f,0xde,0xc0,0xce,0xd0,0x0a,0x60, -0x04,0x63,0xa3,0xd3,0x06,0xa3,0xdc,0x80,0x00,0xa8,0x0b,0x03,0xfa,0x02,0xf6,0xa3, -0x18,0x60,0x00,0x64,0xbd,0xdb,0x00,0x60,0x7e,0x64,0xbd,0xdb,0xd0,0x60,0xce,0x64, -0xa3,0xdb,0x0c,0x60,0x23,0x78,0xff,0xff,0x7f,0x60,0xc0,0x64,0x24,0x45,0xa4,0x80, -0x7f,0x67,0x02,0x61,0x02,0x03,0x23,0x58,0xff,0xff,0x02,0x64,0x40,0x50,0x61,0xff, -0xff,0xff,0x99,0xff,0x88,0xec,0x0e,0xe3,0x12,0xe3,0x1d,0xe3,0x22,0xe3,0x2a,0xe3, -0x32,0xe3,0x3a,0xe3,0x80,0xed,0x42,0xe3,0x4a,0xe3,0x52,0xe3,0x5a,0xe3,0x62,0xe3, -0x68,0xe3,0x70,0xe3,0x7a,0xe3,0x00,0xee,0x82,0xe3,0x8a,0xe3,0x92,0xe3,0x9a,0xe3, -0xa2,0xe3,0xaa,0xe3,0xb2,0xe3,0xba,0xe3,0x01,0x60,0x14,0xe3,0x01,0x60,0x19,0xe3, -0x01,0x60,0x20,0xe3,0x01,0x60,0x28,0xe3,0x21,0x60,0x7d,0xe7,0x68,0x60,0x7d,0xe7, -0x10,0x60,0x7d,0xe7,0x7d,0xe7,0xf0,0x60,0x7d,0xe7,0xa5,0x60,0x7d,0xe7,0x7d,0xe7, -0x36,0x60,0x7d,0xe7,0x6d,0x60,0x7d,0xe7,0x98,0x60,0x7d,0xe7,0x39,0x60,0x7d,0xe7, -0x3f,0x60,0x7d,0xe7,0x42,0x60,0x7d,0xe7,0x0c,0x60,0x7d,0xe7,0xc2,0x60,0x7d,0xe7, -0x7d,0xe7,0xa5,0x60,0x7d,0xe7,0x7d,0xe7,0x36,0x60,0x7d,0xe7,0x01,0x60,0x7d,0xe7, -0xad,0x60,0x7d,0xe7,0x7d,0xe7,0x37,0x60,0x7d,0xe7,0x42,0x60,0x7d,0xe7,0x0e,0x60, -0x7d,0xe7,0xc2,0x60,0x7d,0xe7,0x07,0x60,0x80,0xe7,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xe7,0xff,0xff,0xff,0xff,0x06,0xe3, -0xff,0xff,0x98,0xff,0x73,0x60,0xeb,0x78,0xff,0xff,0x04,0xee,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0x00,0x69,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x16, -0xfe,0x00,0x68,0x5e,0x00,0x7f,0x1f,0xfb,0x88,0xec,0x00,0xee,0xff,0xff,0xff,0xff, -0x04,0xee,0xff,0xff,0xff,0xff,0x00,0xee,0xb0,0xfe,0xb1,0xfe,0xb2,0xfe,0xb3,0xfe, -0xb8,0xfe,0xb9,0xfe,0xba,0xfe,0x10,0x64,0x40,0x40,0x00,0x64,0x40,0x41,0x40,0x42, -0x40,0x54,0x40,0x55,0x40,0x5e,0x40,0x5a,0x40,0x5b,0x1d,0x60,0x8c,0x62,0xa2,0xd1, -0x12,0x60,0x34,0x64,0xd0,0x80,0xff,0xff,0x20,0x02,0x1d,0x60,0x8e,0x62,0xa2,0xd1, -0x55,0x60,0xaa,0x64,0xd0,0x80,0xff,0xff,0x18,0x02,0x1e,0x60,0x50,0x62,0xa2,0xd3, -0xff,0xff,0x01,0xa4,0xa2,0xdb,0x08,0x60,0x2e,0x64,0xa0,0xd3,0xff,0xff,0x00,0xa4, -0xe1,0xa0,0x17,0x03,0xe0,0x85,0x15,0x07,0x1e,0x60,0x52,0x62,0xff,0xff,0xc6,0x82, -0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb,0x0c,0x00,0x1e,0x60,0x50,0x62,0x00,0x64, -0xa2,0xdb,0x1e,0x60,0x52,0x63,0x00,0x64,0x20,0x61,0xbd,0xdb,0xff,0xa1,0xff,0xff, -0xfc,0x02,0x01,0x60,0x88,0x63,0x00,0x60,0x3e,0x61,0xfe,0x60,0x00,0x66,0x7f,0x60, -0xfe,0x64,0x58,0xd0,0x59,0xd9,0xfd,0x1f,0x0f,0x60,0xce,0x63,0x0e,0x60,0x7e,0x61, -0xfe,0x60,0x00,0x66,0x85,0x60,0x08,0x64,0x58,0xd0,0x59,0xd9,0xfd,0x1f,0x4a,0x60, -0x8a,0x63,0x1e,0x60,0x90,0x61,0x00,0x64,0x59,0xdb,0xfe,0x1f,0x01,0x63,0x7f,0xfd, -0x00,0x60,0x2a,0x63,0x0c,0x60,0x40,0x61,0x0e,0x60,0x7e,0x64,0x58,0xd1,0x59,0xd9, -0xfd,0x1f,0x15,0x60,0xf8,0x61,0xa1,0xd3,0xff,0xff,0xe0,0x83,0xcb,0x83,0x59,0xd1, -0x59,0xd3,0xa4,0xdb,0xfc,0x1f,0x00,0x60,0xfe,0x63,0xfe,0x60,0x00,0x65,0x45,0x4b, -0xdb,0x60,0xfe,0x61,0xfe,0x60,0x00,0x65,0x81,0x60,0x88,0x64,0x65,0x46,0x58,0xd0, -0x2b,0x46,0x59,0xd8,0xfb,0x1f,0x01,0x60,0xbe,0x63,0xdd,0x60,0x4e,0x61,0x82,0x60, -0xd8,0x64,0x65,0x46,0x58,0xd0,0x2b,0x46,0x59,0xd8,0xfb,0x1f,0x00,0x60,0x0e,0x63, -0xdf,0x60,0x1e,0x61,0x84,0x60,0xa8,0x64,0x65,0x46,0x58,0xd0,0x2b,0x46,0x59,0xd8, -0xfb,0x1f,0x69,0x60,0x1e,0x64,0x7f,0xa4,0xe0,0x87,0x00,0x7f,0x1a,0xfb,0x0d,0x60, -0x22,0x62,0x08,0x60,0x00,0x65,0xa2,0xd3,0xff,0xff,0xd4,0x80,0xff,0xff,0x0b,0x06, -0xe0,0x84,0xe0,0x84,0xe0,0x84,0xcc,0x84,0x1d,0xfb,0x65,0x44,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0x1c,0xfb,0x65,0x44,0x80,0xa4,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xcc,0x84, -0x1b,0xfb,0x1b,0xf1,0x1a,0xf3,0xff,0xff,0x9e,0xfb,0x7c,0x63,0x60,0x46,0x01,0xfc, -0xdc,0x84,0xd0,0x80,0x00,0xfa,0xfa,0x04,0x9f,0xfb,0x1c,0xf3,0x60,0x46,0x00,0xa8, -0x1d,0xf1,0x09,0x03,0x00,0xfa,0x01,0xfc,0x60,0x46,0x01,0xfc,0xdc,0x84,0xd0,0x80, -0x00,0xfa,0xfa,0x04,0x9f,0xfb,0x00,0x64,0x00,0xfa,0x63,0x44,0x80,0x7f,0x01,0xfa, -0x1b,0xf3,0x1a,0xf1,0xdc,0x84,0x50,0x93,0x33,0x44,0xfd,0xfb,0x00,0x60,0x7c,0x61, -0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0x46,0x45,0x19,0x60,0x58,0x4f,0xc4,0x78, -0xff,0xff,0x1e,0x60,0x9e,0x62,0x66,0x44,0xa2,0xdb,0x1f,0xf1,0x01,0x65,0x64,0x40, -0x10,0x2a,0x07,0x00,0xeb,0x60,0x19,0xe2,0x01,0x60,0x76,0x63,0x20,0x64,0xc5,0xfb, -0x07,0x00,0xeb,0x60,0x19,0xe2,0x00,0x65,0x01,0x60,0x18,0x63,0x14,0x64,0xc2,0xfb, -0x17,0x60,0x34,0x62,0xa2,0xdd,0x17,0x60,0x7e,0x62,0x65,0x44,0xa2,0xdb,0x00,0x60, -0x30,0xe2,0x00,0x60,0x50,0xe2,0x00,0x60,0x79,0xe2,0x01,0x60,0x90,0xe2,0x01,0x60, -0xd0,0xe2,0x01,0x60,0xf9,0xe2,0xb4,0xf3,0xb5,0xf1,0x60,0x45,0xc4,0x84,0xc0,0x84, -0x24,0xfb,0x01,0x60,0x30,0x64,0xc0,0x84,0x25,0xfb,0x60,0x45,0xa0,0xa4,0x29,0xfb, -0x01,0x60,0x60,0x64,0xc0,0x84,0x2d,0xfb,0xa0,0xa4,0x31,0xfb,0x00,0x60,0xf8,0x64, -0xc0,0x84,0x26,0xfb,0xa0,0xa4,0x2a,0xfb,0x01,0x60,0x10,0x64,0xc0,0x84,0x2e,0xfb, -0xa0,0xa4,0x32,0xfb,0x00,0x60,0xd5,0x64,0xc0,0x84,0x27,0xfb,0xa0,0xa4,0x2b,0xfb, -0x00,0x60,0xde,0x64,0xc0,0x84,0x2f,0xfb,0xa0,0xa4,0x33,0xfb,0x00,0x60,0xcb,0x64, -0xc0,0x84,0x28,0xfb,0xa0,0xa4,0x2c,0xfb,0x00,0x60,0xcf,0x64,0xc0,0x84,0x30,0xfb, -0xa0,0xa4,0x34,0xfb,0xb5,0xf3,0x24,0xf1,0xc4,0x84,0x35,0xfb,0xc0,0x84,0x37,0xfb, -0x00,0x64,0x40,0x50,0x63,0xff,0x00,0x64,0x40,0x54,0x40,0x55,0x40,0x41,0x40,0x42, -0x40,0x5e,0xd1,0xfe,0x82,0xff,0x92,0xff,0x98,0xff,0x00,0x64,0x40,0x52,0x17,0x60, -0x3a,0x65,0x1f,0xf3,0xa5,0xd1,0x60,0x40,0x10,0x2a,0xff,0xff,0x20,0x26,0x03,0x00, -0x13,0x60,0x98,0x62,0x02,0x00,0x14,0x60,0x7a,0x62,0x64,0x44,0x3e,0x7f,0xa2,0xdb, -0x1f,0xf3,0xff,0xff,0x17,0x60,0x5c,0x65,0xa5,0xd1,0x60,0x40,0x20,0x26,0x05,0x00, -0x13,0x60,0xa6,0x62,0x64,0x44,0x4c,0x7f,0x04,0x00,0x14,0x60,0x82,0x62,0x64,0x44, -0x46,0x7f,0xa2,0xdb,0x00,0x64,0x40,0x41,0x40,0x46,0x40,0x47,0x00,0xe1,0x11,0x60, -0x8e,0x63,0x0e,0x60,0xac,0x64,0xa0,0xdd,0x00,0x60,0x13,0x66,0x3c,0x64,0x01,0xfa, -0x0a,0x64,0x20,0xfa,0x87,0xff,0x97,0xff,0x08,0x60,0x28,0x62,0x23,0x60,0x45,0x64, -0xa2,0xdb,0x66,0xff,0xff,0xff,0x65,0xff,0xff,0xff,0x64,0xff,0xff,0xff,0x62,0xff, -0xff,0xff,0x61,0xff,0xff,0xff,0x3c,0x60,0xa6,0x65,0x0c,0x64,0xa5,0xdb,0x0e,0x60, -0x5a,0x64,0x97,0xfb,0xff,0xff,0x2d,0xff,0x08,0x60,0x00,0x64,0xc8,0x81,0x3e,0x63, -0x00,0x64,0x59,0xdb,0xfe,0x1f,0x04,0x60,0x41,0x76,0x10,0x60,0x5f,0x78,0xff,0xff, -0x10,0x75,0x01,0x60,0x03,0xe8,0x99,0xff,0x08,0x60,0x2a,0x62,0x04,0x60,0xff,0x64, -0xa2,0xdb,0x04,0x60,0xff,0xe5,0xff,0xff,0xff,0xff,0x10,0x60,0xdc,0xe0,0xff,0xff, -0xff,0xff,0x98,0xff,0x30,0x60,0x7f,0x78,0xff,0xff,0xa1,0xff,0xff,0xff,0xfd,0x00, -0x98,0xff,0x30,0x44,0x02,0xa8,0x00,0xe1,0x07,0x02,0x62,0xff,0x63,0xff,0x64,0xff, -0x65,0xff,0x66,0xff,0xa1,0xff,0xff,0xff,0x82,0xff,0x91,0xff,0x99,0xff,0x88,0xff, -0x6c,0x40,0x41,0xff,0xc4,0xe2,0x43,0xff,0x40,0x49,0x08,0xe1,0x10,0x60,0x81,0x78, -0xff,0xff,0x98,0xff,0x30,0x44,0x02,0xa8,0x00,0xe1,0x02,0x02,0xa1,0xff,0xff,0xff, -0x00,0x64,0xdc,0xfb,0x82,0xff,0x92,0xff,0x98,0xff,0x88,0xff,0x72,0x44,0x60,0x52, -0x03,0x04,0x01,0x64,0x40,0x40,0x05,0x00,0xdc,0x80,0xff,0xff,0x02,0x02,0x01,0x64, -0x40,0x40,0x48,0xe2,0xe2,0xf3,0xff,0xff,0x60,0x40,0x00,0x3a,0x09,0x00,0x67,0x60, -0x84,0x65,0xa5,0xd1,0xff,0xff,0x64,0x40,0x00,0x3a,0x02,0x00,0x64,0xe2,0x01,0x70, -0x6d,0xe2,0xbc,0xff,0xb5,0xff,0xff,0x64,0x40,0x4b,0x00,0x64,0x40,0x4d,0x40,0x47, -0xd7,0xfb,0x22,0xfb,0x00,0xe1,0x08,0x64,0x40,0x4c,0x26,0x44,0x02,0xb4,0x40,0x46, -0x65,0xf3,0xff,0xff,0x60,0x40,0x04,0x26,0x02,0x00,0x00,0x3a,0x03,0x00,0x68,0xe2, -0xc8,0xe2,0x68,0x00,0xb4,0xf1,0x02,0x64,0x64,0x56,0x60,0x54,0xcd,0xe2,0xc4,0xe2, -0x6c,0x40,0x07,0x60,0x80,0xe8,0x44,0xe2,0x64,0xe2,0x46,0xff,0x47,0xff,0x67,0x60, -0x5c,0x62,0x01,0x64,0xa2,0xdb,0x9c,0xfe,0xff,0xff,0x0b,0x04,0xcf,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x06,0x02,0x01,0x64,0x40,0xfb,0x26,0x44,0xfd,0xb4,0x40,0x46, -0x05,0xff,0x27,0x44,0x06,0x22,0x06,0x00,0xf9,0xb4,0x40,0x47,0x02,0x64,0x21,0xfb, -0xc0,0xfe,0x03,0x00,0x20,0x64,0x21,0xfb,0xc0,0xfe,0x99,0xff,0x3d,0x44,0xf7,0xb4, -0x40,0x5d,0x98,0xff,0x99,0xff,0x3c,0x44,0x7f,0xb4,0x10,0xbc,0x40,0x5c,0x3e,0x44, -0x7c,0xb4,0x08,0xbc,0x40,0x5e,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0x99,0xff,0x3d,0x44,0x10,0xbc,0x00,0x7f,0x40,0x5d,0x98,0xff,0xbc,0xff, -0xff,0xff,0xb5,0xff,0xff,0xff,0x99,0xff,0x07,0x60,0x80,0xe9,0x98,0xff,0xff,0xff, -0xff,0xff,0x80,0xe9,0xff,0xff,0xff,0xff,0xb7,0xff,0xb4,0xff,0x99,0xff,0x3e,0x44, -0x02,0xbc,0x00,0x7f,0x40,0x5e,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0x46,0xff,0x47,0xff,0x0e,0x60,0xac,0x64,0xa0,0xd7,0xff,0xff,0xff,0xff,0x98,0xff, -0x30,0x44,0x02,0xa8,0x00,0xe1,0x0f,0x03,0x83,0xff,0x8d,0xff,0x00,0x64,0x40,0x40, -0x40,0x44,0x40,0x43,0x40,0x42,0x40,0x41,0x1a,0x60,0xcc,0x64,0x40,0x4e,0x3c,0x60, -0x6a,0x64,0x40,0x4d,0xe3,0xe1,0x19,0x60,0x56,0x78,0xff,0xff,0x98,0xff,0x30,0x44, -0x02,0xa8,0x00,0xe1,0x02,0x02,0xa1,0xff,0xff,0xff,0x84,0xff,0x88,0xff,0x98,0xff, -0x99,0xff,0xf2,0xe6,0xda,0xe6,0x98,0xff,0x1b,0x60,0x20,0x64,0x40,0x40,0xa8,0xf3, -0x80,0xfb,0x0a,0x64,0x40,0x4b,0x1e,0x60,0x98,0x65,0xb8,0xf3,0xff,0xff,0xa5,0xdb, -0x01,0x64,0x8c,0xfb,0x00,0x64,0x8e,0xfb,0x8d,0xfb,0x40,0x5c,0x1b,0x60,0x20,0x78, -0xff,0xff,0x98,0xff,0x88,0xe2,0x30,0x44,0x00,0xe1,0x02,0xa8,0x85,0xff,0x02,0x02, -0xa1,0xff,0xff,0xff,0x88,0xff,0x99,0xff,0x00,0x60,0x00,0xeb,0xff,0xff,0xff,0xff, -0x00,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x4f,0x60,0xf3,0xea,0x4f,0x60,0x36,0xeb, -0x43,0x60,0x40,0xea,0x43,0x60,0xe4,0xeb,0x44,0x60,0x52,0xea,0x44,0x60,0x34,0xeb, -0x45,0x60,0x7d,0xea,0x45,0x60,0x58,0xeb,0x47,0x60,0x8b,0xea,0x47,0x60,0xd0,0xeb, -0x48,0x60,0x47,0xea,0x48,0x60,0xc3,0xeb,0x49,0x60,0xa0,0xea,0x49,0x60,0xfd,0xeb, -0x4a,0x60,0xb2,0xea,0x4a,0x60,0x34,0xeb,0x4b,0x60,0xc1,0xea,0x4b,0x60,0x58,0xeb, -0x4c,0x60,0xd7,0xea,0x4c,0x60,0xc0,0xeb,0x4d,0x60,0xeb,0xea,0x4d,0x60,0xd0,0xeb, -0x4e,0x60,0xa0,0xea,0x4e,0x60,0x91,0xeb,0x40,0x60,0xf0,0xea,0x40,0x60,0xfc,0xeb, -0x41,0x60,0x24,0xea,0x41,0x60,0xa2,0xeb,0x42,0x60,0x20,0xea,0x42,0x60,0x20,0xeb, -0x3a,0x5c,0x80,0x2b,0x12,0x00,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b, -0x09,0x00,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b,0x03,0x00,0x8b,0xff, -0x74,0x40,0x88,0xff,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b,0xff,0xff, -0x31,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xea,0x3a,0x5c,0x80,0x27, -0x06,0x00,0x31,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xea,0x67,0x60, -0xcc,0x64,0x3a,0x5c,0xa0,0xd9,0xff,0xff,0x30,0x60,0x00,0xea,0xff,0xff,0xff,0xff, -0x67,0x60,0xcc,0x64,0x3a,0x5c,0xa0,0xd9,0x3a,0x5c,0x40,0x27,0xfc,0x00,0xa0,0xd9, -0x00,0x60,0x00,0xeb,0xa0,0x60,0x00,0xeb,0xc0,0x60,0x00,0xeb,0x30,0x60,0x00,0xeb, -0x67,0x60,0xce,0x64,0x3b,0x5c,0xa0,0xd9,0x3b,0x5c,0x40,0x27,0xfc,0x00,0xa0,0xd9, -0x67,0x60,0xcc,0x64,0x3a,0x5c,0xa0,0xd9,0x98,0xff,0xc0,0x60,0x00,0xeb,0x00,0x64, -0x3e,0xfb,0x40,0xfb,0xff,0xff,0x67,0x60,0x4c,0x62,0x00,0x64,0xa2,0xdb,0x0a,0x64, -0x40,0x48,0x03,0x60,0xe8,0x64,0x40,0x4b,0x67,0x60,0x4a,0x62,0x05,0x60,0xdc,0x64, -0xa2,0xdb,0x1e,0x64,0x40,0x4c,0x69,0xe1,0x04,0x60,0x00,0x71,0x8d,0xe2,0x00,0x64, -0x40,0x40,0xf8,0x60,0x89,0x78,0xff,0xff,0xa2,0xff,0x98,0xff,0x30,0x44,0x02,0xa8, -0x00,0xe1,0x28,0x03,0x86,0xff,0x88,0xff,0x18,0x60,0xc6,0x65,0x64,0x64,0xa5,0xdb, -0xff,0xff,0x00,0x64,0x40,0x46,0x58,0xfb,0x28,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff, -0x28,0x60,0x58,0x4f,0x87,0x78,0xff,0xff,0x29,0x60,0x58,0x4f,0x0f,0x78,0xff,0xff, -0x28,0x60,0x58,0x4f,0x3b,0x78,0xff,0xff,0x27,0x60,0x58,0x4f,0xe8,0x78,0xff,0xff, -0x27,0x60,0x58,0x4f,0xd1,0x78,0xff,0xff,0x27,0x60,0x58,0x4f,0xff,0x78,0xff,0xff, -0x13,0xe1,0xa3,0xff,0x3d,0x60,0x2f,0x78,0xff,0xff,0x0f,0x4e,0x01,0x60,0xe4,0x61, -0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff, -0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f, -0x66,0x44,0x15,0xfb,0x07,0xe1,0xa3,0xff,0x04,0x60,0x41,0x76,0x00,0x60,0x00,0x7c, -0x08,0x60,0x14,0x64,0xa0,0xd9,0xae,0xff,0x30,0x60,0x7f,0x78,0xff,0xff,0xa1,0xff, -0xff,0xff,0x2c,0x45,0xb8,0x3f,0x41,0xff,0x30,0x44,0x20,0xb4,0x34,0x91,0x9f,0xfe, -0xff,0xff,0x43,0x05,0x29,0x44,0x05,0x22,0xf2,0x00,0x04,0x26,0x3a,0x00,0x01,0x2a, -0xee,0x00,0x44,0xff,0xc8,0x74,0xcd,0xe2,0x0c,0xe1,0x29,0x44,0xfe,0xb4,0x40,0x49, -0x24,0x41,0xe1,0x81,0x00,0x60,0xc8,0x65,0xc5,0x94,0x0c,0xe1,0xe0,0x00,0x1a,0xff, -0xde,0x00,0xdd,0x00,0x41,0xff,0x40,0x64,0xa0,0xfb,0x3e,0x44,0x01,0x26,0xd7,0x00, -0x08,0x00,0xc4,0xe2,0x41,0x64,0xa0,0xfb,0x3e,0x44,0x01,0x2a,0x02,0x00,0x62,0xff, -0x09,0x00,0x01,0x64,0xdc,0xfb,0x67,0x60,0x56,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x1a,0xff,0x67,0x60,0xc8,0x62,0x01,0x64,0xa2,0xdb,0x08,0xe1,0x00,0x64, -0x40,0x49,0x72,0x52,0x32,0x7b,0x4d,0xe2,0x44,0xff,0xb9,0x00,0xb8,0x00,0xb7,0x00, -0xb6,0x00,0x29,0x44,0xfb,0xb4,0x40,0x49,0xb6,0x00,0x65,0xf3,0xff,0xff,0xff,0xff, -0x04,0x2a,0x04,0x00,0xbf,0xfe,0x10,0x60,0xb3,0x78,0xff,0xff,0x99,0xf1,0x99,0xff, -0x64,0x40,0x02,0x3b,0x03,0x00,0x11,0x60,0x5f,0x78,0xff,0xff,0x03,0x60,0xe8,0x74, -0xcd,0xe2,0x04,0xe1,0xa1,0xff,0xff,0xff,0x3c,0x44,0x6f,0xb4,0x40,0x5c,0x00,0x6b, -0x3e,0x44,0x74,0xb4,0x04,0xbc,0x40,0x5e,0xff,0xff,0xff,0xff,0x02,0xbd,0x45,0x5e, -0xff,0xff,0xff,0xff,0x40,0x5e,0x00,0xe1,0x00,0x7c,0x15,0x60,0x22,0x62,0x58,0x4f, -0x18,0x00,0x58,0x4f,0x16,0x00,0x58,0x4f,0x14,0x00,0x58,0x4f,0x12,0x00,0x01,0x7c, -0x58,0x4f,0x0f,0x00,0x58,0x4f,0x0d,0x00,0x3d,0x44,0x7f,0xb4,0x40,0x5d,0xff,0xff, -0xff,0xff,0x80,0xbc,0x40,0x5d,0xbf,0xfe,0x2d,0xff,0x08,0xe1,0x10,0x60,0x81,0x78, -0xff,0xff,0x02,0x65,0xa2,0xd3,0x02,0xa2,0x60,0x47,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x81,0x06,0x63,0xe1,0x81,0x3d,0x44,0x80,0xb4,0x10,0xbc,0x02,0x24,0x04,0xbc, -0x40,0x5d,0xff,0xff,0x34,0x9d,0xf6,0x1f,0xff,0xff,0xff,0xff,0x40,0x5d,0xa2,0xd3, -0x02,0xa2,0x60,0x47,0x60,0x41,0x0e,0x63,0xe1,0x81,0x3d,0x44,0x80,0xb4,0x10,0xbc, -0x02,0x24,0x04,0xbc,0x40,0x5d,0xff,0xff,0x34,0x9d,0xf6,0x1f,0xff,0xff,0xff,0xff, -0x40,0x5d,0xa2,0xd3,0x02,0xa2,0x60,0x47,0x60,0x41,0x0e,0x63,0xe1,0x81,0x3d,0x44, -0x80,0xb4,0x10,0xbc,0x02,0x24,0x04,0xbc,0x40,0x5d,0xff,0xff,0x34,0x9d,0xf6,0x1f, -0xff,0xff,0xff,0xff,0x40,0x5d,0x64,0x40,0x01,0x26,0x08,0x00,0x3c,0x44,0x5f,0xb4, -0x20,0x65,0x34,0x9c,0xff,0xff,0xff,0xff,0x40,0x5c,0x05,0x00,0x01,0x65,0x34,0x9d, -0xff,0xff,0xff,0xff,0x40,0x5d,0x2f,0x58,0xff,0xff,0x99,0xf1,0x00,0xe1,0x64,0x44, -0x00,0x7f,0xe0,0x85,0xc4,0x84,0xe0,0x85,0x3c,0x44,0x6f,0xb4,0x40,0x5c,0x00,0x6b, -0x3e,0x44,0x74,0xb4,0x40,0x5e,0x01,0x7c,0x15,0x60,0x46,0x62,0xc6,0x82,0x58,0x4f, -0xa0,0x00,0x01,0x60,0xf4,0x64,0x60,0x54,0xcd,0xe2,0x32,0x44,0x08,0x2b,0xfd,0x00, -0x3c,0x44,0x7f,0xb4,0x10,0xbc,0x40,0x5c,0x62,0xff,0x01,0x7c,0x08,0x60,0x2a,0x64, -0xa0,0xd9,0x9a,0xf3,0xbf,0xfe,0x60,0x40,0x05,0x36,0x2d,0xff,0x07,0x36,0xd8,0xfe, -0x08,0xe1,0x10,0x60,0x81,0x78,0xff,0xff,0xdc,0xf3,0xff,0xff,0x60,0x40,0x00,0x36, -0x03,0x00,0x0e,0x60,0x8b,0x78,0xff,0xff,0x00,0x64,0xa0,0xfb,0x0a,0x64,0x40,0x4c, -0x19,0xff,0x20,0x44,0x01,0x2a,0x04,0x00,0x00,0x64,0x40,0x40,0xa1,0xf3,0x09,0x00, -0x1a,0xe1,0x00,0x64,0xd0,0xfb,0x31,0x44,0x01,0x26,0x1b,0xe1,0xa1,0xff,0xff,0xff, -0xb9,0x3f,0x72,0x45,0xdc,0x84,0xa1,0xfb,0x60,0x55,0x65,0x52,0x11,0x64,0xa0,0xfb, -0xa2,0xf3,0x06,0x04,0xdc,0x84,0xa2,0xfb,0xa3,0xf3,0x02,0x04,0xdc,0x84,0xa3,0xfb, -0x4b,0xf3,0xff,0xff,0xfe,0xa0,0x65,0xf3,0xe3,0x04,0x60,0x40,0x02,0x2a,0xe0,0x00, -0x99,0xff,0x3d,0x44,0x7f,0xb4,0x00,0x7f,0x40,0x5d,0x80,0xbc,0xff,0xff,0xff,0xff, -0x40,0x5d,0x98,0xff,0x00,0x64,0x4b,0xfb,0xd3,0x00,0x22,0xf1,0x43,0xff,0x64,0x40, -0x07,0x26,0x03,0x00,0x12,0x60,0x2e,0x78,0xff,0xff,0x6c,0x40,0x03,0xe1,0x00,0x6b, -0x99,0xff,0x3e,0x44,0x01,0xbc,0x00,0x7f,0x40,0x5e,0xdd,0xf1,0x3d,0x44,0xe7,0xb4, -0x40,0x5d,0x3e,0x44,0xed,0xb4,0xb0,0x84,0x40,0x5e,0x3d,0x44,0x08,0xbc,0x40,0x5d, -0x98,0xff,0x05,0x64,0xcc,0x84,0xff,0xff,0xfd,0x02,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x99,0xff,0x3e,0x44,0x77,0xb4,0x80,0xbc, -0x40,0x5e,0x98,0xff,0x3c,0x46,0x1c,0xf0,0x53,0xf3,0x64,0x41,0x08,0xb1,0x60,0x45, -0x03,0x22,0x00,0x61,0xb5,0x85,0x2b,0x5c,0xd1,0x80,0x1f,0xf1,0x0b,0x03,0x41,0x4b, -0x38,0x64,0x65,0x40,0x08,0x2a,0x80,0x64,0x60,0x48,0x88,0x6a,0xff,0xff,0xff,0xff, -0x01,0x16,0xfe,0x00,0x7f,0xf1,0x10,0x64,0x64,0x40,0x0e,0x36,0xb4,0x85,0x65,0x48, -0x8a,0x6a,0xff,0xff,0xff,0xff,0x01,0x16,0xfe,0x00,0x4b,0xf3,0xff,0xff,0x00,0xa0, -0xff,0xff,0x0a,0x03,0x99,0xff,0x3d,0x44,0x7f,0xb4,0x00,0x7f,0x40,0x5d,0x80,0xbd, -0x00,0x64,0x4b,0xfb,0x45,0x5d,0x98,0xff,0x22,0xf1,0x23,0xf3,0x64,0x45,0x00,0xbc, -0x00,0x64,0x4d,0x03,0x00,0x61,0x23,0xfb,0x5e,0xf1,0xa4,0xf3,0x64,0x40,0x04,0x2a, -0x06,0x00,0x60,0x45,0x73,0x44,0xd4,0x84,0xe7,0xa0,0x0d,0x0e,0x0c,0x04,0x28,0x60, -0xda,0x63,0x72,0x45,0x65,0x44,0xd4,0xfb,0x04,0x05,0x65,0x44,0xdc,0x80,0xff,0xff, -0x05,0x02,0x01,0x64,0x40,0x40,0x11,0x60,0x8e,0x78,0xff,0xff,0xff,0x60,0xf0,0x64, -0xd4,0x80,0x20,0xa4,0xf8,0x04,0xd4,0x80,0xff,0xff,0xf5,0x07,0x02,0xfe,0xbd,0xd3, -0xff,0xff,0x44,0x8a,0x02,0x24,0xdd,0x81,0x02,0x24,0xdd,0x81,0xbd,0xd3,0xa1,0xf1, -0x61,0x45,0xc0,0x84,0x00,0x61,0x02,0x24,0x01,0xb9,0xc4,0x84,0x60,0x55,0x2a,0x52, -0xa1,0xfb,0x02,0x24,0x01,0xb9,0xbd,0xd3,0xa2,0xf1,0x61,0x45,0xc0,0x84,0x00,0x61, -0x02,0x24,0x01,0xb9,0xc4,0x84,0xa2,0xfb,0x02,0x24,0x01,0xb9,0xbd,0xd3,0xa3,0xf1, -0x61,0x45,0xc0,0x84,0xc4,0x84,0xa3,0xfb,0x22,0xf3,0xff,0xff,0x60,0x45,0x65,0x40, -0x01,0x2a,0x07,0x00,0x3c,0x44,0x40,0x42,0x22,0xf3,0xff,0xff,0xfe,0xb4,0x22,0xfb, -0x06,0x00,0x11,0x60,0x8e,0x78,0xff,0xff,0x11,0x60,0x8e,0x78,0xff,0xff,0x07,0x64, -0xa0,0xfb,0x22,0x46,0x0f,0xf0,0xff,0xff,0x64,0x40,0x01,0x2a,0x03,0x00,0x16,0x60, -0x40,0x78,0xff,0xff,0x15,0x60,0x3b,0x78,0xff,0xff,0x27,0x44,0x04,0x2a,0x09,0x00, -0xfb,0xb4,0x40,0x47,0x3c,0x46,0x02,0x64,0x21,0xfb,0xc0,0xfe,0x11,0x60,0x8e,0x78, -0xff,0xff,0x27,0x44,0x02,0x2a,0x08,0x00,0xfd,0xb4,0x40,0x47,0x06,0x64,0x21,0xfb, -0xc0,0xfe,0x11,0x60,0x8e,0x78,0xff,0xff,0x02,0x0a,0x00,0x64,0x60,0x50,0x11,0x60, -0x8e,0x78,0xff,0xff,0x01,0x60,0x2c,0x74,0xcd,0xe2,0x46,0xff,0x47,0xff,0x01,0x64, -0x57,0xfb,0x83,0xe1,0x00,0x65,0x26,0x44,0x02,0x26,0x09,0x00,0x3e,0x44,0x34,0x81, -0xff,0xff,0x05,0x03,0x45,0x5e,0x26,0x44,0x02,0xbc,0x40,0x46,0xd1,0xfe,0x0c,0x64, -0x40,0x4c,0x19,0xff,0xa1,0xff,0x4c,0x4e,0x01,0x25,0x00,0x00,0x01,0x64,0xd0,0xfb, -0x4b,0x74,0xcd,0xe2,0xf0,0x60,0x00,0x78,0x00,0x61,0x46,0xff,0x47,0xff,0x11,0x60, -0x8e,0x78,0xff,0xff,0x99,0xff,0x3e,0x44,0xfd,0xb4,0x40,0x5e,0x98,0xff,0xb5,0xff, -0xbc,0xff,0x46,0xff,0xb7,0xff,0xb4,0xff,0xff,0xff,0xff,0xff,0x84,0x60,0x1d,0x7d, -0xb5,0xff,0xff,0xff,0x99,0xff,0x07,0x60,0x80,0xe9,0x98,0xff,0xff,0xff,0xff,0xff, -0x80,0xe9,0xff,0xff,0xff,0xff,0xb7,0xff,0xb4,0xff,0xff,0xff,0x99,0xff,0x3e,0x44, -0x02,0xbc,0x00,0x7f,0x40,0x5e,0x98,0xff,0xff,0xff,0xff,0xff,0x46,0xff,0x47,0xff, -0x26,0x43,0x04,0x2a,0x50,0x00,0xfb,0xb3,0x43,0x46,0x04,0xbb,0x2a,0x44,0x23,0xfa, -0x20,0x44,0xe8,0x80,0x00,0x64,0x40,0x40,0xa1,0xf3,0x05,0x04,0x72,0x45,0xdc,0x84, -0xa1,0xfb,0x60,0x55,0x65,0x52,0x24,0xfa,0xa2,0xf3,0x02,0x04,0xdc,0x84,0xa2,0xfb, -0x27,0xfa,0xa3,0xf3,0x02,0x04,0xdc,0x84,0xa3,0xfb,0x28,0xfa,0x2a,0x44,0xdc,0x80, -0xff,0xff,0x01,0x02,0x58,0x80,0xf4,0xb3,0x32,0x40,0x01,0x2a,0x08,0x00,0x04,0xbb, -0x0f,0xfc,0x01,0x5d,0xdc,0xfe,0x05,0xff,0x11,0x60,0x8e,0x78,0xff,0xff,0x2d,0x44, -0x0c,0x26,0x0d,0x00,0xcf,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x04,0x03,0x26,0x44, -0x02,0xbc,0x40,0x46,0x36,0x00,0x0f,0xfc,0x01,0x5d,0xdc,0xfe,0x05,0xff,0x27,0x44, -0x04,0x2a,0x09,0x00,0xfb,0xb4,0x40,0x47,0x2d,0x44,0x58,0x36,0x37,0x00,0x02,0x64, -0x21,0xfb,0xc0,0xfe,0x26,0x00,0x02,0x2a,0x24,0x00,0xfd,0xb4,0x40,0x47,0x06,0x64, -0x21,0xfb,0xc0,0xfe,0x1e,0x00,0x2a,0x44,0xdc,0x80,0xff,0xff,0x01,0x02,0x58,0x80, -0x27,0x44,0x80,0x2a,0x13,0x00,0x7f,0xb4,0x40,0x47,0x27,0x44,0x04,0x2a,0x06,0x00, -0xfb,0xb4,0x40,0x47,0x02,0x64,0x21,0xfb,0xc0,0xfe,0x08,0x00,0x27,0x44,0x02,0x2a, -0x05,0x00,0xfd,0xb4,0x40,0x47,0x06,0x64,0x21,0xfb,0xc0,0xfe,0x11,0x60,0x8e,0x78, -0xff,0xff,0x26,0x44,0x80,0x2a,0x07,0x00,0x20,0xf1,0x70,0x44,0xd0,0x80,0xff,0xff, -0x02,0x05,0x64,0xe2,0x64,0x50,0x11,0x60,0x8e,0x78,0xff,0xff,0x06,0x64,0xa0,0xfb, -0x22,0x46,0x29,0xf0,0xf7,0x60,0xff,0x64,0xa0,0x84,0xa2,0xda,0x04,0x64,0x03,0xfa, -0x00,0xf2,0xff,0xff,0x04,0xfa,0x01,0x64,0x21,0xfb,0xc0,0xfe,0x11,0x60,0x8e,0x78, -0xff,0xff,0x04,0x64,0xa0,0xfb,0x46,0xff,0x47,0xff,0x0a,0x64,0x40,0x4c,0x19,0xff, -0x03,0xe1,0x29,0xf2,0xff,0xff,0x0c,0xb4,0xff,0xff,0x08,0x3a,0x0f,0x00,0x17,0x60, -0xea,0x64,0xa0,0xd3,0xff,0xff,0xe8,0x84,0xe0,0x84,0x60,0x45,0x17,0x60,0xee,0x64, -0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0xff,0xff,0xa1,0xff,0xff,0xff, -0xb9,0x3f,0x00,0x6b,0x99,0xff,0x3e,0x44,0x01,0xbc,0x00,0x7f,0x40,0x5e,0xdd,0xf1, -0x3d,0x44,0xe7,0xb4,0x40,0x5d,0x3e,0x44,0xed,0xb4,0xb0,0x84,0x40,0x5e,0x3d,0x44, -0x08,0xbc,0x40,0x5d,0x98,0xff,0x05,0x64,0xcc,0x84,0xff,0xff,0xfd,0x02,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x99,0xff,0x3e,0x44, -0x77,0xb4,0x80,0xbc,0x40,0x5e,0x98,0xff,0x22,0xf2,0x08,0x63,0xff,0xff,0x08,0x2a, -0x00,0x63,0x28,0x44,0x04,0x26,0x0a,0x00,0x25,0x44,0x06,0xfa,0x60,0x46,0x01,0xf2, -0xff,0xff,0x61,0x5e,0x03,0x2b,0x01,0xfa,0x21,0x46,0x0d,0x00,0x28,0x44,0xb4,0x36, -0x0a,0x00,0x08,0x63,0x3c,0x46,0x1c,0xf2,0x53,0xf3,0x60,0x40,0xf0,0x27,0x7e,0x00, -0x5c,0x07,0x08,0x2a,0x00,0x63,0x21,0x46,0x60,0x45,0x1b,0x00,0x20,0xf2,0xff,0xff, -0x00,0x7f,0xf6,0xa0,0x00,0x65,0x07,0x03,0xec,0xa0,0x01,0x65,0x04,0x03,0xc9,0xa0, -0x02,0x65,0x01,0x03,0x03,0x65,0x29,0xf2,0xff,0xff,0x0c,0xb4,0xff,0xff,0x00,0x36, -0x08,0x00,0x59,0x60,0x68,0x62,0xa2,0xd3,0xff,0xff,0xd4,0x80,0xff,0xff,0x01,0x05, -0x60,0x45,0x45,0x45,0x65,0x40,0x03,0x22,0x00,0x63,0xb7,0x85,0x2b,0x5c,0xd3,0x80, -0xff,0xff,0x0b,0x03,0x43,0x4b,0x38,0x64,0x65,0x40,0x08,0x2a,0x80,0x64,0x60,0x48, -0x88,0x6a,0xff,0xff,0xff,0xff,0x01,0x16,0xfe,0x00,0x7f,0xf1,0x00,0x64,0x64,0x40, -0x0e,0x36,0x10,0x64,0xb4,0x85,0x65,0x48,0x8a,0x6a,0xff,0xff,0xff,0xff,0x01,0x16, -0xfe,0x00,0x4b,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x0a,0x03,0x99,0xff,0x3d,0x44, -0x7f,0xb4,0x00,0x7f,0x40,0x5d,0x80,0xbd,0x00,0x64,0x4b,0xfb,0x45,0x5d,0x98,0xff, -0x2a,0x44,0x23,0xfa,0x20,0x44,0xe8,0x80,0x00,0x64,0x40,0x40,0xa1,0xf3,0x05,0x04, -0x72,0x45,0xdc,0x84,0xa1,0xfb,0x60,0x55,0x65,0x52,0x24,0xfa,0xa2,0xf3,0x02,0x04, -0xdc,0x84,0xa2,0xfb,0x27,0xfa,0xa3,0xf3,0x02,0x04,0xdc,0x84,0xa3,0xfb,0x28,0xfa, -0x2a,0x44,0xdc,0x80,0xff,0xff,0x01,0x02,0x58,0x80,0x08,0x29,0x09,0x00,0x22,0xf1, -0xff,0xff,0x64,0x40,0x07,0x2e,0x04,0x00,0x43,0xff,0x10,0x64,0x21,0xfb,0xc0,0xfe, -0x2d,0x44,0x08,0x22,0x03,0x00,0x0d,0xb0,0x0c,0x3a,0x0a,0x00,0x26,0x43,0x84,0xbb, -0xf4,0xb3,0x21,0x46,0x0f,0xfc,0x00,0x64,0x40,0x46,0x01,0x5d,0xdc,0xfe,0x05,0xff, -0x09,0x64,0xa0,0xfb,0x28,0x44,0xb4,0x3a,0x0b,0x00,0x27,0x44,0x06,0x22,0x05,0x00, -0xf9,0xb4,0x40,0x47,0x02,0x64,0x21,0xfb,0xc0,0xfe,0x17,0x60,0x32,0x78,0xff,0xff, -0xa4,0x36,0x0a,0x00,0x04,0x26,0x0b,0x00,0x27,0x44,0x06,0x22,0x05,0x00,0xf9,0xb4, -0x40,0x47,0x02,0x64,0x21,0xfb,0xc0,0xfe,0x16,0x60,0xeb,0x78,0xff,0xff,0x28,0x44, -0xd4,0x3a,0x5b,0x00,0x48,0xe2,0x1c,0x42,0x22,0x46,0x1c,0xf2,0xff,0xff,0x07,0xb4, -0xfc,0xa0,0x03,0x64,0x01,0x02,0x1c,0xfa,0x27,0xf0,0x01,0x60,0x00,0x64,0xc0,0x84, -0x27,0xfa,0x26,0xf0,0xff,0x60,0x00,0x64,0xa0,0x84,0x26,0xfa,0x59,0x60,0xec,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x53,0xf3,0x00,0x7c,0x60,0x43,0xe0,0x84,0xe0,0x84,0x60,0x45, -0x59,0x60,0xf0,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x18,0x60,0xbc,0x65,0xe3,0x83, -0xc7,0x82,0xa2,0xd9,0x27,0x44,0xf8,0xb4,0x40,0x44,0x29,0xf0,0xf7,0x60,0xff,0x64, -0xa0,0x84,0xa2,0xda,0x0b,0xf2,0x03,0xfa,0xff,0xff,0x0c,0xf2,0x04,0xfa,0x34,0xf2, -0xff,0xff,0xdc,0x84,0x34,0xfa,0x14,0xf2,0x0f,0xb5,0x0f,0xb4,0xcc,0x84,0x94,0x80, -0x29,0xf0,0x04,0x02,0xfb,0x60,0xff,0x64,0xa0,0x84,0x03,0x00,0x04,0x64,0x60,0x47, -0xb0,0x84,0x29,0xfa,0x00,0x64,0x15,0xfa,0x3f,0x00,0xc4,0x3a,0x1d,0x00,0x27,0x44, -0xfd,0xb4,0x40,0x47,0x48,0xe2,0x5a,0x60,0x2e,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x5a,0x60, -0xbe,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x20,0x00,0x28,0x44,0x04,0x2a,0x0b,0x00,0x32,0x44, -0x04,0x2a,0x08,0x00,0x22,0xf3,0xff,0xff,0xff,0xff,0x02,0x2a,0x03,0x00,0x17,0x60, -0x98,0x78,0xff,0xff,0x04,0x26,0x08,0x00,0x68,0x3a,0x06,0x00,0x32,0x44,0x00,0x2b, -0x03,0x00,0x15,0x60,0x36,0x78,0xff,0xff,0x11,0x60,0x8e,0x78,0xff,0xff,0x0a,0x64, -0xa0,0xfb,0x11,0x60,0x8e,0x78,0xff,0xff,0x1c,0x42,0x22,0x46,0x53,0xf3,0xff,0xff, -0x40,0x45,0x29,0xf2,0xff,0xff,0xff,0xff,0x04,0x2b,0x61,0x00,0x16,0xf2,0xff,0xff, -0x40,0x43,0x21,0xf2,0x25,0x40,0x02,0x36,0xe0,0x84,0x55,0xf3,0x60,0x41,0x60,0x45, -0x23,0x60,0x58,0x4f,0x58,0x78,0xff,0xff,0xae,0x81,0xff,0xff,0x0d,0x03,0xdc,0x84, -0x03,0x65,0xd5,0x80,0x25,0x40,0x03,0x3a,0x07,0x00,0x06,0x07,0x23,0x5c,0x60,0x41, -0x00,0x64,0x80,0x7f,0x30,0x83,0x61,0x44,0x40,0x44,0x0f,0x64,0x14,0xf0,0x34,0xf2, -0xa0,0x81,0x0f,0xb4,0xc9,0x85,0xd4,0x80,0x24,0x44,0x0f,0x02,0x1f,0xf2,0x25,0x40, -0x02,0x36,0xe0,0x84,0x55,0xf3,0x60,0x41,0x60,0x45,0x23,0x60,0x58,0x4f,0x58,0x78, -0xff,0xff,0xae,0x81,0xff,0xff,0x01,0x03,0xdc,0x84,0xc0,0x65,0xc4,0x85,0x59,0x60, -0x68,0x61,0xa1,0xd1,0x25,0x44,0xd0,0x80,0xff,0xff,0x01,0x04,0x64,0x44,0x2b,0x5c, -0x08,0x26,0x0a,0x00,0x00,0x36,0x25,0xf1,0x01,0x36,0x26,0xf1,0x02,0x36,0x27,0xf1, -0x03,0x36,0x28,0xf1,0x65,0x44,0x0a,0x00,0x00,0x36,0x29,0xf1,0x01,0x36,0x2a,0xf1, -0x02,0x36,0x2b,0xf1,0x03,0x36,0x2c,0xf1,0x65,0x44,0xa0,0xa4,0xc0,0x84,0xb5,0xf1, -0xc0,0x84,0xc0,0x84,0x2a,0xfa,0x27,0x44,0x40,0xbc,0x40,0x47,0x44,0x00,0x17,0xf2, -0x1f,0xf2,0x40,0x43,0x25,0x40,0x02,0x36,0xe0,0x84,0x55,0xf3,0x60,0x41,0x60,0x45, -0x23,0x60,0x58,0x4f,0x58,0x78,0xff,0xff,0xae,0x81,0xff,0xff,0x0d,0x03,0xdc,0x84, -0x03,0x65,0xd5,0x80,0x25,0x40,0x03,0x3a,0x07,0x00,0x06,0x07,0x23,0x5c,0x60,0x41, -0x00,0x64,0x80,0x7f,0x30,0x83,0x61,0x44,0x40,0x44,0x56,0x64,0xa0,0xd2,0x00,0x7c, -0x60,0x40,0x01,0x26,0x1c,0x00,0x59,0x60,0x68,0x61,0xa1,0xd1,0x25,0x44,0xd0,0x80, -0xff,0xff,0x01,0x04,0x64,0x44,0x2b,0x5c,0x08,0x26,0x09,0x00,0x00,0x36,0x25,0xf1, -0x01,0x36,0x26,0xf1,0x02,0x36,0x27,0xf1,0x03,0x36,0x28,0xf1,0x08,0x00,0x00,0x36, -0x29,0xf1,0x01,0x36,0x2a,0xf1,0x02,0x36,0x2b,0xf1,0x03,0x36,0x2c,0xf1,0x2a,0xf8, -0x27,0x44,0xbf,0xb4,0x40,0x47,0x22,0x46,0x29,0xf0,0x6b,0x44,0x64,0x40,0x40,0x27, -0x80,0xbc,0x60,0x4b,0xf3,0x60,0x58,0x4f,0xba,0x78,0xff,0xff,0xbc,0xff,0x22,0x46, -0x2b,0xf2,0xff,0xff,0xff,0xff,0x01,0x26,0x0e,0x00,0x27,0x44,0x04,0xbc,0x40,0x47, -0x35,0xf3,0xb4,0xff,0x60,0x5b,0x4d,0xe2,0x84,0x60,0x1d,0x7d,0x8e,0x60,0x00,0x6b, -0x13,0x60,0x9b,0x78,0xff,0xff,0xb5,0xff,0xbc,0xff,0x46,0xff,0x47,0xff,0xb7,0xff, -0xb4,0xff,0x00,0x6b,0x99,0xff,0x3e,0x44,0x7c,0xb4,0x08,0xbc,0x40,0x5e,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x99,0xff, -0x3d,0x44,0x10,0xbc,0x00,0x7f,0x40,0x5d,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xb7,0xff, -0xb4,0xff,0xff,0xff,0xff,0xff,0x84,0x60,0x1d,0x7d,0x99,0xff,0x3e,0x44,0x02,0xbc, -0x00,0x7f,0x40,0x5e,0x98,0xff,0xff,0xff,0x46,0xff,0x47,0xff,0x13,0x60,0x88,0x78, -0xff,0xff,0x0e,0x64,0xa0,0xfb,0x00,0x60,0x13,0x66,0x46,0x42,0x10,0x60,0x00,0x7c, -0x3c,0x46,0x29,0xf2,0x22,0x46,0xa0,0x84,0xb4,0xbc,0x29,0xfa,0x59,0x60,0x68,0x61, -0xa1,0xd1,0x53,0xf3,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x06,0x64,0x44,0x40,0x45, -0x3c,0x46,0x2b,0xf2,0x2c,0xf0,0x60,0x43,0x2d,0xf2,0x22,0x46,0x2b,0xfc,0x2c,0xf8, -0x2d,0xfa,0x3c,0x46,0x2e,0xf2,0x2f,0xf0,0x60,0x43,0x30,0xf2,0x22,0x46,0x2e,0xfc, -0x2f,0xf8,0x30,0xfa,0x3c,0x46,0x29,0xf2,0xff,0xff,0xff,0xff,0x04,0x2b,0x13,0x00, -0x21,0xf2,0x53,0xf1,0xff,0xff,0x64,0x40,0x02,0x36,0xe0,0x84,0x55,0xf3,0x60,0x41, -0x60,0x45,0x23,0x60,0x58,0x4f,0x58,0x78,0xff,0xff,0xae,0x81,0xff,0xff,0x01,0x03, -0xdc,0x84,0x40,0x44,0x12,0x00,0x1f,0xf2,0x53,0xf1,0xff,0xff,0x64,0x40,0x02,0x36, -0xe0,0x84,0x55,0xf3,0x60,0x41,0x60,0x45,0x23,0x60,0x58,0x4f,0x58,0x78,0xff,0xff, -0xae,0x81,0xff,0xff,0x01,0x03,0xdc,0x84,0x40,0x44,0x00,0x64,0x40,0x43,0x25,0x44, -0x00,0x3a,0x0b,0x00,0x2b,0x5c,0x08,0x26,0x04,0x00,0x2d,0xf1,0x25,0xf1,0x64,0x43, -0x2b,0x00,0x31,0xf1,0x29,0xf1,0x64,0x43,0x24,0x00,0x01,0x3a,0x0b,0x00,0x2b,0x5c, -0x08,0x26,0x04,0x00,0x2e,0xf1,0x26,0xf1,0x64,0x43,0x1e,0x00,0x32,0xf1,0x2a,0xf1, -0x64,0x43,0x17,0x00,0x02,0x3a,0x0b,0x00,0x2b,0x5c,0x08,0x26,0x04,0x00,0x2f,0xf1, -0x27,0xf1,0x64,0x43,0x11,0x00,0x33,0xf1,0x2b,0xf1,0x64,0x43,0x0a,0x00,0x2b,0x5c, -0x08,0x26,0x04,0x00,0x30,0xf1,0x28,0xf1,0x64,0x43,0x06,0x00,0x34,0xf1,0x2c,0xf1, -0x64,0x43,0xa0,0xa3,0x60,0x65,0x02,0x00,0xc0,0x65,0xd7,0x83,0xb5,0xf3,0xff,0xff, -0xc0,0x84,0xc0,0x84,0xc4,0x84,0x24,0x45,0xc4,0x84,0x22,0x46,0x2a,0xfa,0x63,0x44, -0xb5,0xf1,0xff,0xff,0xd0,0x84,0xff,0xff,0x40,0x44,0xf3,0x60,0x58,0x4f,0xba,0x78, -0xff,0xff,0xbc,0xff,0x27,0x44,0x02,0xbc,0x40,0x47,0x35,0xf3,0xb4,0xff,0x60,0x5b, -0x4d,0xe2,0x13,0x60,0x9b,0x78,0xff,0xff,0x0d,0x64,0xa0,0xfb,0x00,0x64,0x40,0x43, -0x2b,0x44,0x08,0x26,0x0f,0x00,0x25,0x44,0x00,0x36,0x25,0xf1,0x01,0x36,0x26,0xf1, -0x02,0x36,0x27,0xf1,0xfd,0xa0,0xff,0xff,0x15,0x02,0x28,0xf1,0x80,0x60,0x00,0x64, -0x40,0x43,0x10,0x00,0x25,0x44,0x00,0x36,0x29,0xf1,0x01,0x36,0x2a,0xf1,0x02,0x36, -0x2b,0xf1,0xfd,0xa0,0xff,0xff,0x04,0x02,0x2c,0xf1,0x80,0x60,0x00,0x64,0x40,0x43, -0x60,0x65,0x01,0x00,0xc0,0x65,0x00,0x60,0x13,0x66,0x20,0xf3,0x46,0x42,0xd0,0x83, -0xff,0xff,0x02,0x28,0x00,0x63,0x2a,0xfc,0x64,0x44,0xb5,0xf1,0xd4,0x84,0xd0,0x84, -0xff,0xff,0x40,0x44,0xd4,0x64,0x29,0xfa,0x21,0x46,0x2e,0xf2,0x2f,0xf0,0x60,0x43, -0x30,0xf2,0x22,0x46,0x2b,0xfc,0x2c,0xf8,0x2d,0xfa,0xf3,0x60,0x58,0x4f,0xba,0x78, -0xff,0xff,0xbc,0xff,0x5c,0x00,0x0f,0x64,0xa0,0xfb,0x5a,0x60,0xba,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x00,0x64,0x40,0x43,0x00,0x60,0x13,0x66,0x46,0x42,0xc4,0x64,0x29,0xfa, -0x21,0x46,0x2e,0xf2,0x2f,0xf0,0x60,0x43,0x30,0xf2,0x22,0x46,0x2b,0xfc,0x2c,0xf8, -0x2d,0xfa,0x2b,0x44,0x08,0x26,0x0f,0x00,0x25,0x44,0x00,0x36,0x25,0xf1,0x01,0x36, -0x26,0xf1,0x02,0x36,0x27,0xf1,0xfd,0xa0,0xff,0xff,0x15,0x02,0x28,0xf1,0x80,0x60, -0x00,0x64,0x40,0x43,0x10,0x00,0x25,0x44,0x00,0x36,0x29,0xf1,0x01,0x36,0x2a,0xf1, -0x02,0x36,0x2b,0xf1,0xfd,0xa0,0xff,0xff,0x04,0x02,0x2c,0xf1,0x80,0x60,0x00,0x64, -0x40,0x43,0x60,0x65,0x01,0x00,0xc0,0x65,0x20,0xf3,0x22,0x46,0xd0,0x84,0x2a,0xfa, -0x64,0x44,0xb5,0xf1,0xd4,0x84,0xd0,0x84,0xff,0xff,0x40,0x44,0xf3,0x60,0x58,0x4f, -0xba,0x78,0xff,0xff,0xbc,0xff,0x5a,0x60,0x32,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0xb4,0xff, -0xff,0xff,0xff,0xff,0x84,0x60,0x1d,0x7d,0x8e,0x60,0x00,0x6b,0x11,0x60,0x8e,0x78, -0xff,0xff,0x10,0x64,0xa0,0xfb,0xbc,0xff,0x00,0x60,0x13,0x66,0x46,0x42,0xf3,0x60, -0x58,0x4f,0xba,0x78,0xff,0xff,0x11,0x60,0x8e,0x78,0xff,0xff,0xff,0x00,0x00,0xe0, -0x7f,0x00,0x1a,0x0e,0xd8,0xf1,0x01,0x64,0xd0,0x80,0xcf,0xfb,0x1a,0x03,0xd7,0xfb, -0x17,0x60,0xe4,0x65,0xa5,0xd3,0x41,0x4d,0xdc,0x84,0xa5,0xdb,0x26,0x44,0x02,0x26, -0x17,0x00,0x3e,0x45,0x35,0x81,0xff,0xff,0x0f,0x02,0x5b,0x60,0x06,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0xf3,0x60,0x8e,0x78,0xff,0xff,0x41,0x5e,0x02,0x64,0x40,0x46,0xd1,0xfe, -0x21,0x46,0x46,0x45,0x4c,0xe2,0x0e,0x64,0x40,0x4c,0x19,0xff,0x03,0xe1,0x26,0x44, -0x02,0xb4,0x12,0xbc,0x40,0x46,0x2e,0x44,0x20,0xfa,0x17,0x60,0x7a,0x62,0xa2,0xd1, -0xff,0xff,0x64,0x40,0x01,0x2a,0x12,0x00,0x66,0x69,0xff,0xff,0xff,0xff,0x01,0x16, -0xfe,0x00,0x68,0x44,0x00,0x7f,0x60,0x45,0x7c,0x69,0xff,0xff,0xff,0xff,0x01,0x16, -0xfe,0x00,0x68,0x44,0x00,0x7f,0x60,0x47,0xb4,0x84,0x0f,0x00,0x00,0x65,0x7c,0x69, -0xff,0xff,0xff,0xff,0x01,0x16,0xfe,0x00,0x68,0x44,0xdf,0xf1,0x00,0x7f,0xd0,0x80, -0xff,0xff,0x01,0x04,0x64,0x44,0x60,0x47,0xb4,0x84,0x25,0xfa,0x20,0xf2,0xff,0xff, -0xff,0xb4,0x0a,0x36,0x00,0x7f,0x14,0x36,0x01,0x7f,0x37,0x36,0x02,0x7f,0x6e,0x36, -0x03,0x7f,0x26,0xfa,0x00,0x7c,0x22,0xf8,0x35,0xf1,0x01,0x64,0x57,0xfb,0x2e,0x44, -0xa1,0xff,0x6c,0x43,0x21,0xfc,0x7e,0x69,0xc3,0x94,0xcd,0xe2,0x9c,0xfe,0xff,0xff, -0x0e,0x04,0x67,0x60,0x5e,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x01,0x64, -0xcf,0xfb,0x27,0x44,0x80,0xbc,0x40,0x47,0xf3,0x60,0x94,0x78,0xff,0xff,0xdc,0xf1, -0xff,0xff,0x64,0x40,0x00,0x36,0x03,0x00,0x0e,0x60,0x8b,0x78,0xff,0xff,0x00,0x7c, -0xcf,0xf9,0x40,0x45,0x6e,0x36,0x35,0x00,0x37,0x36,0x26,0x00,0x14,0x36,0x1f,0x00, -0x0a,0x36,0x17,0x00,0x5a,0x60,0xfa,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x21,0x63,0xa0,0xfd, -0x27,0x44,0x80,0xbc,0x40,0x47,0x07,0x60,0xd0,0x74,0xcd,0xe2,0xf3,0x60,0x94,0x78, -0xff,0xff,0xa1,0xff,0x4c,0x48,0xeb,0x83,0xeb,0x83,0xeb,0x83,0x20,0x00,0xa1,0xff, -0x4c,0x48,0xeb,0x83,0xeb,0x83,0x1b,0x00,0xa1,0xff,0x4c,0x48,0xe3,0x85,0xc7,0x85, -0xe3,0x83,0xe3,0x83,0xe3,0x83,0xc7,0x83,0xeb,0x83,0xeb,0x83,0xeb,0x83,0xeb,0x83, -0x0e,0x00,0xe3,0x85,0xc7,0x85,0xe3,0x83,0xe3,0x83,0xe3,0x83,0xa1,0xff,0x4c,0x48, -0xc7,0x83,0xeb,0x83,0xeb,0x83,0xeb,0x83,0xff,0xff,0x80,0x27,0xcf,0x83,0x1f,0xfc, -0xfc,0xa3,0x48,0xf3,0x43,0x43,0xa1,0xff,0x4c,0x4e,0x1c,0x7c,0xd0,0x9c,0xd3,0x80, -0x20,0x44,0x0f,0x04,0x5a,0x60,0xfe,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x27,0x44,0x80,0xbc,0x40,0x47,0x07,0x60,0xd0,0x74,0xcd,0xe2,0xf3,0x60,0x94,0x78, -0xff,0xff,0xe8,0x84,0x52,0x4a,0x01,0x05,0x70,0x80,0x52,0x63,0x28,0x44,0xbd,0xda, -0xff,0xff,0xa1,0xff,0x6c,0x45,0x2e,0x44,0x80,0x2b,0x20,0xfb,0xbd,0xda,0x65,0x44, -0xbd,0xf1,0xbd,0xda,0x50,0xfe,0xff,0xff,0x01,0x2a,0x04,0x00,0x26,0x44,0x20,0xbc, -0x40,0x46,0x01,0x00,0xd0,0x80,0xa1,0xff,0x6c,0x44,0xbe,0xf1,0xbd,0xda,0xc4,0x85, -0xd0,0x80,0x00,0x61,0x28,0x44,0x04,0x2a,0x03,0x00,0x40,0x27,0xd1,0x00,0x01,0x61, -0xbf,0xf1,0xff,0xff,0xa1,0xff,0x6c,0x44,0xbd,0xda,0xc4,0x85,0xd0,0x80,0x32,0x44, -0x01,0x2a,0x27,0x00,0x28,0x44,0xd4,0x36,0x02,0x00,0xc4,0x3a,0x06,0x00,0x00,0x64, -0x38,0xfa,0x08,0x64,0xf2,0x60,0xbb,0x78,0x40,0x4c,0xa1,0xff,0x6c,0x44,0xbd,0xda, -0xff,0xff,0xa1,0xff,0x6c,0x44,0xbd,0xda,0x20,0x61,0x28,0x44,0x03,0x2b,0x00,0x61, -0x60,0x40,0x40,0x27,0x02,0xb9,0x41,0x4e,0xa1,0xff,0x6c,0x44,0xbd,0xda,0x28,0x44, -0xb4,0x36,0xe5,0x00,0xa4,0x36,0xe3,0x00,0xe4,0x36,0xe1,0x00,0xf1,0x60,0xb9,0x78, -0xff,0xff,0x61,0x40,0x01,0x22,0x31,0x00,0xa1,0xff,0x6c,0x44,0xbd,0xda,0x28,0x44, -0xd4,0x3a,0x02,0x00,0x48,0x61,0x08,0x00,0xc4,0x36,0x05,0x00,0x28,0x44,0xb4,0x3a, -0x03,0x00,0x4d,0x61,0x01,0x00,0x49,0x61,0x41,0x4d,0x46,0x4e,0x08,0x64,0x40,0x4c, -0x05,0x01,0x00,0x65,0x2d,0x44,0x04,0x2a,0x0a,0x00,0x0d,0x00,0x2d,0x44,0x49,0x36, -0x05,0x00,0x48,0x3a,0x07,0x00,0x10,0x65,0x27,0x40,0x40,0x26,0x30,0x65,0xf2,0x60, -0xbe,0x78,0x35,0x8d,0x30,0x65,0xa1,0xff,0x6c,0x44,0xbd,0xda,0xff,0xff,0xa1,0xff, -0x6c,0x44,0xbd,0xda,0xf2,0x60,0xbb,0x78,0x35,0x8d,0x45,0x4e,0x23,0x44,0xe8,0xa5, -0xff,0xff,0x05,0x05,0x60,0x43,0xfa,0xa3,0xf3,0x60,0xa8,0x78,0xff,0xff,0xa1,0xff, -0x6c,0x44,0xbd,0xda,0xff,0xff,0xa1,0xff,0x6c,0x44,0xbd,0xda,0xff,0xff,0xa1,0xff, -0x6c,0x44,0xbd,0xda,0x26,0x41,0x20,0x26,0x1d,0x00,0x2d,0x44,0x22,0x01,0x32,0x40, -0x02,0x2a,0x03,0x00,0x50,0xbc,0x40,0x4d,0x1e,0x00,0x01,0x64,0xcf,0xfb,0x18,0x60, -0xc8,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x27,0x44,0x06,0x22,0x06,0x00, -0xf9,0xb4,0x40,0x47,0x02,0x64,0x21,0xfb,0xc0,0xfe,0x48,0xe2,0x27,0x44,0x80,0xbc, -0x40,0x47,0x09,0x00,0x2e,0x44,0x03,0xa4,0xef,0xb1,0x08,0x24,0x40,0xb9,0x41,0x46, -0x02,0x00,0x70,0xbc,0x40,0x4d,0xa1,0xff,0x6c,0x44,0xbd,0xda,0x20,0x61,0x28,0x44, -0x03,0x2b,0x00,0x61,0x60,0x40,0x40,0x2b,0x0d,0x00,0xbf,0x60,0xff,0x65,0x43,0xf3, -0x02,0xb9,0x80,0xb0,0x28,0x44,0x06,0x03,0xa4,0x84,0x40,0x48,0x29,0xfa,0x04,0x64, -0x22,0xfa,0x02,0xa9,0x23,0x44,0xe8,0xa4,0x41,0x4e,0x20,0x26,0xfa,0xa4,0x28,0x40, -0x40,0x27,0xf8,0xa4,0x40,0x43,0x38,0xfa,0xff,0xff,0xa1,0xff,0x6c,0x44,0xbd,0xda, -0x23,0x44,0x80,0x2b,0x03,0x00,0x14,0x64,0x40,0x43,0x38,0xfa,0x23,0x47,0x3f,0xfa, -0x08,0x65,0x45,0x4c,0x21,0xf2,0x70,0x45,0xd4,0x80,0xff,0xff,0x02,0x06,0x64,0xe2, -0x60,0x50,0xa1,0xff,0x6c,0x44,0xbd,0xda,0x2e,0x44,0x22,0x26,0x05,0x00,0x23,0x41, -0xa1,0xff,0x6c,0x44,0x34,0xfa,0x54,0x00,0xa1,0xff,0x6c,0x44,0xbd,0xda,0x2e,0x40, -0x20,0x2a,0x12,0x00,0xa1,0xff,0x6c,0x44,0xbd,0xda,0xff,0xff,0xa1,0xff,0x6c,0x44, -0xbd,0xda,0x2e,0x40,0x02,0x26,0x05,0x00,0x23,0x41,0xa1,0xff,0x6c,0x44,0x37,0xfa, -0x3f,0x00,0xa1,0xff,0x6c,0x44,0x37,0xfa,0x32,0x44,0x01,0x2a,0x1a,0x00,0x00,0xf4, -0x02,0x62,0x46,0x45,0xa1,0xff,0xda,0x82,0x6c,0x44,0xa2,0xda,0xff,0xff,0xa1,0xff, -0xda,0x82,0x6c,0x44,0xa2,0xda,0x23,0x41,0x04,0xa1,0x78,0x7c,0x01,0x65,0x61,0x43, -0xd1,0x80,0x46,0x45,0x02,0x07,0x04,0xa1,0x37,0x00,0x64,0x43,0xd1,0x81,0x7c,0x7c, -0x3b,0x00,0xcf,0xf3,0x48,0xf1,0x00,0xa0,0x23,0x44,0x04,0x02,0x00,0xa0,0xd0,0x80, -0x01,0x03,0x05,0x04,0x60,0x43,0x0c,0xa3,0xf3,0x60,0xa8,0x78,0xff,0xff,0xa1,0xff, -0x6c,0x44,0xff,0xff,0x1a,0xfa,0xff,0xff,0xa1,0xff,0x6c,0x44,0xff,0xff,0x1b,0xfa, -0xb0,0xff,0x01,0x5d,0xdc,0xfe,0x05,0xff,0x3e,0xf3,0x23,0x41,0x04,0xbc,0x3e,0xfb, -0x7c,0x7c,0x01,0x65,0x25,0x44,0xd5,0x80,0x61,0x43,0x45,0x04,0x35,0x03,0xdc,0xf3, -0xff,0xff,0xff,0xff,0x00,0x36,0x03,0x00,0x0e,0x60,0x8b,0x78,0xff,0xff,0x00,0xf4, -0x02,0x62,0xd1,0x80,0x46,0x45,0x06,0x07,0x61,0x40,0x01,0x26,0x01,0xa1,0x61,0x5c, -0x00,0x61,0x02,0x00,0x64,0x43,0xd1,0x81,0xa1,0xff,0xec,0x44,0x5a,0xda,0xfc,0x1d, -0xe2,0x1e,0x23,0x00,0xa1,0xff,0xd5,0x80,0x61,0x43,0x37,0x04,0x16,0x03,0x00,0xf4, -0x02,0x62,0xd1,0x80,0x46,0x45,0x07,0x07,0xec,0x44,0x61,0x40,0x01,0x26,0x01,0xa1, -0x61,0x5c,0x00,0x61,0x05,0x00,0x64,0x43,0xec,0x44,0xd1,0x81,0x01,0x00,0xec,0x44, -0x7a,0xda,0xfd,0x1d,0xe8,0x1e,0x0a,0x00,0xa1,0xff,0xb6,0xff,0x6c,0x44,0x00,0xf4, -0x02,0xfa,0x02,0x7c,0x46,0x45,0xb7,0xff,0x06,0x00,0xa1,0xff,0xb6,0xff,0x00,0x64, -0x6c,0x44,0x5a,0xda,0xb7,0xff,0x64,0x41,0x28,0x44,0x40,0x2b,0x1d,0x00,0xb1,0xff, -0x32,0x44,0x01,0x26,0x19,0x00,0xa1,0xff,0x6c,0x44,0xff,0xff,0x3c,0xfb,0xff,0xff, -0xa1,0xff,0x6c,0x44,0xff,0xff,0x3d,0xfb,0x0f,0x00,0x6c,0x44,0x64,0x41,0x28,0x40, -0x40,0x2b,0x0d,0x00,0xb1,0xff,0x32,0x40,0x01,0x26,0x09,0x00,0x3c,0xfb,0xff,0xff, -0xa1,0xff,0x6c,0x44,0xff,0xff,0x3d,0xfb,0x21,0x46,0xa1,0xff,0x6c,0x40,0x21,0x46, -0x6a,0x43,0xa1,0xff,0x6c,0x40,0x24,0xf1,0xff,0xff,0x64,0x54,0xcd,0xe2,0x19,0xff, -0x01,0x16,0xfe,0x00,0x68,0x44,0x60,0x40,0x10,0x2a,0x04,0x00,0x22,0xf2,0xff,0xff, -0x08,0xbc,0x22,0xfa,0x32,0x44,0x03,0x22,0x20,0x00,0x47,0xff,0x26,0x44,0xfd,0xb4, -0x84,0xbc,0x63,0x40,0x40,0x27,0x08,0x00,0x0d,0x63,0x07,0x15,0x06,0x15,0x05,0x15, -0x04,0x15,0xff,0xa3,0x02,0x15,0xf9,0x02,0x7f,0xb4,0x40,0x46,0x6c,0x40,0x28,0x44, -0x40,0x2b,0x08,0x00,0x32,0x44,0x01,0x2a,0x05,0x00,0x23,0x44,0x08,0xa4,0x38,0xfa, -0x60,0x47,0x3f,0xfa,0xf3,0x60,0x74,0x78,0xff,0xff,0x63,0x40,0x40,0x2b,0x05,0x00, -0xd2,0xf3,0xff,0xff,0x01,0xa4,0xd2,0xfb,0x08,0x00,0x0d,0x64,0x4b,0x15,0x4a,0x15, -0x49,0x15,0x48,0x15,0xff,0xa4,0x46,0x15,0xf9,0x02,0x48,0xe2,0xcf,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x73,0x02,0x27,0x44,0x06,0x22,0x05,0x00,0xf9,0xb4,0x40,0x47, -0x02,0x64,0x21,0xfb,0xc0,0xfe,0x20,0xf2,0xff,0xff,0xff,0xb4,0x0a,0x36,0x00,0x7f, -0x14,0x36,0x01,0x7f,0x37,0x36,0x02,0x7f,0x6e,0x36,0x03,0x7f,0x26,0xfa,0x5a,0x60, -0xd2,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84, -0xe0,0x84,0x60,0x45,0x5a,0x60,0xd6,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x28,0x40, -0x04,0x26,0x3c,0x00,0x28,0x40,0x40,0x2b,0x39,0x00,0x26,0x44,0x04,0xbc,0xfd,0xb4, -0x40,0x46,0x34,0x00,0x6c,0x40,0x2d,0x44,0x20,0x2a,0x18,0x00,0xb5,0xf3,0xff,0xff, -0xf7,0xa4,0x60,0x54,0xcd,0xe2,0x5d,0x2a,0x05,0x00,0x70,0x44,0x00,0xbc,0xff,0xff, -0x0d,0x02,0x05,0x00,0x59,0x2a,0x03,0x00,0x27,0x40,0x02,0x2a,0x07,0x00,0x47,0xff, -0xb5,0xff,0x00,0x64,0xd7,0xfb,0x13,0x60,0xbb,0x78,0xff,0xff,0xcf,0xf3,0xff,0xff, -0x00,0xa0,0x26,0x44,0x03,0x03,0x84,0xbc,0x40,0x46,0x10,0x00,0x84,0xbc,0x2d,0x40, -0x0c,0x22,0x02,0x00,0x40,0x46,0x0a,0x00,0xfd,0xb4,0x40,0x46,0x25,0x44,0x06,0xfa, -0x60,0x46,0x01,0xf2,0xff,0xff,0x61,0x5e,0x03,0x2b,0x01,0xfa,0x21,0x46,0x08,0x29, -0x09,0x00,0x22,0xf1,0xff,0xff,0x64,0x40,0x07,0x2e,0x04,0x00,0x43,0xff,0x10,0x64, -0x21,0xfb,0xc0,0xfe,0x00,0x64,0xd7,0xfb,0x47,0xff,0x12,0x60,0xe4,0x78,0xff,0xff, -0xa1,0xff,0x6c,0x43,0x63,0x54,0xcd,0xe2,0x0e,0x64,0x01,0x00,0x0c,0x64,0x40,0x4c, -0x19,0xff,0x00,0x64,0x40,0x4a,0xd7,0xfb,0x08,0x64,0x40,0x4c,0x27,0x44,0x06,0x22, -0x06,0x00,0xf9,0xb4,0x40,0x47,0x02,0x64,0x21,0xfb,0xc0,0xfe,0x48,0xe2,0x82,0xe1, -0xa1,0xff,0xd4,0x00,0x00,0x60,0x18,0x63,0xa1,0xff,0xec,0x44,0xff,0xff,0xfc,0x1d, -0x04,0x1e,0xb6,0xff,0xa1,0xff,0x6c,0x44,0xb7,0xff,0x08,0x64,0x40,0x4c,0x19,0xff, -0x27,0x44,0x80,0xbc,0x40,0x47,0xc2,0x00,0x01,0x64,0xd0,0xfb,0x24,0x44,0x60,0x48, -0x90,0x6a,0x60,0x47,0x23,0x41,0xe1,0x81,0xff,0xff,0x01,0x16,0xfe,0x00,0x60,0x48, -0x8e,0x6a,0x00,0x64,0x02,0x24,0x80,0x64,0x69,0x83,0xde,0xf1,0x25,0x45,0x02,0x2a, -0x03,0x00,0x64,0x40,0x01,0x2a,0x04,0xbc,0x01,0x16,0xfe,0x00,0x60,0x48,0x8c,0x6a, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x01,0x16,0xfe,0x00,0x02,0xe1,0x08,0x64, -0x40,0x4c,0x29,0x44,0x01,0xbc,0x40,0x49,0x19,0xff,0x52,0x63,0x22,0x46,0xbd,0xd0, -0x22,0xf3,0x43,0xff,0x60,0x40,0x07,0x22,0x03,0x00,0x10,0x64,0x21,0xfb,0xc0,0xfe, -0x01,0xe1,0x28,0xf2,0x44,0x48,0x60,0x40,0x01,0x2a,0x03,0x00,0x40,0x67,0xb0,0x84, -0x60,0x5c,0x99,0xff,0x07,0x60,0x00,0xe8,0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xe8,0xff,0xff,0xff,0xff,0xff,0xff,0x64,0x4d, -0x64,0x47,0x60,0x4d,0xff,0xff,0xff,0xff,0xa1,0xff,0xb5,0xff,0xbb,0xff,0x32,0x64, -0xa0,0xfb,0xff,0xff,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4d,0x60,0x47,0x60,0x4d, -0x26,0x44,0x02,0xb4,0x40,0x46,0x20,0x61,0x28,0x44,0x80,0x36,0x04,0x00,0x50,0x3a, -0x03,0x00,0x00,0x65,0xb5,0x81,0x04,0xb9,0x41,0x4e,0xa1,0xff,0xbd,0xd2,0xff,0xff, -0x60,0x4d,0x60,0x47,0x60,0x4d,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4d,0x60,0x47, -0x60,0x4d,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c,0x28,0x44,0xc4,0x36,0x13,0x00, -0xd4,0x36,0x11,0x00,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c,0xa1,0xff,0xbd,0xd2, -0xff,0xff,0x60,0x4c,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c,0x28,0x44,0xb4,0x36, -0x02,0x00,0xa4,0x3a,0x03,0x00,0xf5,0x60,0x03,0x78,0xff,0xff,0xa1,0xff,0xbd,0xd2, -0xff,0xff,0x60,0x4c,0xff,0x65,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c,0x2e,0x41, -0x28,0x44,0x03,0x2b,0xdf,0xb1,0x60,0x40,0x40,0x27,0x02,0xb9,0xa1,0xff,0xbd,0xd2, -0xff,0xff,0x60,0x4c,0x23,0x44,0xcc,0x84,0xdc,0x84,0x03,0x03,0x03,0x02,0x08,0xb9, -0x01,0x00,0x10,0xb9,0xbd,0xd0,0x41,0x4e,0xa1,0xff,0xff,0xff,0x64,0x4c,0x2e,0x44, -0x22,0x22,0x30,0x00,0x20,0x2a,0x0f,0x00,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c, -0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c,0xa1,0xff,0xbd,0xd2,0xff,0xff,0x60,0x4c, -0x2e,0x44,0x02,0x2a,0x1f,0x00,0xa1,0xff,0xff,0xff,0x38,0xf3,0x39,0xf3,0x60,0x4c, -0x60,0x43,0x03,0xf0,0x04,0xf4,0x01,0xf2,0x64,0x42,0x04,0xa4,0xd0,0x81,0xa1,0xff, -0x63,0x4c,0x23,0x43,0x2e,0x44,0x10,0x2a,0x06,0x00,0xa2,0xd2,0xff,0xff,0xa1,0xff, -0xff,0xff,0x60,0x4f,0x63,0x00,0xe2,0xd2,0xff,0xff,0xa1,0xff,0xda,0x82,0xc9,0x81, -0x60,0x4e,0x51,0x00,0x18,0x22,0x0a,0x00,0x10,0x26,0x03,0x00,0xf5,0x60,0x03,0x78, -0xff,0xff,0x03,0xf0,0x04,0xf4,0x00,0x61,0x64,0x42,0x4b,0x00,0x04,0x2a,0x32,0x00, -0x00,0xf4,0x01,0xf2,0xff,0x65,0xa4,0x81,0xa1,0xff,0x02,0xfe,0xff,0xff,0x10,0x25, -0x42,0xfe,0x72,0x45,0x28,0x40,0x50,0x3a,0x00,0x00,0x65,0x4c,0x23,0x43,0xa1,0xf3, -0x04,0x04,0xdc,0x84,0xa1,0xfb,0x60,0x55,0x65,0x52,0xa1,0xff,0xff,0xff,0x60,0x4c, -0xa2,0xf3,0x03,0x04,0xdc,0x84,0xa2,0xfb,0xff,0xff,0xa1,0xff,0xff,0xff,0x60,0x4c, -0xa3,0xf3,0x03,0x04,0xdc,0x84,0xa3,0xfb,0xff,0xff,0xa1,0xff,0x0c,0x62,0x60,0x4c, -0xf8,0xa3,0x2e,0x44,0xfb,0xb4,0x40,0x4e,0x65,0x44,0xdc,0x80,0xff,0xff,0x01,0x02, -0x58,0x80,0x0c,0x00,0x23,0x43,0x03,0xf0,0x04,0xf4,0x01,0xf2,0x64,0x42,0x04,0xa4, -0xd0,0x81,0x04,0x00,0x00,0xf4,0x01,0xf2,0x04,0x62,0xa4,0x81,0xa1,0xff,0xe2,0xd2, -0xda,0x82,0xc9,0x81,0x60,0x4c,0xfa,0x1c,0xf5,0x1d,0x08,0x1e,0x02,0x02,0x00,0xf4, -0x04,0x62,0xa2,0xd2,0xff,0xff,0xa1,0xff,0xff,0xff,0x60,0x4d,0x28,0x44,0x40,0x2b, -0x04,0x00,0xa1,0xff,0x60,0x4e,0xa1,0xff,0x60,0x4c,0xa1,0xff,0xc3,0x60,0x33,0x64, -0x60,0x4e,0xa1,0xff,0xff,0xff,0x62,0x5c,0x02,0xe1,0x08,0x64,0x40,0x4c,0x19,0xff, -0x61,0x40,0x7f,0x26,0x02,0x00,0x00,0xf4,0x04,0x7c,0x66,0x44,0x22,0x46,0x0b,0xf8, -0x0c,0xfa,0x34,0x64,0xa0,0xfb,0x6a,0x40,0x40,0x26,0x02,0x00,0xfc,0x0b,0x02,0x00, -0x07,0x60,0x80,0xe8,0x24,0xf3,0xff,0xff,0x60,0x54,0xcd,0xe2,0x03,0x64,0xcc,0x84, -0xff,0xff,0xfd,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0x99,0xff,0x3e,0x44,0x7d,0xb4,0x08,0xbc,0x40,0x5e,0x98,0xff,0x05,0x64, -0xcc,0x84,0xff,0xff,0xfd,0x02,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0x99,0xff,0x3d,0x44,0xf7,0xb4,0x40,0x5d,0x98,0xff,0x00,0x60, -0x00,0x6b,0x99,0xff,0x3d,0x44,0x10,0xbc,0x40,0x5d,0x3e,0x44,0xfe,0xb4,0x40,0x5e, -0x98,0xff,0xbc,0xff,0x28,0x44,0x40,0x2b,0x3e,0x00,0x99,0xff,0x3a,0x44,0x98,0xff, -0x10,0x2b,0xfb,0x00,0x99,0xff,0x00,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff, -0x3a,0x5c,0x80,0x2b,0x12,0x00,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b, -0x09,0x00,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b,0x03,0x00,0x8b,0xff, -0x74,0x40,0x88,0xff,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b,0xff,0xff, -0x31,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xea,0x3a,0x5c,0x80,0x27, -0x06,0x00,0x31,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xea,0x00,0x64, -0xdb,0xfb,0x67,0x60,0xcc,0x64,0x3a,0x5c,0xa0,0xd9,0xff,0xff,0x30,0x60,0x00,0xea, -0xff,0xff,0xff,0xff,0x98,0xff,0xff,0xff,0xb7,0xff,0xb4,0xff,0xff,0xff,0xff,0xff, -0x84,0x60,0x1d,0x7d,0xb5,0xff,0xff,0xff,0x99,0xff,0x07,0x60,0x80,0xe9,0x98,0xff, -0xff,0xff,0xff,0xff,0x80,0xe9,0xff,0xff,0xff,0xff,0xb7,0xff,0xb4,0xff,0xff,0xff, -0x99,0xff,0x3e,0x44,0x02,0xbc,0x00,0x7f,0x40,0x5e,0x98,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0x46,0xff,0x47,0xff,0x2f,0x58,0xff,0xff,0x01,0x64,0x3f,0xfb, -0xff,0xff,0x00,0xea,0x99,0xff,0x3b,0x44,0x40,0x27,0xfd,0x00,0x98,0xff,0x00,0xeb, -0x40,0xf3,0xff,0xff,0x60,0x40,0x01,0x2a,0x03,0x00,0x18,0x60,0x17,0x78,0xff,0xff, -0x1b,0xf2,0x41,0xf1,0x60,0x40,0xc0,0x27,0x07,0x00,0x64,0x40,0x01,0x2a,0x16,0x00, -0x67,0x60,0x8e,0x63,0x00,0x65,0x77,0x00,0xc0,0x2b,0x07,0x00,0x64,0x40,0x08,0x2a, -0x0d,0x00,0x67,0x60,0xb8,0x63,0x30,0x65,0x6e,0x00,0x40,0x2b,0x0c,0x00,0x64,0x40, -0x02,0x2a,0x04,0x00,0x67,0x60,0x9c,0x63,0x10,0x65,0x65,0x00,0x20,0x60,0x00,0xea, -0xf6,0x60,0xeb,0x78,0xff,0xff,0x64,0x40,0x04,0x2a,0xf8,0x00,0x67,0x60,0xaa,0x63, -0x95,0xf3,0xd6,0xf3,0x00,0xa0,0x00,0xa0,0x55,0x03,0x54,0x03,0x19,0x60,0x2a,0x65, -0x30,0xf2,0x2f,0xf0,0x60,0x41,0x64,0x43,0xeb,0x83,0x00,0x7f,0xe0,0x84,0x44,0xd1, -0x61,0x47,0x93,0x83,0x00,0x7f,0xe0,0x84,0x44,0xd1,0xeb,0x83,0x93,0x83,0x0f,0x60, -0xf0,0x65,0xa7,0x85,0x44,0x60,0x4e,0x63,0xc7,0x83,0x02,0x65,0xbd,0xd3,0xff,0xff, -0x60,0x40,0x80,0x2b,0x0e,0x00,0x5c,0x61,0xa1,0xd0,0xbd,0xd3,0x50,0xfe,0x59,0xd0, -0xd0,0x80,0xbd,0xd3,0x59,0xd0,0xd0,0x80,0xbd,0xd3,0xff,0xff,0xd0,0x80,0xff,0xff, -0x1f,0x01,0x65,0x44,0xff,0xa5,0xff,0xff,0xe9,0x02,0x54,0x60,0x4e,0x63,0x7e,0x65, -0xbd,0xd3,0xff,0xff,0x60,0x40,0x80,0x2b,0x0e,0x00,0x5c,0x61,0xa1,0xd0,0xbd,0xd3, -0x50,0xfe,0x59,0xd0,0xd0,0x80,0xbd,0xd3,0x59,0xd0,0xd0,0x80,0xbd,0xd3,0xff,0xff, -0xd0,0x80,0xff,0xff,0x05,0x01,0x65,0x44,0xff,0xa5,0xff,0xff,0xe9,0x02,0x0a,0x00, -0xf8,0xa3,0xa3,0xd3,0xff,0xff,0xe0,0x84,0xe8,0x85,0x3d,0x60,0x4c,0x64,0xc4,0x83, -0x67,0x44,0xd9,0xfb,0x20,0x65,0x22,0xf2,0xff,0xff,0xb4,0x84,0x22,0xfa,0x1a,0xf0, -0x99,0xff,0x64,0x44,0xe0,0x7f,0x40,0x5b,0x64,0x47,0xe1,0x7f,0x40,0x5b,0x1b,0xf0, -0xff,0xff,0x64,0x44,0xe2,0x7f,0x40,0x5b,0x60,0x47,0x60,0x41,0xd9,0xf3,0xd9,0xf9, -0x45,0xf1,0x90,0x84,0x00,0x37,0x13,0x00,0x63,0x42,0x02,0x63,0x64,0x40,0x07,0x3a, -0x0a,0x63,0x5a,0xd3,0xdd,0x81,0x60,0x45,0x61,0x5f,0x40,0x5b,0x65,0x47,0xdd,0x81, -0x61,0x5f,0x40,0x5b,0xf6,0x1f,0x5a,0xd3,0xdd,0x81,0x61,0x5f,0x40,0x5b,0x98,0xff, -0xa0,0x60,0x00,0xeb,0xc0,0x60,0x00,0xeb,0x64,0x40,0x07,0x3a,0x03,0x00,0x80,0x60, -0x07,0xeb,0x02,0x00,0x80,0x60,0x0f,0xeb,0x33,0x60,0x00,0xeb,0x00,0x64,0x3f,0xfb, -0x38,0xf2,0x00,0xf4,0xff,0xff,0x28,0x87,0x04,0x64,0x40,0x49,0x46,0x4a,0xb3,0xff, -0x02,0x64,0x9c,0xfb,0x99,0xff,0x30,0x44,0x02,0xbc,0x40,0x51,0x98,0xff,0xf8,0x60, -0x89,0x78,0xff,0xff,0x40,0xf3,0x2a,0x46,0x60,0x40,0x01,0x26,0x65,0x00,0x29,0x43, -0x27,0x44,0x00,0xa8,0x60,0x41,0xa3,0xd2,0x1b,0x03,0x99,0xff,0x3b,0x40,0x80,0x2b, -0xfd,0x00,0x98,0xff,0x60,0x57,0xff,0xff,0x77,0x5f,0xc9,0x81,0x60,0x57,0xff,0xff, -0x77,0x5f,0xbd,0xda,0x01,0x0f,0x25,0x00,0x0b,0x03,0xa3,0xd2,0x7f,0x26,0xf2,0x00, -0x00,0xf2,0x04,0x63,0x00,0xa8,0x40,0x4a,0x60,0x46,0x3b,0x03,0xa3,0xd2,0xea,0x00, -0x3d,0x46,0x38,0xf2,0x2a,0x46,0x60,0x40,0x01,0x2a,0x1f,0x00,0x63,0x40,0x7f,0x26, -0x05,0x00,0x00,0xf2,0x04,0x63,0x00,0xa8,0x60,0x46,0x2b,0x03,0x46,0x4a,0x01,0x0f, -0x11,0x00,0xa3,0xd2,0xff,0xff,0x60,0x57,0xff,0xff,0x77,0x5f,0x60,0x47,0xa3,0xda, -0x0c,0x00,0xe6,0x03,0x63,0x40,0x7f,0x26,0x05,0x00,0x00,0xf2,0x04,0x63,0x00,0xa8, -0x40,0x4a,0x17,0x03,0x43,0x49,0x41,0x47,0x11,0x00,0x00,0x64,0x9c,0xfb,0x99,0xff, -0x30,0x44,0xfd,0xb4,0x40,0x51,0x98,0xff,0x3e,0xf3,0x00,0x7c,0x02,0xbc,0x3e,0xfb, -0x3d,0x46,0x0f,0xf2,0x44,0x47,0x60,0x40,0x04,0x26,0x0b,0x00,0xf8,0x60,0x89,0x78, -0xff,0xff,0x3d,0x46,0x0f,0xf0,0xff,0x60,0xf7,0x65,0x64,0x43,0x17,0x60,0xe5,0x78, -0xff,0xff,0x17,0x60,0xa6,0x78,0xff,0xff,0x18,0x60,0x17,0x78,0xff,0xff,0x4c,0x2f, -0x7e,0x00,0x18,0x09,0x3d,0x46,0x0f,0xf0,0x3c,0xf3,0x64,0x43,0x60,0x45,0x1b,0xf2, -0x41,0xf1,0x60,0x40,0xc0,0x23,0x01,0x64,0xc0,0x2b,0x01,0x00,0x08,0x64,0x80,0x2b, -0x01,0x00,0x04,0x64,0x40,0x2b,0x01,0x00,0x02,0x64,0xa0,0x84,0x0f,0x22,0x2d,0x00, -0x65,0x44,0x63,0x5c,0x80,0x2a,0x29,0x00,0x99,0xff,0x3b,0x40,0x80,0x2b,0xfd,0x00, -0x98,0xff,0x60,0x57,0xff,0xff,0x77,0x5f,0x60,0x57,0xff,0xff,0x77,0x5f,0x99,0xff, -0x3b,0x40,0x80,0x2b,0xfd,0x00,0x98,0xff,0x3d,0xf3,0xff,0xff,0x60,0x57,0xff,0xff, -0x77,0x5f,0x60,0x57,0xff,0xff,0x77,0x5f,0xff,0xff,0xff,0x60,0xf7,0x65,0x0b,0x14, -0x0a,0x14,0x09,0x14,0x08,0x14,0x07,0x14,0x06,0x14,0x05,0x14,0x04,0x14,0x03,0x14, -0x02,0x14,0xa7,0x83,0x01,0x00,0x08,0xbb,0x0f,0xfc,0x0f,0xf0,0x80,0x60,0x00,0x63, -0xb3,0x9c,0x0f,0xf8,0x00,0x64,0x9c,0xfb,0x99,0xff,0x30,0x44,0xfd,0xb4,0x40,0x51, -0x98,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x60,0x00,0xea,0x00,0xeb, -0xa0,0x60,0x00,0xeb,0x30,0x60,0x00,0xeb,0x3e,0xf3,0xff,0xff,0xf9,0xb4,0x3e,0xfb, -0xf8,0x60,0xd7,0x78,0xff,0xff,0x00,0x64,0x9c,0xfb,0x99,0xff,0x30,0x44,0xfd,0xb4, -0x40,0x51,0x98,0xff,0x00,0xeb,0xa0,0x60,0x00,0xeb,0x30,0x60,0x00,0xeb,0x20,0x60, -0x00,0xea,0x00,0x64,0x3e,0xf3,0xff,0xff,0xf9,0xb4,0x3e,0xfb,0x40,0xfb,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0x99,0xff,0x3a,0x44,0x3b,0x44,0x98,0xff,0x3d,0x46, -0x0f,0xf0,0x80,0x60,0x00,0x63,0xb3,0x83,0xff,0x60,0x7f,0x7c,0xa3,0x83,0x0f,0xfc, -0xf8,0x60,0xd7,0x78,0xff,0xff,0xa9,0xff,0x77,0x44,0x60,0x57,0x40,0x4a,0x01,0x2a, -0x31,0x00,0x24,0x44,0x00,0xa8,0x24,0x46,0x09,0xf2,0x2c,0x03,0x00,0xa8,0x40,0x44, -0x13,0x03,0x60,0x46,0x60,0x5c,0x08,0x60,0x20,0x64,0xa0,0xd9,0x64,0x44,0x3a,0x44, -0x01,0x26,0x02,0x00,0x01,0x75,0x03,0x00,0x3b,0x44,0x01,0xbc,0x40,0x5b,0x0e,0xf2, -0xff,0xff,0x01,0xbc,0x0e,0xfa,0x0a,0xf4,0x08,0xf2,0x2d,0x45,0xd4,0x80,0x0e,0xf2, -0x02,0x03,0xd2,0xfe,0x0f,0x00,0x02,0xbc,0x0e,0xfa,0xd0,0xfe,0x5a,0x60,0x70,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x2a,0x44,0x08,0x2a,0x1c,0x00,0x23,0x44,0x00,0xa8,0xff,0xff, -0x18,0x03,0x3c,0x60,0x40,0x64,0x40,0x47,0x58,0x4f,0x53,0x00,0x46,0x43,0x11,0x02, -0x0e,0xf2,0x66,0x43,0x60,0x5c,0x08,0x60,0x22,0x64,0xa0,0xdd,0x64,0x44,0x01,0xbc, -0x0e,0xfa,0x3a,0x44,0x01,0x26,0x02,0x00,0x08,0x75,0x03,0x00,0x3b,0x44,0x08,0xbc, -0x40,0x5b,0x2a,0x44,0x06,0x22,0x4b,0x00,0x22,0x44,0x00,0xa8,0x60,0x46,0x0e,0xf2, -0x46,0x03,0x01,0xb0,0x02,0xbc,0x03,0x02,0x00,0x64,0x40,0x42,0x40,0x00,0x0e,0xfa, -0xd0,0xfe,0x3c,0x60,0x46,0x64,0x40,0x47,0x58,0x4f,0x2b,0x00,0x46,0x42,0x37,0x02, -0x22,0xf2,0x66,0x43,0x00,0xa8,0x0e,0xf2,0x12,0x02,0x01,0xbc,0x40,0x2a,0xe9,0x00, -0xf7,0xb4,0x0e,0xfa,0xff,0xff,0x08,0x60,0x24,0x64,0xa0,0xdd,0x3a,0x44,0x01,0x26, -0x02,0x00,0x02,0x75,0x24,0x00,0x3b,0x44,0x02,0xbc,0x40,0x5b,0x20,0x00,0x01,0xbc, -0x80,0x2a,0xd7,0x00,0xf7,0xb4,0x0e,0xfa,0xff,0xff,0x08,0x60,0x24,0x64,0xa0,0xdd, -0x3a,0x44,0x01,0x26,0x02,0x00,0x04,0x75,0x12,0x00,0x3b,0x44,0x04,0xbc,0x40,0x5b, -0x0e,0x00,0x27,0x42,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x0e,0xf2,0x04,0x03, -0x05,0xb0,0x09,0xf2,0xf9,0x02,0x01,0x00,0x08,0xfe,0x2f,0x58,0xff,0xff,0x2a,0x44, -0x80,0x2a,0x1f,0x00,0x21,0x44,0x00,0xa8,0x60,0x46,0x0e,0xf2,0x1a,0x03,0x02,0xbc, -0x0e,0xfa,0xd0,0xfe,0x3c,0x60,0x70,0x64,0x40,0x47,0x58,0x4f,0xe2,0x00,0x46,0x41, -0x10,0x02,0x0e,0xf2,0x66,0x43,0x01,0xbc,0x0e,0xfa,0xff,0xff,0x08,0x60,0x10,0x64, -0xa0,0xdd,0x3a,0x44,0x01,0x26,0x02,0x00,0x80,0x75,0x03,0x00,0x3b,0x44,0x80,0xbc, -0x40,0x5b,0x34,0x40,0xff,0x26,0x3b,0xff,0x2a,0x44,0x0c,0xf7,0xff,0xff,0xff,0xff, -0x3a,0x44,0x02,0x2a,0x09,0x00,0x3b,0x44,0x00,0xa0,0xff,0xff,0x01,0x03,0x60,0x55, -0x00,0x64,0x40,0x5a,0x40,0x5b,0x3d,0x00,0x00,0x64,0x40,0x4a,0x35,0x40,0x01,0x2a, -0x19,0x00,0x24,0x41,0x00,0xb9,0x40,0x55,0x2c,0x02,0x0d,0x47,0x58,0x4f,0xb1,0x00, -0x28,0x02,0x0e,0xf2,0x46,0x44,0x01,0xbc,0x0e,0xfa,0x66,0x5c,0x08,0x60,0x20,0x64, -0xa0,0xd9,0x3a,0x44,0x01,0x26,0x02,0x00,0x01,0x75,0x03,0x00,0x3b,0x44,0x01,0xbc, -0x40,0x5b,0x17,0x00,0x35,0x40,0x04,0x2a,0x07,0x00,0x23,0x41,0x00,0xb9,0x40,0x55, -0x10,0x02,0x18,0x60,0x7d,0x78,0xff,0xff,0x35,0x40,0x02,0x2a,0x07,0x00,0x22,0x41, -0x00,0xb9,0x40,0x55,0x06,0x02,0x18,0x60,0xa5,0x78,0xff,0xff,0x35,0x40,0x08,0x26, -0x03,0x00,0x34,0x40,0x08,0x2a,0x05,0x00,0x21,0x41,0x00,0xb9,0x40,0x55,0x40,0x54, -0x99,0x03,0x00,0x00,0xa1,0xff,0xff,0xff,0xba,0x3f,0x19,0x60,0x68,0x61,0x27,0x42, -0xa2,0xd3,0x0e,0x4c,0x41,0x4e,0x40,0x45,0x60,0x46,0x00,0xa8,0x09,0xf2,0x06,0x03, -0x40,0x4b,0x1a,0x60,0x5e,0x78,0xff,0xff,0x2b,0x44,0xf5,0x00,0x0c,0x4e,0x2e,0x58, -0xff,0xff,0x25,0x46,0x08,0xf0,0x27,0x43,0xa4,0xd5,0xbd,0xd3,0x46,0x45,0x63,0x45, -0x64,0x43,0x60,0x41,0x00,0xa8,0x00,0x64,0xa3,0xdb,0xbe,0xdb,0x04,0x02,0x65,0x43, -0x25,0x44,0xbf,0xdb,0x05,0x00,0x61,0x44,0x0a,0xfa,0x61,0x46,0x25,0x44,0x09,0xfa, -0x25,0x44,0x27,0x43,0x08,0xfe,0x05,0x03,0x60,0x46,0x09,0xf2,0x08,0xfc,0x00,0xa8, -0xfa,0x00,0x66,0x44,0xa5,0xdb,0x2e,0x58,0xff,0xff,0x28,0x41,0x58,0x4f,0x0e,0x00, -0x2e,0x58,0xff,0xff,0x28,0x41,0x40,0xa1,0x58,0x4f,0x08,0x00,0x05,0x03,0x28,0x41, -0x58,0x4f,0x26,0x00,0x58,0x4f,0x56,0x00,0x2e,0x58,0xff,0xff,0x9e,0xf3,0x7c,0x63, -0x00,0xbe,0x40,0x45,0x1b,0x03,0x00,0x65,0x65,0x44,0xdc,0x85,0x84,0xa1,0x00,0xf2, -0x06,0x06,0x01,0xfc,0x00,0xa8,0x60,0x46,0xf7,0x02,0x40,0x45,0x0f,0x00,0x33,0x44, -0x54,0x93,0x33,0x44,0xfd,0xfb,0x80,0x60,0x7c,0x64,0x01,0xfa,0x00,0x64,0x00,0xf0, -0x00,0xfa,0xd0,0x80,0x9e,0xf9,0x02,0x02,0x9f,0xf9,0x08,0xfe,0x2f,0x58,0xff,0xff, -0x66,0x43,0x25,0x46,0x05,0xfc,0x06,0xfc,0x61,0x44,0x02,0xfa,0x01,0xf0,0x03,0x67, -0xb0,0x84,0x00,0xf0,0x3c,0x7e,0x01,0xfa,0x04,0x64,0x03,0xfa,0x04,0xf8,0x00,0x64, -0x23,0xfa,0x0c,0x61,0x10,0x63,0x59,0xda,0xfe,0x1f,0x2f,0x58,0xff,0xff,0x05,0x4c, -0x7c,0x61,0x58,0x4f,0xc3,0x00,0x80,0x63,0x13,0x03,0x2c,0x46,0xbf,0xd0,0x25,0x46, -0xff,0xd8,0x2c,0x46,0xfb,0x1d,0x25,0x46,0x00,0x64,0xd0,0x80,0x09,0xfa,0x0a,0xfa, -0x05,0x03,0x64,0x46,0x01,0xf0,0x08,0x67,0xc0,0x84,0x01,0xfa,0x58,0x4f,0x02,0x00, -0x2e,0x58,0xff,0xff,0x27,0x43,0x00,0xbb,0x25,0x46,0x12,0x03,0xbe,0xd3,0x08,0xfc, -0x00,0xa8,0xff,0xff,0x03,0x02,0x25,0x44,0xa3,0xdb,0x04,0x00,0x0a,0xfa,0x60,0x46, -0x25,0x44,0x09,0xfa,0xbe,0xdb,0x04,0xa3,0xa3,0xd3,0xff,0xff,0xdc,0x84,0xa3,0xdb, -0x2f,0x58,0xff,0xff,0x07,0x4c,0x58,0x4f,0x28,0x00,0x0c,0x47,0x58,0x4f,0xe2,0x00, -0x2e,0x58,0xff,0xff,0x07,0x4c,0x58,0x4f,0x20,0x00,0x0c,0x47,0x58,0x4f,0x5e,0x00, -0x2e,0x58,0xff,0xff,0x07,0x4c,0x58,0x4f,0x18,0x00,0x0c,0x47,0x27,0x44,0x00,0xbe, -0x08,0xf0,0x11,0x03,0x09,0xf2,0x25,0x43,0x09,0xfc,0x63,0x46,0x27,0x43,0x0a,0xfc, -0x09,0xfa,0x08,0xf8,0x00,0xa8,0x66,0x43,0x03,0x02,0x64,0x44,0x58,0xdd,0x03,0x00, -0x60,0x46,0x25,0x44,0x0a,0xfa,0x2e,0x58,0xff,0xff,0x25,0x46,0x08,0xf2,0x09,0xf0, -0x00,0xa8,0x40,0x47,0x1d,0x03,0x0a,0xf2,0x64,0x43,0x00,0xbb,0x27,0x42,0xda,0x82, -0x08,0x24,0xa2,0xdb,0x00,0xa8,0xca,0x82,0x02,0x02,0xa2,0xdd,0x02,0x00,0x60,0x46, -0x09,0xfc,0x00,0xbb,0x63,0x46,0x08,0x28,0x0a,0xfa,0x25,0x46,0x00,0x64,0x09,0xfa, -0x0a,0xfa,0x08,0xfa,0x27,0x42,0x04,0xa2,0xa2,0xd3,0xff,0xff,0xcc,0x84,0xa2,0xdb, -0x2f,0x58,0xff,0xff,0x25,0x46,0x01,0xf2,0x00,0xf2,0xff,0xff,0x03,0x23,0x11,0x00, -0x00,0xa8,0x60,0x46,0x0c,0x03,0x01,0xf0,0x78,0x67,0xa0,0x80,0xf8,0x67,0x07,0x03, -0xc0,0x84,0x01,0xfa,0x25,0x46,0x00,0x64,0x00,0xfa,0x25,0x44,0x05,0xfa,0x58,0x4f, -0xc4,0x00,0x58,0x4f,0x27,0x00,0xd1,0xfe,0x2e,0x58,0xff,0xff,0x27,0x43,0x00,0xbb, -0x25,0x46,0x10,0x03,0xa3,0xd3,0x08,0xfc,0x00,0xa8,0x09,0xfa,0x03,0x02,0x25,0x44, -0xbe,0xdb,0x04,0x00,0x60,0x46,0x25,0x44,0x0a,0xfa,0x25,0x46,0x00,0x64,0x0a,0xfa, -0x25,0x44,0xa3,0xdb,0x2f,0x58,0xff,0xff,0x9f,0xf3,0x05,0xf0,0x00,0xbe,0x9f,0xf9, -0x25,0x44,0x02,0x02,0x9e,0xfb,0x01,0x00,0x00,0xfa,0x25,0x46,0x7c,0x64,0x01,0xfa, -0x2f,0x58,0xff,0xff,0x9f,0xf3,0x00,0x61,0x00,0xbe,0x25,0x44,0x02,0x03,0x00,0xfa, -0x01,0x00,0x9e,0xfb,0x60,0x46,0x00,0xf2,0x66,0x43,0x00,0xbe,0xdd,0x81,0xfb,0x02, -0x9f,0xfd,0x33,0x45,0x45,0x93,0x33,0x44,0xfd,0xfb,0x2f,0x58,0xff,0xff,0x25,0x46, -0x05,0xf0,0x06,0xf2,0x05,0xfa,0xd0,0x80,0x64,0x43,0x0e,0x03,0x60,0x46,0x01,0xf0, -0x80,0x67,0xb0,0x84,0x01,0xfa,0x00,0xf0,0x00,0x64,0x00,0xfa,0x64,0x46,0x05,0xfc, -0x46,0x45,0x58,0x4f,0xd7,0x00,0xd1,0xfe,0x2e,0x58,0xff,0xff,0x00,0x66,0x46,0x45, -0x29,0x43,0xfc,0xa3,0x66,0x44,0xbd,0xdb,0x25,0x44,0xbd,0xdb,0x00,0x64,0xbd,0xdb, -0x03,0x61,0x1a,0x65,0x3c,0x60,0x80,0x63,0x43,0x49,0xa3,0xd3,0x06,0xa3,0x00,0xa8, -0xcd,0x81,0x04,0x02,0xf9,0x02,0x19,0x60,0x56,0x78,0xff,0xff,0x01,0x26,0xe6,0x00, -0xd4,0x80,0x60,0x45,0xe3,0x05,0xf6,0xa3,0xbd,0xd1,0xbd,0xd1,0x44,0x47,0x44,0x48, -0x44,0x45,0x13,0x60,0x1a,0x64,0x44,0xd7,0xff,0xff,0xff,0xff,0x9e,0xf3,0x33,0x41, -0x00,0xa8,0x40,0x45,0x0f,0x03,0x60,0x46,0x80,0x60,0x7c,0x64,0x01,0xfa,0x4d,0x93, -0x33,0x44,0xfd,0xfb,0x00,0x64,0x00,0xf0,0x00,0xfa,0xd0,0x80,0x9e,0xf9,0x02,0x02, -0x9f,0xf9,0x08,0xfe,0x2f,0x58,0xff,0xff,0xa2,0xfe,0xff,0xff,0x12,0x05,0xa0,0xfe, -0xff,0xff,0x07,0x05,0xa3,0xfe,0xff,0xff,0x07,0x05,0xa1,0xfe,0xff,0xff,0x0a,0x04, -0x18,0x00,0x20,0x58,0xff,0xff,0xff,0xff,0x65,0xf3,0xff,0xff,0x80,0xbc,0x65,0xfb, -0x10,0x00,0xff,0xff,0xff,0xff,0x0a,0x00,0x99,0xff,0x30,0x44,0x50,0xbc,0x40,0x51, -0x98,0xff,0x99,0xff,0x30,0x44,0x7d,0xb4,0x40,0x51,0x98,0xff,0xa1,0xff,0xff,0xff, -0xbb,0x3f,0x3c,0x44,0xac,0x84,0x8b,0xf3,0xf9,0x02,0x02,0xa8,0x00,0x64,0x09,0x02, -0x8b,0xfb,0x8c,0xfb,0x8d,0xfb,0xca,0xfe,0x00,0x64,0x8e,0xfb,0x1b,0x60,0x20,0x78, -0xff,0xff,0x8b,0xf3,0x8c,0xf3,0x02,0xa8,0x02,0xa8,0x0a,0x02,0x00,0x64,0x8d,0xfb, -0x8b,0xfb,0x8c,0xfb,0x00,0x64,0x8e,0xfb,0xca,0xfe,0x1b,0x60,0xd8,0x78,0xff,0xff, -0x8d,0xf1,0x00,0x64,0x64,0x41,0x02,0x02,0x8c,0xfb,0xca,0xfe,0x61,0x44,0x01,0xa8, -0xff,0xff,0x09,0x02,0x3c,0x60,0x76,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46, -0x14,0x02,0xfe,0xb4,0x8d,0xfb,0x95,0xf3,0xff,0xff,0x60,0x40,0x01,0x26,0x10,0x00, -0x8c,0xf3,0x8e,0xf3,0x01,0xa8,0x02,0xb0,0x01,0x02,0x0a,0x03,0x3c,0x60,0x2e,0x62, -0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x67,0x03,0x1b,0x60,0xef,0x78,0xff,0xff, -0x3c,0x60,0x2e,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x74,0x02,0xcb,0xf3, -0xff,0xff,0xfd,0xa0,0x6d,0xf3,0x44,0x02,0x02,0xb0,0x67,0xf1,0x06,0x02,0x64,0x43, -0x00,0xbb,0xff,0xff,0x02,0x03,0x63,0x44,0x08,0x00,0xfd,0xb4,0x6d,0xfb,0x3c,0x60, -0x28,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x00,0xbc,0x67,0xfb,0x44,0x03, -0x60,0x46,0x2b,0xf2,0xff,0xff,0x01,0xb0,0x6d,0xf3,0x04,0x03,0x01,0xb0,0xff,0xff, -0x19,0x02,0x16,0x00,0xfe,0xb4,0x6d,0xfb,0x69,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff, -0x0f,0x03,0x19,0xf2,0xff,0xff,0x00,0xbc,0xff,0xff,0x0c,0x03,0xa0,0xd3,0xff,0xff, -0x02,0xb0,0xff,0xff,0x07,0x03,0x69,0x60,0x58,0x4e,0x9b,0x78,0xff,0xff,0x02,0x03, -0x09,0xf2,0xdb,0x00,0x0d,0xf2,0xff,0xff,0x00,0x7f,0x0d,0xfa,0x09,0xf2,0x67,0xfb, -0x00,0xbc,0xff,0xff,0x30,0x02,0x6d,0xf3,0xff,0xff,0xfe,0xb4,0x6d,0xfb,0x2b,0x00, -0x3c,0x60,0x28,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x0d,0x03,0x13,0xf3, -0x95,0xf3,0x00,0xa8,0x00,0xa0,0x1f,0x03,0x1e,0x03,0x22,0xf0,0x10,0x64,0xb0,0x84, -0xa2,0xda,0x1e,0x60,0xc5,0x78,0xff,0xff,0x00,0x64,0x40,0x5c,0x65,0xf3,0xff,0xff, -0xcb,0xf1,0x80,0x2a,0x0d,0x00,0x7f,0xb4,0x65,0xfb,0x64,0x40,0x04,0x3a,0x08,0x00, -0x29,0x44,0x2a,0x37,0x05,0x00,0x74,0xf3,0xff,0xff,0x04,0xbc,0x74,0xfb,0xc9,0xfe, -0x1b,0x60,0x20,0x78,0xff,0xff,0x65,0xf3,0xff,0xff,0xff,0xff,0x80,0x26,0x13,0x00, -0x02,0x26,0x0f,0x00,0x68,0x60,0xcc,0x62,0x90,0x60,0x62,0x64,0xa2,0xdb,0x3c,0x60, -0x9a,0x62,0x08,0x64,0xa2,0xdb,0x00,0x64,0x5a,0xdb,0x2d,0xff,0x1b,0x60,0x2a,0x78, -0xff,0xff,0x80,0xbc,0x65,0xfb,0xcb,0xf3,0x0e,0xf0,0xfc,0xa0,0xfd,0xa0,0x01,0x03, -0x17,0x02,0x60,0x41,0x02,0x65,0x64,0x44,0x40,0x49,0x2a,0x37,0x11,0x00,0x18,0x37, -0x0f,0x00,0xff,0x37,0x02,0x00,0xfd,0x3b,0x06,0x00,0x61,0x44,0xfd,0xa0,0x01,0x65, -0x02,0x03,0x00,0x64,0x66,0xfb,0x74,0xf3,0xff,0xff,0xb4,0x84,0x74,0xfb,0xc9,0xfe, -0x29,0xf2,0x66,0xf1,0x60,0x40,0xb0,0x36,0x06,0x00,0x00,0x36,0x04,0x00,0x20,0x36, -0x02,0x00,0xb0,0x84,0x29,0xfa,0xf7,0x60,0x0d,0x78,0xff,0xff,0x1a,0xee,0x7f,0x00, -0x86,0x02,0x67,0x60,0x4e,0x62,0x00,0x64,0xa2,0xdb,0x29,0xf0,0xff,0xff,0x64,0x40, -0x40,0x27,0x03,0x00,0x1c,0x60,0x32,0x78,0xff,0xff,0x3e,0xf3,0xff,0xff,0xff,0xff, -0x04,0x2a,0x19,0x00,0x46,0x5c,0x67,0x60,0x58,0x62,0x01,0x64,0xa2,0xdb,0xf7,0x60, -0x2e,0x64,0x40,0x44,0x99,0xff,0x30,0x44,0x41,0xbc,0x40,0x51,0x98,0xff,0xa1,0xff, -0xff,0xff,0xbb,0x3f,0x99,0xff,0x30,0x44,0xfe,0xb4,0x40,0x51,0x98,0xff,0x67,0x60, -0x58,0x62,0x00,0x64,0xa2,0xdb,0x42,0xf3,0x00,0x65,0x60,0x41,0xd6,0xf3,0x95,0xf3, -0x00,0xa0,0x00,0xa0,0x09,0x03,0x23,0xf2,0x04,0x03,0x60,0x45,0x00,0x7f,0x60,0x41, -0x03,0x00,0xff,0xff,0xff,0x36,0x03,0x61,0x44,0xf1,0x98,0xff,0x64,0x40,0x08,0x26, -0x02,0x00,0x00,0x64,0x14,0x00,0x07,0xf2,0xff,0xff,0x00,0xa0,0xff,0xff,0x06,0x03, -0x1a,0xf2,0x38,0xfb,0xff,0xff,0x1b,0xf2,0x39,0xfb,0x15,0x00,0x38,0xf3,0x39,0xf1, -0xdc,0x84,0x38,0xfb,0x1a,0xfa,0x64,0x44,0x02,0x24,0xdc,0x84,0xff,0xb4,0x60,0x5c, -0x02,0xfe,0x61,0x44,0x03,0xb4,0xf8,0x84,0xf8,0x84,0xf8,0x84,0xb0,0x84,0x39,0xfb, -0x1b,0xfa,0x01,0x64,0x07,0xfa,0x61,0x5c,0x41,0xf3,0x64,0x40,0x03,0x26,0x06,0x00, -0x60,0x40,0x01,0x2a,0x15,0x00,0x67,0x60,0x90,0x63,0x30,0x00,0x64,0x40,0x03,0x2a, -0x06,0x00,0x60,0x40,0x08,0x2a,0x0c,0x00,0x67,0x60,0xba,0x63,0x27,0x00,0x64,0x40, -0x01,0x2a,0x0e,0x00,0x60,0x40,0x02,0x2a,0x03,0x00,0x67,0x60,0x9e,0x63,0x1e,0x00, -0x46,0x5c,0x22,0xf0,0x04,0x64,0xb0,0x84,0xa2,0xda,0x1e,0x60,0xc5,0x78,0xff,0xff, -0x60,0x40,0x04,0x2a,0xf5,0x00,0x65,0x47,0x00,0x36,0x0e,0x00,0x00,0x7f,0xe0,0x84, -0x60,0x45,0xe0,0x84,0xe0,0x81,0xc4,0x85,0xc5,0x85,0x3d,0x60,0x4e,0x64,0xc4,0x83, -0x02,0x61,0x67,0x44,0xda,0xfb,0x02,0x00,0x67,0x60,0xac,0x63,0x00,0x60,0x00,0xea, -0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xeb,0xff,0xff,0xff,0xff,0x38,0xf1,0xe0,0x7f, -0x64,0x5e,0x99,0xff,0x40,0x5a,0x64,0x47,0xe1,0x7f,0x40,0x5a,0x39,0xf3,0xff,0xff, -0xe2,0x7f,0x40,0x5a,0x61,0x5c,0xda,0xf3,0xda,0xf9,0xd0,0x80,0xbd,0xd3,0x30,0x03, -0x60,0x45,0xe3,0x7f,0x40,0x5a,0x65,0x47,0xe4,0x7f,0xbd,0xd3,0x40,0x5a,0x60,0x45, -0xe5,0x7f,0x40,0x5a,0x65,0x47,0xe6,0x7f,0xbd,0xd3,0x40,0x5a,0x60,0x45,0x45,0xf1, -0xe7,0x7f,0x40,0x5a,0x64,0x40,0x0f,0x3a,0x61,0x00,0x65,0x47,0xe8,0x7f,0xbd,0xd3, -0x40,0x5a,0x60,0x45,0xe9,0x7f,0x40,0x5a,0x65,0x47,0xea,0x7f,0xbd,0xd3,0x40,0x5a, -0x60,0x45,0xeb,0x7f,0x40,0x5a,0x65,0x47,0xec,0x7f,0xbd,0xd3,0x40,0x5a,0x60,0x45, -0xed,0x7f,0x40,0x5a,0x65,0x47,0xee,0x7f,0xbd,0xd3,0x40,0x5a,0xef,0x7f,0x40,0x5a, -0x20,0x60,0x00,0xeb,0x67,0x60,0xc8,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff,0x01,0x2a, -0x3d,0x00,0x00,0x64,0xa2,0xdb,0x00,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff, -0x3a,0x5c,0x80,0x2b,0x12,0x00,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b, -0x09,0x00,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b,0x03,0x00,0x8b,0xff, -0x74,0x40,0x88,0xff,0x8b,0xff,0x74,0x40,0x88,0xff,0x3a,0x5c,0x80,0x2b,0xff,0xff, -0x31,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xea,0x3a,0x5c,0x80,0x27, -0x09,0x00,0x31,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0x00,0x60,0x00,0xea,0x3a,0x5c, -0x80,0x2b,0xf7,0x00,0x00,0x64,0xdb,0xfb,0x67,0x60,0xcc,0x64,0x3a,0x5c,0xa0,0xd9, -0xff,0xff,0x30,0x60,0x00,0xea,0xff,0xff,0xff,0xff,0xff,0xff,0x3a,0x40,0x40,0x27, -0xfd,0x00,0x67,0x60,0x5c,0x62,0x00,0x64,0xa2,0xdb,0x45,0xf1,0x80,0x60,0x00,0x64, -0xb0,0x84,0x40,0x5a,0x98,0xff,0x33,0x60,0x00,0xea,0x3f,0xf3,0xff,0xff,0x01,0xbc, -0x3f,0xfb,0x1c,0x60,0x32,0x78,0xff,0xff,0x64,0x38,0x7e,0x00,0xe8,0x06,0x19,0xf2, -0xff,0xff,0x00,0xb8,0x1d,0xf2,0x06,0x03,0x60,0x47,0x00,0x7f,0x53,0xfb,0x51,0xfb, -0x60,0x5c,0x07,0x00,0x50,0xf3,0x51,0xf1,0xff,0xff,0x52,0xfb,0x53,0xf9,0x00,0x64, -0x54,0xfb,0x95,0xf3,0xff,0xff,0x00,0xbc,0xff,0xff,0x06,0x02,0x29,0xf2,0xff,0xff, -0x0c,0xb4,0xff,0xff,0x00,0x3a,0x02,0x00,0x13,0xf0,0x53,0xf9,0x64,0x44,0x00,0xa0, -0x01,0x63,0x04,0x03,0xff,0xa0,0x02,0x63,0x01,0x03,0x0b,0x63,0x55,0xfd,0x46,0x5c, -0x22,0xf2,0xff,0xff,0x60,0x40,0x10,0x26,0x40,0x00,0x21,0xf2,0x16,0xf2,0x60,0x45, -0x45,0x4c,0xc4,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x21,0xfa,0x17,0xf0,0x2c,0x44, -0xc0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x1f,0xfa,0x95,0xf3,0x29,0xf0,0x00,0xbc, -0x00,0x64,0x03,0x02,0x64,0x40,0x80,0x3a,0x01,0xbc,0x4f,0xfb,0x95,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x06,0x03,0x27,0xf2,0xff,0xff,0x00,0xa0,0xff,0xff,0x19,0x03, -0x1c,0x00,0xa6,0xf3,0x56,0x63,0x02,0xa8,0x29,0xf2,0x13,0x03,0x29,0xf0,0x60,0x47, -0x64,0x40,0x08,0x2a,0x0e,0x00,0x03,0xa8,0x03,0x2e,0x0b,0x00,0x03,0xb0,0x03,0x22, -0x62,0x63,0x81,0xf1,0xbd,0xd8,0xff,0xff,0x82,0xf1,0xbd,0xd8,0xff,0xff,0x83,0xf1, -0xa3,0xd8,0x4c,0xf3,0x34,0xfa,0x10,0xa4,0x4c,0xfb,0x29,0xf2,0xcb,0xf3,0x60,0x40, -0x08,0x3a,0x76,0x00,0xfd,0xa0,0xfc,0xa0,0x05,0x03,0x95,0xf3,0x03,0x03,0x60,0x40, -0x00,0x36,0x6e,0x00,0x14,0xf2,0x21,0xf0,0xcc,0x84,0x60,0x41,0x04,0x03,0x00,0x64, -0xcd,0x81,0xc0,0x84,0xfd,0x02,0x1f,0xf0,0x53,0xf1,0xc0,0x84,0x55,0xf1,0x64,0x41, -0x02,0x36,0xe0,0x84,0x64,0x45,0x00,0x62,0x11,0x61,0xe0,0x84,0xcd,0x81,0xfd,0x04, -0x01,0x00,0xe0,0x84,0xf2,0x82,0xff,0xff,0x02,0x24,0xc6,0x82,0x02,0x28,0xd6,0x82, -0xe2,0x80,0xcd,0x81,0x02,0x28,0x01,0xbc,0xf4,0x02,0x01,0x2a,0xc6,0x82,0x14,0xf0, -0x60,0x43,0x00,0x60,0xaf,0x65,0x00,0x64,0x64,0x41,0xcd,0x81,0xc4,0x84,0xfd,0x02, -0x63,0x45,0xc4,0x84,0x40,0x48,0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60,0x10,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x28,0x44,0x70,0x45,0xc4,0x85, -0x02,0x60,0x58,0x64,0xc4,0x84,0xa4,0xf1,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84, -0xe8,0x84,0xe8,0x84,0xc0,0x84,0x60,0x41,0x73,0x45,0xd4,0x80,0xe1,0xf1,0x0d,0x0d, -0x64,0x44,0x00,0x36,0x38,0x00,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x61,0x45, -0xc4,0x84,0x73,0x45,0xd4,0x80,0xff,0xff,0x2e,0x0e,0x68,0x60,0xcc,0x62,0x80,0x60, -0x20,0x64,0xa2,0xdb,0xcb,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x0a,0x02,0x00,0x64, -0x40,0x5c,0x22,0xf0,0x10,0x64,0xb0,0x84,0xa2,0xda,0x1b,0x60,0x20,0x78,0xff,0xff, -0x26,0x00,0xe2,0xf3,0x28,0x45,0x60,0x40,0x00,0x3a,0x15,0x00,0x07,0x60,0xd0,0x64, -0xc4,0x84,0x70,0x45,0xd4,0x80,0xff,0xff,0x0e,0x04,0x60,0x50,0x60,0x45,0x68,0x60, -0xcc,0x62,0x80,0x60,0x30,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb, -0x01,0x64,0xe4,0xfb,0x0c,0x00,0x28,0x44,0x68,0xfb,0x60,0x45,0x68,0x60,0xcc,0x62, -0x80,0x60,0x10,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x67,0x60, -0x4e,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0x00,0x64,0x08,0x03,0xa2,0xdb,0x67,0x60, -0x5a,0x62,0xa2,0xd1,0x1e,0x60,0x9a,0x62,0xa2,0xd9,0x2a,0x00,0x1e,0x60,0x98,0x64, -0xa0,0xd1,0x95,0xf3,0x64,0x41,0x00,0xa0,0x29,0xf2,0x0b,0x02,0x60,0x40,0x80,0x3a, -0x08,0x00,0x71,0xf3,0xdd,0x81,0xf6,0xa0,0xec,0xa0,0x03,0x04,0xdd,0x81,0x01,0x04, -0xdd,0x81,0x25,0xf2,0xff,0xff,0x60,0x47,0x60,0x43,0xff,0xb3,0x61,0x40,0xff,0x22, -0x04,0x00,0x23,0x60,0x58,0x4f,0x4a,0x78,0xff,0xff,0x1e,0x60,0x9a,0x64,0xa0,0xdd, -0xb8,0xf1,0x23,0x60,0x58,0x4f,0x49,0x78,0xff,0xff,0x1e,0x60,0x9c,0x64,0xa0,0xdd, -0x29,0xf2,0xff,0xff,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x60,0x64,0xa2,0xdb, -0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x22,0xf0,0xff,0x60,0xef,0x64,0xa0,0x84, -0xa2,0xda,0x8e,0xf3,0x46,0x5c,0xfd,0xb4,0x01,0xbc,0x8e,0xfb,0x66,0x44,0xe0,0xfb, -0x20,0x60,0x19,0x78,0xff,0xff,0x00,0x64,0x68,0xfb,0xe0,0xfb,0x68,0x60,0xcc,0x62, -0x90,0x60,0x61,0x64,0xa2,0xdb,0x46,0x5c,0x8e,0xf3,0x3c,0x46,0x4e,0xf1,0xfe,0xb4, -0x8e,0xfb,0x01,0x65,0x32,0x40,0x04,0x2b,0x64,0x45,0x02,0x22,0x03,0x00,0x1e,0x60, -0xed,0x78,0xff,0xff,0x65,0x40,0x01,0x26,0x09,0x00,0x5a,0x60,0x5a,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1e,0x60,0xc5,0x78,0xff,0xff,0x27,0xf0,0x01,0x60, -0x00,0x64,0xc0,0x84,0x27,0xfa,0x29,0xf0,0x00,0x60,0x0c,0x64,0xa0,0x84,0x04,0x36, -0x02,0x00,0x0c,0x3a,0x03,0x00,0x1e,0x60,0xc5,0x78,0xff,0xff,0x60,0x41,0x61,0x40, -0x08,0x36,0x67,0x00,0x29,0xf0,0x00,0x60,0xf0,0x64,0xa0,0x84,0xff,0xff,0x00,0x3a, -0x07,0x00,0x5a,0x60,0x1e,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x56,0x00, -0x20,0x3a,0x07,0x00,0x5a,0x60,0x1e,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x4d,0x00,0x40,0x3a,0x07,0x00,0x5a,0x60,0x26,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x44,0x00,0xb0,0x3a,0x07,0x00,0x5a,0x60,0x1c,0x64,0xa0,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x3b,0x00,0x80,0x3a,0x16,0x00,0x68,0x60,0xcc,0x62,0x90,0x60, -0x31,0x64,0xa2,0xdb,0x71,0xf3,0xff,0xff,0xdc,0x84,0x71,0xfb,0x80,0xf3,0xff,0xff, -0xfd,0xa4,0x60,0x47,0x01,0xbc,0x6e,0xfb,0x5a,0x60,0x14,0x64,0xa0,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x23,0x00,0xa0,0x3a,0x07,0x00,0x5a,0x60,0x24,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1a,0x00,0x50,0x3a,0x07,0x00,0x5a,0x60,0x2a,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x11,0x00,0x10,0x3a,0x07,0x00,0x5a,0x60, -0x20,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x08,0x00,0x30,0x3a,0x06,0x00, -0x5a,0x60,0x20,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1e,0x60,0xc5,0x78, -0xff,0xff,0x19,0xf2,0x0e,0x65,0x00,0xbc,0xc4,0x83,0x14,0x03,0xa3,0xd3,0xff,0xff, -0x60,0x40,0x14,0x3a,0xdc,0x84,0xa3,0xdb,0x14,0x3a,0x0c,0x00,0x60,0x47,0x00,0x7f, -0xfd,0xa0,0xff,0xff,0x07,0x07,0x19,0xf0,0x1f,0x60,0x58,0x4e,0xd5,0x78,0xff,0xff, -0x00,0x64,0xa3,0xdb,0x14,0xf2,0x28,0xf2,0x60,0x41,0x60,0x45,0x1e,0x63,0x60,0x47, -0x18,0x63,0x04,0xa3,0x63,0x45,0x00,0x63,0xcd,0x81,0xc7,0x83,0xfd,0x02,0x38,0xf0, -0xff,0xff,0xc3,0x83,0x2b,0xf2,0xff,0xff,0xff,0xff,0x01,0x2a,0x31,0x00,0x3d,0x60, -0x1c,0x64,0xa0,0xd3,0xff,0xff,0x01,0xbc,0xa2,0xdb,0x5a,0x60,0x00,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x51,0xf3,0xff,0xff,0xe0,0x84,0xe0,0x84,0x60,0x45,0x5a,0x60,0x04,0x64, -0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x5a,0x60,0x42,0x64,0xa0,0xd3,0x63,0x45,0xc4,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x32,0x00, -0x59,0x60,0xec,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82, -0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x53,0xf3,0xff,0xff,0xe0,0x84,0xe0,0x84, -0x60,0x45,0x59,0x60,0xf0,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x18,0x60,0xbc,0x65, -0x53,0xf3,0xff,0xff,0xe0,0x84,0xc4,0x82,0x00,0x64,0xa2,0xdb,0x5a,0x60,0x42,0x64, -0xa0,0xd3,0x63,0x45,0xc4,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0xcb,0xf3,0x3c,0x46,0xfd,0xa0,0xfc,0xa0,0x01,0x03,0x13,0x00, -0x22,0xf2,0xff,0xff,0x60,0x40,0x10,0x2a,0x0e,0x00,0x8c,0xf1,0x00,0x64,0x40,0x5c, -0x13,0xfb,0xe0,0xfb,0x64,0x40,0x02,0x36,0x03,0x00,0x1b,0x60,0x20,0x78,0xff,0xff, -0x1b,0x60,0x2d,0x78,0xff,0xff,0x3c,0x60,0x7c,0x62,0x3c,0x60,0x4c,0x64,0xa2,0xdb, -0x3c,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xce,0xfe,0x1b,0x60, -0x3d,0x78,0xff,0xff,0x67,0x60,0x4e,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff, -0x03,0x03,0x1f,0x60,0xa1,0x78,0xff,0xff,0x0f,0xf0,0xb7,0xf1,0x64,0x41,0x01,0x2a, -0xb6,0xf1,0x95,0xf3,0xff,0xff,0x60,0x40,0xff,0x26,0x1d,0xf0,0x26,0xf2,0xff,0xff, -0xdc,0x84,0x26,0xfa,0x15,0xf2,0xff,0xff,0xdc,0x84,0xd0,0x80,0x15,0xfa,0x03,0x04, -0x1f,0x60,0xa6,0x78,0xff,0xff,0x13,0xf3,0xff,0xff,0x00,0xa8,0xff,0xff,0x05,0x03, -0x22,0xf0,0x10,0x64,0xb0,0x84,0xa2,0xda,0xad,0x00,0x95,0xf3,0xff,0xff,0x00,0xbc, -0x29,0xf2,0x02,0x02,0x0c,0xb4,0x00,0x36,0x7d,0x00,0x19,0xf2,0xff,0xff,0x00,0xbc, -0x0e,0xa4,0x4f,0x03,0x60,0x43,0xa3,0xd1,0x01,0x60,0x01,0x64,0xc0,0x84,0xa3,0xdb, -0x60,0x45,0x00,0x7f,0xec,0xa0,0xff,0xff,0x0c,0x04,0x65,0x47,0x00,0x7f,0xf9,0xa0, -0xff,0xff,0x05,0x04,0x19,0xf0,0x1f,0x60,0x58,0x4e,0xbe,0x78,0xff,0xff,0x00,0x64, -0xa3,0xdb,0x0d,0xf2,0xff,0xff,0x01,0xa4,0x0d,0xfa,0x00,0x7f,0xfe,0xa0,0xff,0xff, -0x15,0x04,0x1f,0x60,0x58,0x4e,0xec,0x78,0xff,0xff,0x1d,0xf2,0xff,0xff,0x00,0x7e, -0x60,0x47,0x53,0xfb,0x0b,0x63,0x60,0x40,0x00,0x36,0x01,0x63,0x60,0x40,0x01,0x36, -0x02,0x63,0x55,0xfd,0x0d,0xf2,0xff,0xff,0x00,0x7e,0x0d,0xfa,0x0d,0xf2,0xff,0xff, -0x60,0x47,0x01,0xa4,0x60,0x47,0x0d,0xfa,0x60,0x47,0x00,0x7f,0xfd,0xa0,0xff,0xff, -0x39,0x04,0x69,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x04,0x03,0x69,0x60,0x58,0x4e, -0xcc,0x78,0xff,0xff,0x22,0xf0,0x10,0x64,0xb0,0x84,0xa2,0xda,0x1e,0x60,0xc5,0x78, -0xff,0xff,0x54,0xf3,0xff,0xff,0xdc,0x84,0xfe,0xa0,0x54,0xfb,0x23,0x04,0x00,0x64, -0x54,0xfb,0x53,0xf3,0x52,0xf3,0x60,0x41,0xff,0xa0,0xe8,0x84,0x1b,0x03,0xff,0xa1, -0x60,0x45,0x59,0x60,0x6a,0x63,0xa3,0xd3,0xff,0xff,0xa4,0x80,0x65,0x44,0xf4,0x03, -0x52,0xfb,0x61,0x43,0x53,0xfd,0x63,0x44,0x00,0x3a,0x02,0x00,0x01,0x63,0x09,0x00, -0x01,0x3a,0x02,0x00,0x02,0x63,0x05,0x00,0x02,0x3a,0x02,0x00,0x0b,0x63,0x01,0x00, -0x0b,0x63,0x55,0xfd,0x29,0xf0,0x08,0x67,0xb0,0x84,0xa2,0xda,0x00,0x64,0x4f,0xfb, -0xf8,0x60,0x50,0x78,0xff,0xff,0xa0,0xf0,0x7f,0x00,0x72,0x00,0x29,0xf0,0xff,0xff, -0x64,0x40,0x40,0x2b,0x31,0x00,0x3e,0xf3,0xff,0xff,0x60,0x40,0x04,0x2a,0x18,0x00, -0x67,0x60,0x58,0x62,0x01,0x64,0xa2,0xdb,0xf8,0x60,0x69,0x64,0x40,0x44,0x99,0xff, -0x30,0x44,0x41,0xbc,0x40,0x51,0x98,0xff,0xa1,0xff,0xff,0xff,0xbb,0x3f,0x99,0xff, -0x30,0x44,0xfe,0xb4,0x40,0x51,0x98,0xff,0x67,0x60,0x58,0x62,0x00,0x64,0xa2,0xdb, -0x99,0xff,0x3a,0x44,0x98,0xff,0x8f,0x2b,0x0f,0x00,0x50,0x27,0x0d,0x00,0x67,0x60, -0x5c,0x62,0x00,0x64,0xa2,0xdb,0x45,0xf1,0x80,0x60,0x00,0x64,0xb0,0x84,0x99,0xff, -0x40,0x5a,0x98,0xff,0x33,0x60,0x00,0xea,0x1c,0x60,0xa0,0x78,0xff,0xff,0x4c,0x3f, -0x7e,0x00,0xa8,0x07,0x29,0xf2,0xff,0xff,0x60,0x40,0x08,0x3a,0x06,0x00,0x5a,0x60, -0x5a,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1e,0x60,0x98,0x65,0xb8,0xf3, -0xff,0xff,0xa5,0xdb,0x22,0xf0,0x01,0x64,0xb0,0x84,0xa2,0xda,0x1e,0x60,0xc5,0x78, -0xff,0xff,0xff,0x00,0x64,0x44,0x08,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x41,0x60,0x47, -0x00,0x7f,0x60,0x45,0x61,0x44,0x00,0x7f,0xe8,0x84,0xa4,0x80,0x00,0xa0,0x02,0x02, -0x06,0x03,0xfa,0x00,0x60,0x41,0x65,0x47,0x61,0x45,0xb4,0x84,0xa2,0xdb,0x2e,0x58, -0xff,0xff,0x64,0x44,0x08,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x41,0x60,0x47,0x00,0x7f, -0x60,0x45,0x61,0x44,0x00,0x7f,0xe0,0x84,0xa4,0x80,0xf0,0xa0,0x02,0x02,0x06,0x03, -0xfa,0x00,0x60,0x41,0x65,0x47,0x61,0x45,0xb4,0x84,0xa2,0xdb,0x2e,0x58,0xff,0xff, -0x19,0xf2,0xff,0xff,0x08,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x47,0x00,0x7f,0x60,0x45, -0x1d,0xf2,0xff,0xff,0x40,0x4d,0x60,0x47,0x00,0x7f,0x60,0x41,0x2d,0x44,0x00,0x7f, -0xcd,0x81,0xe8,0x84,0x07,0x0e,0xa4,0x80,0xff,0xff,0xfa,0x03,0x60,0x45,0x61,0x47, -0xb4,0x84,0x1d,0xfa,0x2e,0x58,0xff,0xff,0x22,0x60,0x6b,0x78,0xff,0xff,0x99,0xff, -0x30,0x44,0xff,0xff,0x98,0xff,0x80,0x2a,0x03,0x00,0x47,0xff,0x21,0x58,0xff,0xff, -0x47,0xff,0xa1,0xff,0xff,0xff,0xbb,0x3f,0xff,0xff,0x99,0xff,0x32,0x44,0x98,0xff, -0x10,0x26,0x57,0x00,0x64,0xe2,0x45,0xff,0x47,0xff,0x53,0x0a,0x99,0xff,0x32,0x44, -0x98,0xff,0x10,0x26,0x4e,0x00,0x04,0x27,0x04,0x00,0xb5,0xf3,0xff,0xff,0x60,0x54, -0xcd,0xe2,0x20,0x60,0x3a,0x64,0x40,0x42,0xc4,0xe2,0x99,0xff,0x30,0x44,0x04,0xbc, -0x1d,0xb4,0x40,0x51,0x98,0xff,0xa1,0xff,0xff,0xff,0xbb,0x3f,0x99,0xff,0x32,0x44, -0x98,0xff,0x10,0x26,0x36,0x00,0x64,0xe2,0x45,0xff,0x47,0xff,0x32,0x0a,0x99,0xff, -0x32,0x44,0x98,0xff,0x10,0x26,0x2d,0x00,0xd0,0xf3,0x4f,0xf3,0x00,0xa0,0xff,0xff, -0xea,0x02,0x01,0x3a,0x63,0x00,0x99,0xff,0x3e,0x44,0xfc,0xb4,0x40,0x5e,0x02,0xbc, -0xff,0xff,0xff,0xff,0x40,0x5e,0x98,0xff,0x20,0x60,0x64,0x64,0x40,0x42,0x99,0xff, -0x30,0x44,0x44,0xbc,0x5d,0xb4,0x40,0x51,0x98,0xff,0xa1,0xff,0xff,0xff,0xbb,0x3f, -0x99,0xff,0x32,0x44,0x98,0xff,0x10,0x26,0x0c,0x00,0x64,0xe2,0x45,0xff,0x47,0xff, -0x08,0x0a,0x99,0xff,0x32,0x44,0x98,0xff,0x10,0x26,0x03,0x00,0x21,0x60,0x3b,0x78, -0xff,0xff,0x20,0x60,0x84,0x64,0x40,0x40,0x20,0x60,0xb2,0x64,0x40,0x41,0x99,0xff, -0x30,0x44,0xe0,0xbc,0xf9,0xb4,0x40,0x51,0x98,0xff,0xa1,0xff,0xff,0xff,0xbb,0x3f, -0x28,0x60,0x60,0x62,0xa2,0xd3,0x13,0xf3,0x00,0xa0,0x00,0xa0,0x13,0x03,0x67,0x60, -0xc8,0x62,0x01,0x64,0xa2,0xdb,0x22,0xf0,0x01,0x64,0xb0,0x84,0xa2,0xda,0x99,0xff, -0x30,0x44,0x59,0xb4,0x40,0x51,0x98,0xff,0x1b,0x60,0x20,0x64,0x40,0x40,0x1e,0x60, -0xc5,0x78,0xff,0xff,0x13,0x03,0x67,0x60,0xc8,0x62,0x01,0x64,0xa2,0xdb,0x22,0xf0, -0x10,0x64,0xb0,0x84,0xa2,0xda,0x99,0xff,0x30,0x44,0x59,0xb4,0x40,0x51,0x98,0xff, -0x1b,0x60,0x20,0x64,0x40,0x40,0x1e,0x60,0xc5,0x78,0xff,0xff,0x21,0x60,0x1d,0x64, -0x40,0x40,0x20,0x60,0xe2,0x64,0x40,0x42,0x99,0xff,0x30,0x44,0x44,0xbc,0x5d,0xb4, -0x40,0x51,0x98,0xff,0x99,0xff,0x32,0x44,0x98,0xff,0x10,0x26,0xb2,0x00,0xd0,0xf3, -0x64,0xe2,0x00,0xa0,0x45,0xff,0x47,0xff,0x16,0x02,0xab,0x0a,0x99,0xff,0x32,0x44, -0x98,0xff,0x10,0x26,0xa6,0x00,0x1e,0x60,0x9a,0x65,0xa5,0xd3,0xff,0xff,0x01,0xa8, -0xff,0xff,0x09,0x02,0x99,0xff,0x3e,0x44,0xfc,0xb4,0x40,0x5e,0x02,0xbc,0xff,0xff, -0xff,0xff,0x40,0x5e,0x98,0xff,0xa1,0xff,0xff,0xff,0xbb,0x3f,0xd0,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0xf8,0x02,0x99,0xff,0x32,0x44,0x98,0xff,0x10,0x26,0x89,0x00, -0x64,0xe2,0x45,0xff,0x47,0xff,0x29,0x0a,0x99,0xff,0x32,0x44,0x98,0xff,0x10,0x26, -0x24,0x00,0x13,0xf3,0xff,0xff,0x00,0xa8,0xff,0xff,0x13,0x03,0x67,0x60,0xc8,0x62, -0x01,0x64,0xa2,0xdb,0x22,0xf0,0x10,0x64,0xb0,0x84,0xa2,0xda,0x99,0xff,0x30,0x44, -0x59,0xb4,0x40,0x51,0x98,0xff,0x1b,0x60,0x20,0x64,0x40,0x40,0x1e,0x60,0xc5,0x78, -0xff,0xff,0x1e,0x60,0x9a,0x65,0xa5,0xd3,0xff,0xff,0x00,0xa8,0xcc,0x84,0x27,0x03, -0xa5,0xdb,0x25,0x03,0x20,0x60,0xcf,0x78,0xff,0xff,0x20,0x60,0x75,0x78,0xff,0xff, -0x1e,0x00,0x28,0x60,0x60,0x62,0xa2,0xd3,0x13,0xf3,0x00,0xa0,0x00,0xa0,0x13,0x03, -0x67,0x60,0xc8,0x62,0x01,0x64,0xa2,0xdb,0x22,0xf0,0x01,0x64,0xb0,0x84,0xa2,0xda, -0x99,0xff,0x30,0x44,0x59,0xb4,0x40,0x51,0x98,0xff,0x1b,0x60,0x20,0x64,0x40,0x40, -0x1e,0x60,0xc5,0x78,0xff,0xff,0xc2,0x02,0x20,0x60,0xcf,0x78,0xff,0xff,0x13,0xf3, -0xff,0xff,0x00,0xa8,0xff,0xff,0x13,0x03,0x67,0x60,0xc8,0x62,0x01,0x64,0xa2,0xdb, -0x22,0xf0,0x10,0x64,0xb0,0x84,0xa2,0xda,0x99,0xff,0x30,0x44,0x59,0xb4,0x40,0x51, -0x98,0xff,0x1b,0x60,0x20,0x64,0x40,0x40,0x1e,0x60,0xc5,0x78,0xff,0xff,0x29,0xf2, -0xff,0xff,0x60,0x40,0x40,0x2b,0x25,0x00,0x3e,0xf3,0xff,0xff,0x60,0x40,0x04,0x26, -0x0b,0x00,0x99,0xff,0x3a,0x5c,0x98,0xff,0x64,0x40,0x40,0x27,0x09,0x00,0x64,0x40, -0x0f,0x2b,0x02,0x00,0x33,0x60,0x00,0xea,0x98,0xff,0x20,0x60,0xb2,0x78,0xff,0xff, -0x99,0xff,0x3a,0x5c,0x98,0xff,0x64,0x40,0x10,0x2b,0xf6,0x00,0xdb,0xf3,0xff,0xff, -0xff,0xff,0x01,0x26,0x06,0x00,0x8b,0xff,0x74,0x40,0x74,0x40,0x88,0xff,0x01,0x64, -0xdb,0xfb,0x21,0xf3,0xff,0xff,0xc4,0xb4,0x21,0xfb,0x21,0x60,0x9d,0x64,0x40,0x40, -0x01,0x64,0x22,0xfb,0x99,0xff,0x30,0x44,0x40,0xbc,0x59,0xb4,0x40,0x51,0x98,0xff, -0xe2,0xf1,0x68,0x60,0xcc,0x62,0x80,0x60,0x70,0x64,0xa2,0xdb,0x64,0x40,0x01,0x26, -0xff,0xff,0xa0,0xfe,0x1a,0xff,0x00,0x64,0x68,0xfb,0xff,0xff,0xa1,0xff,0xff,0xff, -0xbb,0x3f,0x95,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x07,0x02,0x13,0xf3,0xff,0xff, -0x00,0xa0,0x00,0x64,0x02,0x03,0x13,0xfb,0xe3,0x00,0x28,0x60,0x60,0x62,0xa2,0xd3, -0xff,0xff,0x00,0xa0,0x00,0x64,0x02,0x03,0xa2,0xdb,0xda,0x00,0x21,0xf3,0xff,0xff, -0xff,0xff,0x01,0x2a,0x0d,0x00,0xfe,0xb4,0x21,0xfb,0x01,0x64,0x4e,0xfb,0x1e,0x60, -0x98,0x65,0xb8,0xf3,0xff,0xff,0xa5,0xdb,0xff,0xff,0x22,0x60,0x3c,0x78,0xff,0xff, -0x02,0x2a,0x62,0x00,0x27,0xf2,0xff,0xff,0xdc,0x84,0x27,0xfa,0x5a,0x60,0x46,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x17,0x60,0xea,0x64,0xa0,0xd3,0xff,0xff,0xe8,0x84,0xe0,0x84, -0x60,0x45,0x18,0x60,0x56,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x53,0xf3,0xff,0xff,0xe0,0x84,0x60,0x45,0x18,0x60,0xbc,0x64,0xc4,0x84,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x53,0xf3,0xff,0xff,0xe0,0x84,0xe0,0x84,0x60,0x45, -0x5a,0x60,0x4a,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x21,0xf3,0xff,0xff,0xfd,0xb4, -0x21,0xfb,0x02,0x64,0x4e,0xfb,0x29,0xf2,0xff,0xff,0x0c,0xb4,0xff,0xff,0x00,0x36, -0x5e,0x00,0x95,0xf1,0x00,0x63,0xd3,0x80,0xff,0xff,0x04,0x02,0xb9,0xf1,0xff,0xff, -0x64,0x45,0x09,0x00,0x25,0xf2,0xff,0xff,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84, -0x0f,0xb4,0xff,0xff,0x60,0x45,0x1e,0x60,0x98,0x63,0xa3,0xd3,0xff,0xff,0xd4,0x80, -0xdc,0x84,0x45,0x03,0xa3,0xdb,0x43,0x00,0x10,0x2a,0x07,0x00,0x21,0xf3,0x2b,0xf0, -0xef,0xb4,0x21,0xfb,0x20,0x60,0x19,0x78,0xff,0xff,0x21,0xf3,0xff,0xff,0xdf,0xb4, -0x21,0xfb,0x2b,0xf0,0x02,0x64,0x64,0x40,0x01,0x26,0x01,0x64,0x4e,0xfb,0x2f,0x00, -0x00,0x63,0x95,0xf3,0x68,0xfd,0x00,0xbc,0xff,0xff,0x29,0x02,0x28,0x0a,0x70,0x44, -0xac,0x80,0xff,0xff,0x24,0x02,0x32,0x40,0x02,0x27,0x21,0x00,0x1e,0x60,0x9c,0x65, -0xa5,0xd3,0xff,0xff,0x00,0xa8,0xff,0xff,0x1a,0x03,0x22,0x60,0x5d,0x64,0x40,0x42, -0x99,0xff,0x30,0x44,0x04,0xbc,0x1d,0xb4,0x40,0x51,0x98,0xff,0xa1,0xff,0xff,0xff, -0xbb,0x3f,0x0d,0x0a,0x70,0x44,0xac,0x80,0xff,0xff,0x09,0x02,0x1e,0x60,0x9c,0x65, -0xa5,0xd3,0xff,0xff,0xcc,0x84,0xa5,0xdb,0xff,0xff,0xf0,0x02,0x00,0x00,0x99,0xff, -0x30,0x44,0x59,0xb4,0x40,0x51,0x98,0xff,0x1b,0x60,0x20,0x64,0x40,0x40,0x1d,0x60, -0x96,0x78,0xff,0xff,0xa4,0xe2,0xff,0xff,0xa4,0xe2,0x73,0x44,0xa4,0xfb,0x80,0xf3, -0x60,0x45,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xc4,0x93,0x00,0x60,0x01,0x71, -0x95,0xf1,0xcb,0xf3,0x64,0x40,0x00,0x36,0x05,0x00,0x8a,0xff,0x80,0x60,0x00,0x75, -0x88,0xff,0x03,0x00,0xfc,0xa0,0xff,0xff,0x18,0x02,0xe1,0xf3,0x80,0xf1,0x00,0xa0, -0x60,0x45,0x13,0x03,0x67,0x60,0x7c,0x62,0x64,0x41,0xd5,0x84,0xdc,0x84,0xa2,0xdb, -0x00,0x64,0xe2,0xfb,0x99,0xff,0x3c,0x44,0x00,0x7f,0xbf,0xb4,0x40,0x5c,0x98,0xff, -0x68,0x60,0xcc,0x62,0x80,0x60,0x60,0x64,0xa2,0xdb,0xe4,0xf3,0xe3,0xf1,0x00,0xa0, -0xff,0xff,0x03,0x03,0x64,0x50,0x00,0x64,0xe4,0xfb,0x5e,0xf3,0xff,0xff,0x60,0x41, -0xfd,0xb4,0xa2,0xdb,0x61,0x44,0x01,0xb0,0x02,0xb0,0x0a,0x03,0x09,0x02,0x3c,0x60, -0xae,0x62,0x28,0x60,0xce,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x16,0x60,0x42,0x62,0xa2,0xd3,0xff,0xff,0xfc,0xa0,0x01,0x64,0x02,0x02,0x75,0xfb, -0xc9,0xfe,0x73,0x44,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x10,0x64,0xa2,0xdb, -0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0xcb,0xf3,0x62,0xf3,0xfc,0xa0,0x00,0xa0, -0x69,0x02,0x17,0x02,0x64,0xf3,0xff,0xff,0x00,0xa0,0xcc,0x84,0x12,0x03,0x64,0xfb, -0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60,0x40,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62, -0x65,0x44,0xa2,0xdb,0x57,0x02,0x63,0xf3,0x64,0xfb,0x67,0x60,0x8a,0x62,0x01,0x64, -0xa2,0xdb,0x67,0x60,0x8a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0x00,0x64,0x4a,0x03, -0xa2,0xdb,0x67,0x60,0x84,0x65,0x67,0x60,0x82,0x63,0xa5,0xd1,0xa3,0xd3,0x64,0x40, -0x00,0x36,0x40,0x03,0xcc,0x84,0xa3,0xdb,0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60, -0x50,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x33,0x02,0x64,0x44, -0xa3,0xdb,0x67,0x60,0x86,0x63,0x67,0x60,0x8c,0x65,0xbd,0xd3,0xa3,0xdb,0xc4,0xa0, -0xff,0xff,0x11,0x04,0xc4,0xa4,0xa3,0xdb,0xa5,0xdb,0xf0,0x60,0x00,0x64,0x60,0x50, -0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60,0x32,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62, -0x65,0x44,0xa2,0xdb,0x17,0x00,0x60,0x47,0xe0,0x84,0xe0,0x84,0x70,0x45,0xd4,0x80, -0xff,0xff,0x10,0x04,0x60,0x50,0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60,0x32,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x67,0x60,0x8c,0x65,0x00,0x64, -0xa3,0xdb,0xa5,0xdb,0x1b,0x60,0x2a,0x78,0xff,0xff,0x64,0x41,0x40,0x60,0x0b,0x65, -0x2b,0x44,0x00,0x63,0xe8,0x80,0xf8,0x84,0x02,0x24,0x94,0x84,0xf3,0x83,0xcd,0x81, -0xff,0xff,0xf8,0x02,0x2f,0x58,0x40,0x4b,0x00,0x62,0x01,0x64,0xd4,0x80,0xe0,0x84, -0x1b,0x03,0xd4,0x80,0xe0,0x84,0x16,0x03,0x61,0x44,0x11,0x61,0xe0,0x84,0xcd,0x81, -0xfd,0x04,0x01,0x00,0xe0,0x84,0xf2,0x82,0xff,0xff,0x02,0x24,0xc6,0x82,0x02,0x28, -0xd6,0x82,0xe2,0x80,0xcd,0x81,0x02,0x28,0x01,0xbc,0xf4,0x02,0x01,0x2a,0xc6,0x82, -0x2f,0x58,0xff,0xff,0xe9,0x81,0xf2,0x82,0x61,0x44,0xfa,0x00,0x12,0xf1,0x7f,0x00, -0xda,0x00,0xa1,0xff,0xff,0xff,0xbc,0x3f,0x40,0xf3,0xff,0xff,0x60,0x40,0x01,0x2a, -0x03,0x00,0x18,0x60,0x17,0x78,0xff,0xff,0x3d,0x46,0x29,0xf0,0xff,0xff,0x64,0x40, -0x40,0x2b,0x27,0x00,0x3e,0xf3,0xff,0xff,0x60,0x40,0x02,0x26,0x1a,0x00,0x0f,0xf2, -0xff,0xff,0x60,0x40,0x04,0x2a,0x00,0x00,0x99,0xff,0x3b,0x44,0x98,0xff,0xff,0xff, -0x0f,0x2b,0x05,0x00,0x40,0x27,0xf8,0x00,0xf5,0x60,0xbc,0x78,0xff,0xff,0x9c,0xf3, -0xff,0xff,0xff,0xff,0x02,0x26,0xd5,0x00,0x67,0x60,0xca,0x62,0x01,0x64,0xa2,0xdb, -0xd0,0x00,0x0f,0xf2,0xff,0xff,0x60,0x40,0x04,0x2a,0xcb,0x00,0x17,0x60,0xa6,0x78, -0xff,0xff,0x0f,0xf2,0xff,0xff,0x08,0xbc,0x0f,0xfa,0x3c,0x60,0x64,0x62,0xa2,0xd3, -0xff,0xff,0x00,0xa8,0x60,0x46,0x01,0x02,0xbc,0x00,0x0f,0xf0,0xff,0xff,0xff,0xff, -0x64,0x40,0x00,0x3a,0x04,0x00,0x0f,0xf0,0x70,0x64,0xb0,0x84,0xa2,0xda,0x67,0x60, -0x62,0x62,0x00,0x64,0xa2,0xdb,0x40,0xfb,0x3e,0xf3,0xff,0xff,0xf9,0xb4,0x3e,0xfb, -0x3d,0x46,0x0f,0xf0,0x04,0x64,0xb0,0x84,0xa2,0xda,0xcb,0xfe,0x40,0xff,0xbc,0xfe, -0x29,0xf2,0xff,0xff,0xff,0xff,0x40,0x2b,0x9c,0x00,0x67,0x60,0x58,0x64,0xa0,0xd3, -0xff,0xff,0xff,0xa0,0xff,0xff,0x95,0x02,0x04,0xff,0x93,0x00,0xf4,0x46,0x7e,0x00, -0x00,0x10,0x7f,0xf1,0x10,0x60,0xdc,0xe0,0x43,0x45,0x65,0xf3,0x44,0x46,0x60,0x40, -0x02,0x2a,0x03,0x00,0x23,0x60,0xc8,0x78,0xff,0xff,0x01,0x64,0x65,0xfb,0x99,0xff, -0x00,0x6b,0x3e,0x44,0x70,0xb4,0x40,0x5e,0x3d,0x44,0xf7,0xb4,0x90,0xbc,0x40,0x5d, -0x3c,0x44,0x6f,0xb4,0x40,0x5c,0x98,0xff,0x20,0x44,0x60,0xbc,0x40,0x40,0x01,0x64, -0x60,0x47,0x99,0xfb,0x05,0x64,0x9a,0xfb,0xff,0xff,0xdf,0xfe,0x19,0xff,0x23,0x60, -0xa6,0x64,0x9b,0xfb,0xf8,0x60,0x89,0x78,0xff,0xff,0x1f,0xf3,0xff,0xff,0xff,0xff, -0x20,0x26,0x05,0x00,0x13,0x60,0x5a,0x63,0x14,0x60,0x3e,0x65,0x04,0x00,0x14,0x60, -0x3e,0x63,0x15,0x60,0x22,0x65,0x80,0xe1,0x02,0x00,0x01,0x16,0xfe,0x00,0xbd,0xd1, -0xff,0xff,0x64,0x48,0x64,0x47,0x00,0x7f,0x60,0x41,0x80,0xbc,0x60,0x4a,0xff,0xff, -0xff,0xff,0xa1,0xff,0xff,0xff,0xd7,0x80,0xff,0xff,0xef,0x02,0x68,0x40,0x67,0x60, -0x80,0x62,0xa2,0xd3,0x00,0x7c,0xa2,0xd9,0x60,0x40,0x01,0x2a,0x09,0x00,0x40,0x65, -0xa4,0x85,0x99,0xff,0x3c,0x44,0xbf,0xb4,0xb4,0x84,0x00,0x7f,0x40,0x5c,0x98,0xff, -0x20,0x44,0x60,0xbc,0x40,0x40,0x80,0xe1,0x14,0x60,0x7a,0x63,0xa3,0xd1,0x67,0x60, -0x70,0x62,0xa2,0xd3,0xff,0xff,0xd0,0x80,0xa2,0xd9,0x16,0x03,0x01,0x64,0xd8,0xfb, -0xd7,0xf3,0xff,0xff,0xff,0xff,0x01,0x26,0xfb,0x00,0x64,0x48,0x64,0x47,0x00,0x7f, -0x80,0xbc,0x60,0x4a,0xff,0xff,0xff,0xff,0xa1,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0x68,0x40,0x00,0x64,0xd8,0xfb,0x66,0x60,0xd4,0x62,0x17,0x60,0x52,0x7c, -0xa2,0xd3,0x99,0xff,0xe0,0x84,0x40,0xd1,0x00,0x63,0x64,0x40,0x01,0x26,0x10,0x63, -0xdd,0xfd,0x00,0x65,0x64,0x40,0x02,0x26,0x04,0x65,0x3c,0x44,0xfb,0xb4,0xb4,0x84, -0x40,0x5c,0x98,0xff,0x26,0x44,0x7f,0xfb,0x02,0x7f,0x99,0xfb,0x05,0x64,0x9a,0xfb, -0xff,0xff,0xdf,0xfe,0x19,0xff,0x24,0x60,0x28,0x64,0x9b,0xfb,0x9c,0xf3,0x69,0x65, -0xb4,0x84,0x99,0xff,0x40,0x51,0x98,0xff,0xf8,0x60,0x89,0x78,0xff,0xff,0x65,0xf3, -0xff,0xff,0x02,0xbc,0x65,0xfb,0x25,0x43,0x24,0x60,0x9d,0x78,0xff,0xff,0x20,0x44, -0x43,0x45,0x20,0xbc,0x40,0x40,0x65,0xf3,0xff,0xff,0x60,0x40,0x80,0x2a,0x03,0x00, -0x24,0x60,0x55,0x78,0xff,0xff,0x00,0xee,0x04,0xbc,0x65,0xfb,0xff,0xff,0xdf,0xfe, -0x19,0xff,0xff,0xff,0x99,0xff,0x00,0x6b,0x3c,0x44,0x40,0xb4,0x80,0xbc,0x40,0x5c, -0x00,0xed,0x04,0xee,0xff,0xff,0xff,0xff,0x00,0xee,0x98,0xff,0x00,0x64,0x65,0xfb, -0x55,0x60,0xfc,0xe0,0xff,0xff,0xff,0xff,0x25,0x43,0x24,0x60,0x9d,0x78,0xff,0xff, -0x24,0x60,0x9d,0x78,0xff,0xff,0x20,0x44,0x20,0xbc,0x40,0x40,0x24,0x60,0x9d,0x78, -0xff,0xff,0x99,0xff,0x3c,0x44,0x7f,0xb4,0x10,0xbc,0x40,0x5c,0x98,0xff,0x99,0xff, -0x3d,0x44,0x10,0xbc,0x00,0x7f,0x40,0x5d,0x98,0xff,0x99,0xff,0x3e,0x44,0x02,0xbc, -0x00,0x7f,0x40,0x5e,0x98,0xff,0x24,0x60,0x9d,0x78,0xff,0xff,0x20,0x44,0x20,0xbc, -0x40,0x40,0x80,0xe1,0x01,0x64,0xd8,0xfb,0xd7,0xf3,0xff,0xff,0xff,0xff,0x01,0x26, -0xfb,0x00,0x64,0x47,0x3f,0xb4,0xe0,0x85,0x64,0x44,0x80,0x2b,0x09,0x00,0x00,0x7f, -0x60,0x48,0x65,0x44,0x80,0xbc,0x60,0x4a,0xff,0xff,0xff,0xff,0x0b,0x16,0xfe,0x00, -0x65,0x49,0xff,0xff,0xff,0xff,0xa1,0xff,0x00,0x64,0x68,0x5e,0x60,0x5c,0x08,0x60, -0x0a,0x64,0xa0,0xd9,0x00,0x64,0xd8,0xfb,0x9c,0xf3,0x69,0x65,0xb4,0x84,0x99,0xff, -0x40,0x51,0x98,0xff,0x00,0x64,0xbf,0xdb,0x20,0x44,0x20,0x2a,0x07,0x00,0x07,0xb4, -0x04,0x36,0xc3,0xfe,0x06,0x36,0xcc,0xfe,0x07,0x36,0xd8,0xfe,0x20,0x44,0xd8,0xb4, -0x40,0x40,0x20,0x44,0x40,0x2a,0x08,0x00,0x9f,0xfe,0xff,0xff,0x24,0x05,0xbf,0xb4, -0x40,0x40,0x9b,0xf7,0xff,0xff,0xff,0xff,0x3c,0x60,0x8e,0x62,0xa2,0xd3,0xda,0x83, -0x00,0xa8,0x02,0x61,0x1b,0x02,0xdb,0x82,0x5a,0xd3,0xda,0x83,0x00,0xa8,0x02,0x61, -0x15,0x02,0xdb,0x82,0x5a,0xd3,0xda,0x83,0x00,0xa8,0x04,0x61,0x0f,0x02,0xdb,0x82, -0x5a,0xd3,0xda,0x83,0x00,0xa8,0x06,0x61,0x09,0x02,0xdb,0x82,0x5a,0xd3,0xda,0x83, -0x00,0xa8,0x07,0x61,0x03,0x02,0xf8,0x60,0x89,0x78,0xff,0xff,0xa3,0xd1,0x40,0x44, -0x62,0x43,0x20,0x44,0x07,0xb5,0xd4,0x85,0x35,0x80,0x24,0x45,0x13,0x60,0x32,0x64, -0x44,0xd7,0xff,0xff,0xff,0xff,0x80,0xe1,0x43,0x45,0x20,0x44,0x20,0xbc,0x40,0x40, -0x64,0x43,0xbd,0xd3,0xbd,0xd1,0xff,0xff,0x10,0x2b,0x01,0x00,0x0b,0x00,0x01,0x16, -0xfe,0x00,0x64,0x49,0xff,0xff,0xff,0xff,0xff,0xff,0xa1,0xff,0xff,0xff,0x68,0x44, -0x00,0x7f,0xa3,0xdb,0x25,0x43,0x98,0x00,0x80,0xe1,0x43,0x45,0x20,0x44,0x20,0xbc, -0x40,0x40,0x64,0x43,0xbd,0xd3,0xbd,0xd1,0x40,0x44,0x10,0x2b,0x01,0x00,0x1a,0x00, -0xa3,0xd3,0xff,0xff,0x01,0x16,0xfe,0x00,0x60,0x48,0x64,0x44,0x00,0x7f,0x60,0x4a, -0xff,0xff,0xff,0xff,0xff,0xff,0xa1,0xff,0xff,0xff,0x68,0x40,0x01,0x16,0xfe,0x00, -0x64,0x49,0xff,0xff,0xff,0xff,0xff,0xff,0xa1,0xff,0xff,0xff,0x68,0x45,0xd4,0x80, -0xff,0xff,0xe8,0x02,0x25,0x43,0xd7,0x00,0x3c,0x60,0xac,0x61,0xa1,0xd3,0x00,0x63, -0x00,0xa8,0x59,0xd1,0x31,0x02,0x59,0xd3,0x00,0x63,0x00,0xa8,0x59,0xd1,0x2c,0x02, -0x59,0xd3,0x00,0x63,0x00,0xa8,0x59,0xd1,0x27,0x02,0x59,0xd3,0x00,0x63,0x00,0xa8, -0x59,0xd1,0x22,0x02,0x59,0xd3,0x00,0x63,0x00,0xa8,0x59,0xd1,0x1d,0x02,0x59,0xd3, -0x00,0x63,0x00,0xa8,0x59,0xd1,0x18,0x02,0x59,0xd3,0x00,0x63,0x00,0xa8,0x59,0xd1, -0x13,0x02,0x59,0xd3,0x00,0x63,0x00,0xa8,0x59,0xd1,0x0e,0x02,0x59,0xd3,0x00,0x63, -0x00,0xa8,0x59,0xd1,0x09,0x02,0xf8,0x60,0x89,0x78,0xff,0xff,0x27,0x60,0xb5,0x78, -0xff,0xff,0x27,0x60,0x8f,0x78,0xff,0xff,0x49,0xdd,0x60,0x40,0x02,0x36,0xf9,0x00, -0x03,0x36,0xf4,0x00,0x01,0x36,0x28,0x00,0x05,0x3a,0xbe,0x00,0xa4,0xd3,0x5a,0xd3, -0x9c,0x85,0xa4,0x84,0xa2,0xdb,0xb8,0x00,0x84,0xe2,0x04,0x60,0x00,0x71,0x1e,0xf3, -0x14,0xf3,0x00,0xbd,0xcc,0x84,0x08,0x03,0x14,0xfb,0x06,0x02,0x65,0x44,0x14,0xfb, -0x8a,0xff,0x80,0x60,0x00,0x75,0x88,0xff,0x73,0x44,0xce,0xfb,0x1e,0x60,0x92,0x62, -0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb,0x0a,0x02,0x1e,0x60,0x94,0x62,0xa2,0xd3, -0xff,0xff,0x01,0xa4,0xa2,0xdb,0x03,0x00,0x27,0x60,0x88,0x78,0xff,0xff,0x66,0x60, -0xb4,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xcc,0x84,0x06,0x03,0xa2,0xdb,0x04,0x02, -0x3a,0x44,0x02,0xbc,0x40,0x5a,0x3b,0xff,0x6e,0xf3,0xff,0xff,0x60,0x47,0xff,0x23, -0x05,0x00,0xcc,0x84,0x60,0x47,0xff,0x22,0x00,0x64,0x6e,0xfb,0xa4,0xf3,0xff,0xff, -0x10,0xa4,0xa4,0xfb,0x68,0xf3,0x10,0xa5,0x00,0xa0,0x73,0x41,0x49,0x03,0xd5,0x80, -0xff,0xff,0x27,0x03,0x70,0x45,0xc4,0x85,0x02,0x60,0x58,0x64,0xc4,0x84,0xa4,0xf1, -0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0x40,0x4d,0xc0,0x84, -0x60,0x41,0x73,0x45,0xd4,0x80,0xe1,0xf1,0x14,0x0d,0x64,0x44,0x00,0x36,0x30,0x00, -0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x61,0x45,0xc4,0x84,0x73,0x45,0xd4,0x80, -0xff,0xff,0x07,0x0d,0x67,0x60,0x7c,0x62,0xa2,0xd3,0xff,0xff,0xfe,0xa0,0xff,0xff, -0x1f,0x02,0xcb,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x06,0x02,0x01,0x64,0x13,0xfb, -0x00,0x64,0x68,0xfb,0xc0,0xfe,0x14,0x00,0xe3,0xf1,0x2d,0x44,0xc0,0x84,0x70,0x45, -0xd4,0x80,0xff,0xff,0x0d,0x04,0x60,0x50,0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60, -0x31,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x01,0x64,0xe4,0xfb, -0x66,0x60,0xb2,0x64,0xa0,0xd3,0xff,0xff,0x00,0xa0,0xcc,0x84,0x12,0x03,0xa2,0xdb, -0x10,0x02,0xe0,0xf3,0x76,0xf3,0x60,0x45,0x77,0xf3,0xd4,0x80,0xd4,0x80,0x01,0x03, -0x08,0x02,0x28,0x60,0x60,0x62,0x80,0x64,0xa2,0xdb,0xff,0xff,0xc0,0xfe,0x00,0x64, -0xa2,0xdb,0x3d,0x60,0x1a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x0c,0x03, -0xcc,0x84,0xa2,0xdb,0x09,0x02,0x3d,0x60,0x16,0x63,0xbd,0xd1,0x18,0x60,0xc8,0x64, -0xa0,0xd3,0xff,0xff,0xd0,0x84,0xa3,0xdb,0x32,0x44,0x01,0x2a,0x30,0x00,0x68,0x60, -0xd4,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff,0x3b,0x02,0x68,0x60,0xda,0x61, -0xa1,0xd3,0xff,0xff,0xcc,0x84,0xff,0xff,0xa1,0xdb,0x33,0x02,0x20,0x40,0x40,0x2a, -0x03,0x00,0x01,0x64,0xa1,0xdb,0x2d,0x00,0xff,0x64,0xa1,0xdb,0x7f,0xf3,0xff,0xff, -0x01,0xa4,0x7f,0xfb,0xf2,0xa0,0xff,0xff,0x02,0x06,0x01,0x64,0x7f,0xfb,0x60,0x41, -0x20,0x44,0x40,0xbc,0x40,0x40,0x24,0x60,0xbd,0x64,0x9b,0xfb,0x61,0x44,0x02,0x7f, -0x99,0xfb,0x05,0x64,0x9a,0xfb,0xff,0xff,0xdf,0xfe,0x19,0xff,0x12,0x00,0x95,0xf3, -0x65,0xf3,0x00,0xa0,0xff,0xff,0x0d,0x03,0x02,0x2a,0x0b,0x00,0x16,0x60,0xbc,0x62, -0xa2,0xd3,0x7f,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x03,0x03,0x20,0x40,0x40,0x2a, -0xd8,0x00,0x67,0x60,0x7c,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xcc,0x84,0x31,0x03, -0xa2,0xdb,0x2f,0x02,0x01,0x64,0xe2,0xfb,0x99,0xff,0x3c,0x44,0x40,0xbc,0x00,0x7f, -0x40,0x5c,0x98,0xff,0x68,0x60,0xcc,0x62,0x80,0x60,0x61,0x64,0xa2,0xdb,0x22,0xf3, -0xff,0xff,0x01,0xb4,0xff,0xff,0x06,0x03,0x67,0x60,0x8e,0x64,0xa0,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0xe1,0xf3,0xe3,0xf1,0x60,0x47,0xe0,0x84,0xe0,0x84,0xc0,0x84, -0x70,0x45,0xd4,0x80,0xff,0xff,0x0d,0x04,0x60,0x50,0x60,0x45,0x68,0x60,0xcc,0x62, -0x80,0x60,0x31,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x00,0x64, -0xe4,0xfb,0x67,0x60,0x7e,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xcc,0x84,0x16,0x03, -0xa2,0xdb,0x14,0x02,0x00,0x64,0xe2,0xfb,0x99,0xff,0x3c,0x44,0xbf,0xb4,0x00,0x7f, -0x40,0x5c,0x98,0xff,0x68,0x60,0xcc,0x62,0x80,0x60,0x60,0x64,0xa2,0xdb,0x67,0x60, -0x7c,0x63,0xe1,0xf3,0x80,0xf3,0x60,0x45,0xd4,0x84,0xa3,0xdb,0x67,0x60,0x8c,0x62, -0xa2,0xd3,0xff,0xff,0x00,0xa0,0xcc,0x84,0x10,0x03,0xa2,0xdb,0x04,0x60,0x00,0x65, -0x70,0x44,0xc4,0x84,0x60,0x50,0x60,0x45,0x68,0x60,0xcc,0x62,0x80,0x60,0x32,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0xe1,0xf3,0xff,0xff,0x00,0xa0, -0xff,0xff,0x31,0x02,0x28,0x44,0xcc,0x84,0x40,0x48,0x2d,0x02,0x67,0x60,0x50,0x62, -0xa2,0xd3,0xff,0xff,0xff,0xff,0x03,0x22,0x03,0x00,0x01,0x2a,0x1a,0x00,0x07,0x00, -0x67,0x60,0x4c,0x62,0xa2,0xd3,0xff,0xff,0x01,0xac,0xa2,0xdb,0x12,0x03,0x99,0xff, -0x3c,0x44,0x40,0xbc,0x00,0x7f,0x40,0x5c,0x98,0xff,0xcb,0xf3,0x0a,0x65,0xfc,0xa0, -0xfd,0xa0,0x10,0x03,0x0f,0x03,0xfb,0xa0,0xff,0xff,0x0c,0x03,0x01,0x60,0xf4,0x65, -0x09,0x00,0x99,0xff,0x3c,0x44,0xbf,0xb4,0x40,0x5c,0x67,0x60,0x4a,0x62,0xa2,0xd3, -0x98,0xff,0x60,0x45,0x45,0x48,0x2b,0x44,0xcc,0x84,0x40,0x4b,0x40,0x02,0x03,0x60, -0xe8,0x64,0x40,0x4b,0x2c,0x44,0xcc,0x84,0x40,0x4c,0x05,0x02,0x1e,0x64,0x4b,0xf3, -0x40,0x4c,0xdc,0x84,0x4b,0xfb,0xcb,0xf3,0xff,0xff,0xfc,0xa0,0xfd,0xa0,0x07,0x03, -0x06,0x03,0xfb,0xa0,0xff,0xff,0x03,0x03,0x05,0x60,0xdc,0x64,0x24,0x00,0x5a,0x60, -0x74,0x63,0xa3,0xd1,0x59,0x60,0xec,0x62,0xa2,0xd3,0xff,0xff,0xc0,0x83,0x67,0x60, -0x44,0x62,0xa2,0xd1,0xa2,0xdd,0xd3,0x84,0xff,0xff,0xfe,0x27,0x13,0x00,0x01,0x27, -0x0f,0x00,0xc0,0x26,0x0b,0x00,0x30,0x26,0x07,0x00,0x0f,0x26,0x03,0x00,0x03,0x60, -0xde,0x64,0x09,0x00,0xf0,0x64,0x07,0x00,0x73,0x64,0x05,0x00,0x38,0x64,0x03,0x00, -0x1e,0x64,0x01,0x00,0x0f,0x64,0x60,0x5c,0x67,0x60,0x4a,0x62,0xa2,0xd9,0x01,0x60, -0x3a,0x61,0xa1,0xd3,0x61,0x43,0x00,0xa8,0x60,0x41,0x03,0x02,0xf8,0x60,0x89,0x78, -0xff,0xff,0x59,0xd3,0x00,0x66,0x00,0xa8,0xcc,0x84,0x02,0x03,0xa1,0xdb,0xf6,0x00, -0x49,0xd3,0xa3,0xdb,0x00,0xa8,0x60,0x43,0x5b,0xd3,0x06,0x03,0x00,0xa8,0xcc,0x84, -0x02,0x02,0x01,0x66,0x01,0x00,0xa3,0xdb,0x06,0xa1,0xa1,0xd3,0x59,0xd1,0x60,0x45, -0xa5,0xd3,0x59,0xd1,0xb0,0x84,0xa5,0xdb,0x64,0x47,0x06,0x36,0xcd,0xfe,0x07,0x37, -0xd9,0xfe,0x66,0x40,0x00,0x3a,0xd3,0x00,0xf8,0x60,0x89,0x78,0xff,0xff,0x01,0x60, -0x3a,0x61,0x00,0x64,0xa1,0xdb,0x25,0x60,0x2d,0x78,0xff,0xff,0x27,0x60,0x94,0x64, -0x40,0x41,0x44,0x42,0x24,0x00,0x01,0x60,0x3a,0x66,0xa6,0xd3,0x04,0xa1,0x60,0x43, -0xa1,0xd3,0xc9,0x81,0x60,0x45,0x00,0xbb,0xa1,0xdb,0xbe,0xd3,0x09,0x03,0xd4,0x84, -0x9c,0x84,0xdc,0x84,0xff,0xff,0x04,0x0e,0xa3,0xd1,0x63,0x46,0x64,0x43,0xf2,0x00, -0x9c,0x84,0xdc,0x85,0x49,0xdd,0x61,0x44,0x00,0xbb,0xa6,0xdb,0x02,0x03,0x65,0x44, -0xbe,0xdb,0x25,0x60,0x2d,0x78,0xff,0xff,0x25,0x60,0x2d,0x64,0x40,0x41,0x01,0x60, -0x3a,0x66,0xa6,0xd3,0xff,0xff,0x00,0xa8,0xd0,0x80,0x10,0x03,0x02,0x03,0x60,0x46, -0xf8,0x00,0x58,0xd3,0xa4,0xd3,0x60,0x45,0x00,0x63,0xa4,0xdd,0x58,0xd3,0x02,0xa8, -0xc4,0x83,0x01,0x03,0xa2,0xdd,0x62,0x44,0xc8,0x84,0xa6,0xdb,0x21,0x58,0x22,0x41, -0x28,0x60,0xaa,0x63,0x00,0x64,0xa3,0xdb,0x06,0xa3,0x1f,0x60,0x1a,0x64,0xbd,0xdb, -0xbd,0xdb,0x06,0x64,0xa3,0xdb,0x1f,0x60,0x18,0x62,0x58,0x60,0xd2,0x64,0xa2,0xdb, -0x1e,0x60,0xea,0x62,0x52,0x60,0x85,0x64,0xa2,0xdb,0x2f,0x58,0xff,0xff,0x28,0x60, -0x92,0x63,0x00,0x64,0xa3,0xdb,0x06,0xa3,0x1f,0x60,0x12,0x64,0xbd,0xdb,0xbd,0xdb, -0x06,0x64,0xa3,0xdb,0x1f,0x60,0x10,0x62,0x5c,0x60,0x14,0x64,0xa2,0xdb,0x1e,0x60, -0xea,0x62,0x52,0x60,0x85,0x64,0xa2,0xdb,0x2f,0x58,0xff,0xff,0x00,0x60,0x7a,0x66, -0x32,0x64,0x61,0xfb,0x1e,0x60,0x92,0x64,0xa0,0xd3,0x03,0xfa,0x0f,0x4e,0x00,0x60, -0x3c,0x61,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff, -0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe, -0x0e,0x4f,0x66,0x44,0x7b,0xfb,0x00,0x64,0x28,0xfa,0x01,0x60,0x48,0x64,0x29,0xfa, -0x00,0x64,0x38,0xfa,0x28,0x60,0x9e,0x63,0x00,0x64,0xa3,0xdb,0x06,0xa3,0x1f,0x60, -0x16,0x64,0xbd,0xdb,0x02,0x64,0xbd,0xdb,0x06,0x64,0xa3,0xdb,0x1f,0x60,0x14,0x62, -0x64,0x60,0x3f,0x64,0xa2,0xdb,0x1e,0x60,0xf0,0x62,0x64,0x60,0x4a,0x64,0xa2,0xdb, -0x2f,0x58,0xff,0xff,0x0f,0x4e,0x00,0x60,0x48,0x61,0x41,0x4d,0x40,0xa1,0xa2,0xff, -0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60, -0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x66,0x44,0x7a,0xfb,0x08,0x64, -0x28,0xfa,0xff,0x60,0xff,0x64,0x2b,0xfa,0x2c,0xfa,0x2d,0xfa,0xff,0xff,0x31,0xfa, -0x32,0xfa,0x33,0xfa,0x12,0x60,0x20,0x64,0x0e,0xfa,0x28,0x60,0x62,0x63,0x00,0x64, -0xa3,0xdb,0x06,0xa3,0x1e,0x60,0xf6,0x64,0xbd,0xdb,0x04,0x64,0xbd,0xdb,0x06,0x64, -0xa3,0xdb,0x1e,0x60,0xf4,0x62,0x56,0x60,0x3d,0x64,0xa2,0xdb,0x28,0x60,0x6e,0x63, -0x00,0x64,0xa3,0xdb,0x06,0xa3,0x1e,0x60,0xfa,0x64,0xbd,0xdb,0x08,0x64,0xbd,0xdb, -0x06,0x64,0xa3,0xdb,0x1e,0x60,0xf8,0x62,0x56,0x60,0x48,0x64,0xa2,0xdb,0x1e,0x60, -0xe8,0x62,0x56,0x60,0x2d,0x64,0xa2,0xdb,0x2f,0x58,0xff,0xff,0x28,0x60,0x7a,0x63, -0x00,0x64,0xa3,0xdb,0x06,0xa3,0x1f,0x60,0x0a,0x64,0xbd,0xdb,0xbd,0xdb,0x06,0x64, -0xa3,0xdb,0x1f,0x60,0x08,0x62,0x52,0x60,0x9f,0x64,0xa2,0xdb,0x1e,0x60,0xea,0x62, -0x52,0x60,0x85,0x64,0xa2,0xdb,0x2f,0x58,0xff,0xff,0x00,0x64,0x40,0x40,0x0f,0x4e, -0x00,0x60,0x6c,0x61,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78, -0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff, -0x08,0xfe,0x0e,0x4f,0x66,0x44,0x79,0xfb,0x0f,0x4e,0x00,0x60,0x6c,0x61,0x41,0x4d, -0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03, -0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x66,0x44, -0x78,0xfb,0x0f,0x4e,0x00,0x60,0x3c,0x61,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60, -0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f, -0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x66,0x44,0x77,0xfb,0x08,0x64,0x28,0xfa, -0xf0,0x60,0x20,0x64,0x0e,0xfa,0x00,0x64,0x38,0xfa,0x00,0x60,0x90,0x64,0x29,0xfa, -0x0f,0x4e,0x00,0x60,0xab,0x61,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f, -0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78, -0xff,0xff,0x08,0xfe,0x0e,0x4f,0x66,0x44,0x76,0xfb,0x08,0x64,0x28,0xfa,0x18,0x60, -0x20,0x64,0x0e,0xfa,0x00,0x60,0x80,0x64,0x29,0xfa,0x00,0x64,0x19,0xfa,0x1e,0x60, -0xec,0x62,0x43,0x60,0x6e,0x64,0xa2,0xdb,0x2f,0x58,0xff,0xff,0x1e,0x60,0xe4,0x62, -0x2c,0x60,0x33,0x64,0xa2,0xdb,0x28,0x60,0xb6,0x62,0x00,0x64,0xa2,0xdb,0x06,0xa2, -0x1e,0x60,0xfe,0x64,0xa2,0xdb,0x06,0x64,0x5a,0xdb,0x5a,0xdb,0x28,0x60,0xc2,0x62, -0x00,0x64,0xa2,0xdb,0x06,0xa2,0x1f,0x60,0x02,0x64,0xa2,0xdb,0x06,0x64,0x5a,0xdb, -0x5a,0xdb,0x28,0x60,0xce,0x62,0x00,0x64,0xa2,0xdb,0x06,0xa2,0x1f,0x60,0x06,0x64, -0xa2,0xdb,0x06,0x64,0x5a,0xdb,0x5a,0xdb,0xab,0xf1,0x28,0x60,0xd2,0x62,0xa2,0xd9, -0x1e,0x60,0xfc,0x62,0x2d,0x60,0x2a,0x64,0xa2,0xdb,0x1f,0x60,0x00,0x62,0x2d,0x60, -0x35,0x64,0xa2,0xdb,0x1f,0x60,0x04,0x62,0x2d,0x60,0x40,0x64,0xa2,0xdb,0x1e,0x60, -0xb2,0x62,0x00,0x60,0x02,0x64,0xa2,0xdb,0x29,0x60,0x53,0x64,0x5a,0xdb,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xb0,0x62,0x00,0x64,0xa2,0xdb,0x03,0x64,0x5e,0xfb, -0x2d,0x60,0x58,0x4e,0x1e,0x78,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0xff,0x60, -0x8f,0x64,0xa0,0x84,0xa2,0xdb,0xac,0xf1,0x28,0x60,0xc6,0x62,0xa2,0xd9,0x3c,0x60, -0xb6,0x62,0x28,0x60,0xc2,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x1e,0x60,0xb2,0x62,0x00,0x60,0x74,0x64,0xa2,0xdb,0x29,0x60,0x7c,0x64,0x5a,0xdb, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0x67,0x60,0x76,0x62,0xa2,0xd3,0xff,0xff,0x60,0x40, -0x02,0x2a,0x03,0x00,0x2b,0x60,0x0f,0x78,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1, -0x00,0x60,0x04,0x64,0xa0,0x80,0x9c,0x84,0x05,0x03,0xa0,0x84,0xa2,0xdb,0x2c,0x60, -0x33,0x78,0xff,0xff,0x00,0x60,0x40,0x64,0xa0,0x80,0x9c,0x84,0x03,0x03,0xa0,0x84, -0xa2,0xdb,0xd6,0x00,0x00,0x60,0x20,0x64,0xa0,0x80,0x9c,0x84,0x0e,0x03,0xa0,0x84, -0xa2,0xdb,0x01,0x65,0x2e,0x60,0x58,0x4e,0xd4,0x78,0xff,0xff,0xff,0x60,0xf7,0x65, -0x5e,0xf3,0xff,0xff,0xa4,0x84,0xa2,0xdb,0xc3,0x00,0x00,0x60,0x10,0x64,0xa0,0x80, -0x9c,0x84,0xc7,0x03,0xa0,0x84,0xa2,0xdb,0x1e,0x60,0x92,0x63,0xa3,0xd1,0x66,0x60, -0xf0,0x65,0xa5,0xd3,0xff,0xff,0xd0,0x80,0xff,0xff,0x1e,0x0d,0xad,0xf3,0xff,0xff, -0xc0,0x84,0xa5,0xdb,0x66,0x60,0xee,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x66,0x60,0xfc,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xf8,0xa0,0xff,0xff,0x01,0x04, -0x08,0x64,0xa2,0xdb,0x67,0x60,0x02,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xf8,0xa0, -0xff,0xff,0x01,0x04,0x08,0x64,0xa2,0xdb,0x66,0x60,0xf2,0x65,0xa5,0xd1,0x58,0xf3, -0xff,0xff,0xd0,0x80,0x60,0x41,0x0d,0x06,0xa5,0xdb,0x66,0x60,0xf8,0x63,0x66,0x60, -0xf6,0x65,0xa5,0xd1,0x61,0x44,0xd0,0x84,0xff,0xff,0x01,0x05,0x00,0x64,0xa3,0xdb, -0x16,0x00,0x66,0x60,0xf8,0x63,0xa3,0xd1,0x58,0xf3,0xff,0xff,0xd0,0x80,0x60,0x41, -0x0e,0x05,0xa5,0xdb,0x66,0x60,0xf6,0x65,0xa5,0xd1,0x61,0x44,0xd0,0x84,0xff,0xff, -0x01,0x05,0x00,0x64,0xa3,0xdb,0x66,0x60,0xfa,0x62,0x01,0x64,0xa2,0xdb,0x66,0x60, -0xfa,0x63,0xbd,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x2e,0x03,0xbd,0xd3,0xa3,0xd1, -0xff,0xff,0xd0,0x80,0xff,0xff,0x28,0x06,0x66,0x60,0xee,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x21,0x03,0x61,0x60,0xc8,0x62,0x06,0x64,0xa2,0xdb,0x66,0x60, -0xfa,0x63,0x00,0x64,0xbd,0xdb,0xbd,0xdb,0xa3,0xd3,0xff,0xff,0xe0,0x84,0xf8,0xa0, -0xff,0xff,0x01,0x04,0x08,0x64,0xa3,0xdb,0x66,0x60,0xf6,0x62,0xa2,0xd3,0xff,0xff, -0xe8,0x84,0xe8,0x84,0xc4,0xfb,0x66,0x60,0xe8,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x2b,0x60,0x5e,0x78,0xff,0xff,0x67,0x60,0x00,0x63,0xbd,0xd3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x49,0x03,0xbd,0xd3,0xa3,0xd1,0xff,0xff,0xd0,0x80,0xff,0xff, -0x43,0x06,0x66,0x60,0xee,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x3c,0x03, -0x66,0x60,0xf4,0x63,0xbd,0xd1,0xa3,0xd3,0xff,0xff,0xe8,0x84,0xe8,0x85,0x64,0x44, -0xd4,0x85,0x58,0xf3,0x01,0x05,0x00,0x65,0xd4,0x80,0xff,0xff,0x10,0x06,0x66,0x60, -0xf6,0x65,0xa5,0xd3,0xff,0xff,0xe8,0x84,0xc2,0xf3,0xe8,0x85,0x58,0xf3,0xc4,0x85, -0xd4,0x80,0xff,0xff,0x21,0x05,0x61,0x60,0xc8,0x62,0x08,0x64,0xa2,0xdb,0x67,0x60, -0x00,0x63,0x00,0x64,0xbd,0xdb,0xbd,0xdb,0xa3,0xd3,0xff,0xff,0xe0,0x84,0xf8,0xa0, -0xff,0xff,0x01,0x04,0x08,0x64,0xa3,0xdb,0x66,0x60,0xf6,0x62,0xa2,0xd3,0xff,0xff, -0xe8,0x84,0xe8,0x84,0xc4,0xfb,0x66,0x60,0xea,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x2b,0x60,0x5e,0x78,0xff,0xff,0xc2,0xf3,0x58,0xf1,0xff,0xff,0xd0,0x80, -0xff,0xff,0x0d,0x04,0x61,0x60,0xc8,0x62,0x06,0x64,0xa2,0xdb,0x59,0x60,0xb6,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x2b,0x60,0x5e,0x78,0xff,0xff,0x59,0x60, -0x9c,0x62,0xa2,0xd1,0xc3,0xf3,0xff,0xff,0xd0,0x80,0xff,0xff,0x0d,0x07,0x61,0x60, -0xc8,0x62,0x02,0x64,0xa2,0xdb,0x59,0x60,0xb6,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x2b,0x60,0x5e,0x78,0xff,0xff,0x66,0x60,0xba,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa0,0x60,0x45,0x0b,0x03,0x1e,0x60,0x94,0x62,0xa2,0xd3,0xff,0xff,0xd4,0x80, -0xff,0xff,0x35,0x04,0x66,0x60,0xba,0x62,0x00,0x64,0xa2,0xdb,0x66,0x60,0xb8,0x62, -0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff,0x2a,0x02,0x66,0x60,0xbc,0x62,0xa2,0xd1, -0x66,0x60,0xbe,0x63,0xa3,0xd3,0xff,0xff,0xd0,0x84,0xfe,0xa0,0xff,0xff,0x1f,0x04, -0xe0,0x84,0xe0,0x84,0xd0,0x80,0xff,0xff,0x1a,0x04,0x66,0x60,0xbc,0x62,0x64,0x44, -0x01,0xa4,0xa2,0xdb,0x1e,0x60,0x94,0x62,0x66,0x60,0xba,0x63,0xa2,0xd3,0xff,0xff, -0x03,0xa4,0xa3,0xdb,0x61,0x60,0xc8,0x62,0x04,0x64,0xa2,0xdb,0x59,0x60,0xb8,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x2b,0x60,0x5e,0x78,0xff,0xff,0x66,0x60, -0xb6,0x62,0xa2,0xd1,0x1e,0x60,0x94,0x62,0xa2,0xd3,0xff,0xff,0xd0,0x80,0xff,0xff, -0x0d,0x04,0x61,0x60,0xc8,0x62,0x04,0x64,0xa2,0xdb,0x59,0x60,0xba,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x2b,0x60,0x5e,0x78,0xff,0xff,0x67,0x60,0x76,0x62, -0xa2,0xd3,0xff,0xff,0x60,0x40,0x03,0x22,0x11,0x00,0x60,0x45,0xfd,0xb4,0xa2,0xdb, -0x20,0x44,0xb4,0x84,0x40,0x40,0x61,0x60,0xc8,0x62,0x10,0x64,0xa2,0xdb,0x59,0x60, -0xbc,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x37,0x00,0x1e,0x60,0xb2,0x62, -0x00,0x60,0x64,0x64,0xa2,0xdb,0x2b,0x60,0x32,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x00,0x60,0x04,0x64,0xa0,0x80,0x9c,0x84, -0x05,0x03,0xa0,0x84,0xa2,0xdb,0x2c,0x60,0x33,0x78,0xff,0xff,0x00,0x60,0x40,0x64, -0xa0,0x80,0x9c,0x84,0x05,0x03,0xa0,0x84,0xa2,0xdb,0x29,0x60,0xb5,0x78,0xff,0xff, -0x00,0x60,0x20,0x64,0xa0,0x80,0x9c,0x84,0xe2,0x03,0xa0,0x84,0xa2,0xdb,0x01,0x65, -0x2e,0x60,0x58,0x4e,0xd4,0x78,0xff,0xff,0xff,0x60,0xf7,0x65,0x5e,0xf3,0xff,0xff, -0xa4,0x84,0xa2,0xdb,0x29,0x60,0xb5,0x78,0xff,0xff,0xad,0xf1,0x28,0x60,0xc6,0x62, -0xa2,0xd9,0x2b,0x60,0x68,0x64,0x7c,0xfb,0x2c,0x60,0x68,0x78,0xff,0xff,0x3c,0x60, -0xb2,0x62,0x28,0x60,0xce,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x1e,0x60,0xb0,0x62,0xa2,0xd1,0xff,0x60,0xdf,0x64,0xa0,0x84,0xa2,0xdb,0x1e,0x60, -0x92,0x65,0xf4,0x56,0x7e,0x00,0x00,0x10,0x66,0x60,0xee,0x63,0x00,0x64,0xbd,0xdb, -0xa5,0xd3,0xa3,0xdb,0x61,0x60,0xc8,0x62,0xa2,0xd3,0xff,0xff,0xf0,0xa0,0xfc,0xa0, -0x08,0x03,0x13,0x02,0x66,0x60,0xb8,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff, -0x0c,0x03,0x3c,0x60,0xb2,0x62,0x28,0x60,0xc2,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb, -0xff,0xff,0x1d,0xff,0x29,0x60,0x5d,0x78,0xff,0xff,0x88,0xf1,0x27,0x60,0xe0,0x63, -0xd3,0x80,0xc4,0xf1,0x25,0x03,0x00,0x64,0xc4,0xfb,0x66,0x60,0xf4,0x65,0x58,0xf3, -0xa5,0xdb,0xa3,0xd3,0xc0,0x85,0xd4,0x80,0x5b,0xd3,0x1a,0x04,0x60,0x43,0x63,0x42, -0x06,0x65,0x46,0xd3,0x5a,0xd3,0x40,0x48,0x5a,0xd3,0x40,0x4c,0x40,0x4d,0x81,0xf3, -0x28,0x45,0xd4,0x80,0x5a,0xd3,0x09,0x02,0x2c,0x45,0xd4,0x80,0x5a,0xd3,0x05,0x02, -0x2d,0x45,0xd4,0x80,0x63,0x42,0x01,0x02,0x03,0x00,0x2c,0x60,0x2a,0x78,0xff,0xff, -0xc2,0xf1,0x58,0xf3,0xff,0xff,0xd0,0x80,0xff,0xff,0x14,0x06,0x59,0x60,0x9c,0x62, -0xa2,0xd3,0xc3,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x0c,0x05,0x3c,0x60,0xb2,0x62, -0x28,0x60,0xc2,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x29,0x60, -0x5d,0x78,0xff,0xff,0x1e,0x60,0xb2,0x62,0x00,0x60,0x74,0x64,0xa2,0xdb,0x2b,0x60, -0xeb,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1, -0x00,0x60,0x04,0x64,0xa0,0x80,0x9c,0x84,0x05,0x03,0xa0,0x84,0xa2,0xdb,0x2c,0x60, -0x33,0x78,0xff,0xff,0x00,0x60,0x40,0x64,0xa0,0x80,0x9c,0x84,0x05,0x03,0xa0,0x84, -0xa2,0xdb,0x2b,0x60,0x9b,0x78,0xff,0xff,0x00,0x60,0x20,0x64,0xa0,0x80,0x9c,0x84, -0x10,0x03,0xa0,0x84,0xa2,0xdb,0x01,0x65,0x2e,0x60,0x58,0x4e,0xd4,0x78,0xff,0xff, -0xff,0x60,0xf7,0x65,0x5e,0xf3,0xff,0xff,0xa4,0x84,0xa2,0xdb,0x2b,0x60,0x9b,0x78, -0xff,0xff,0x00,0x60,0x10,0x64,0xa0,0x80,0x9c,0x84,0xcd,0x03,0xa0,0x84,0xa2,0xdb, -0x3c,0x60,0xb2,0x62,0x28,0x60,0xce,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff, -0x1d,0xff,0x2b,0x60,0x5e,0x78,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60, -0x20,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x3c,0x60,0xb2,0x62,0x28,0x60, -0xb6,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x3c,0x60,0xb2,0x62, -0x28,0x60,0xc2,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x3c,0x60, -0xb2,0x62,0x28,0x60,0xce,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x1e,0x60,0xb0,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x00,0x64,0x5e,0xfb,0x1e,0x60, -0xa8,0x62,0xa2,0xd1,0x08,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x1e,0x60, -0xb2,0x62,0x00,0x60,0x02,0x64,0xa2,0xdb,0x29,0x60,0x53,0x64,0x5a,0xdb,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xb2,0x62,0x80,0x60,0x00,0x64,0xa2,0xdb,0x2c,0x60, -0x71,0x64,0x5a,0xdb,0xcf,0xfe,0x8c,0xf3,0xff,0xff,0xff,0xa0,0x02,0x64,0x2a,0x02, -0x8c,0xfb,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x64,0xa0,0x84,0xa2,0xdb, -0x1e,0x60,0xb2,0x62,0x80,0x60,0x00,0x64,0xa2,0xdb,0x2c,0x60,0x8a,0x64,0x5a,0xdb, -0xcf,0xfe,0xc1,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x7f,0x60, -0xff,0x64,0xa0,0x84,0xa2,0xdb,0x8c,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0xf2,0x02, -0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb, -0xa1,0x84,0x5a,0xdb,0x20,0x44,0x40,0x2a,0x10,0x00,0x20,0xbc,0x40,0x40,0x11,0x60, -0x48,0x65,0x2f,0x60,0x58,0x4e,0x23,0x78,0xff,0xff,0x3a,0x60,0x58,0x4e,0x14,0x78, -0xff,0xff,0x2f,0x60,0x58,0x4e,0x42,0x78,0xff,0xff,0x59,0x60,0x20,0x64,0x5b,0xfb, -0x1e,0x60,0xb0,0x62,0xa2,0xd1,0xef,0x60,0xff,0x64,0xa0,0x84,0xa2,0xdb,0x0f,0x4e, -0x52,0x60,0x58,0x4f,0xaa,0x78,0xff,0xff,0x0e,0x4f,0x1e,0x60,0xb2,0x62,0x10,0x60, -0x00,0x64,0xa2,0xdb,0x2c,0x60,0xce,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x20,0x44,0x20,0x2a,0x10,0x00,0xdf,0xb4,0x40,0x40,0x01,0x60,0x48,0x65,0x2f,0x60, -0x58,0x4e,0x23,0x78,0xff,0xff,0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff,0x2f,0x60, -0x58,0x4e,0x42,0x78,0xff,0xff,0x3c,0x60,0xb6,0x62,0x28,0x60,0xc2,0x64,0xa2,0xdb, -0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0xef,0x60, -0xef,0x64,0xa0,0x84,0xa2,0xdb,0x01,0x64,0x8c,0xfb,0xff,0xff,0xc1,0xfe,0x7c,0xf7, -0xff,0xff,0xff,0xff,0x59,0xf1,0x28,0x44,0xd0,0x84,0x0f,0xa4,0x03,0x0e,0xe8,0x84, -0xe8,0x84,0x04,0x00,0xe2,0xa4,0xe8,0x84,0xe8,0x87,0xf0,0xbf,0xc0,0x84,0xa2,0xdb, -0x2e,0x58,0xff,0xff,0x5a,0xf1,0x28,0x44,0xd0,0x84,0x1f,0xa4,0x06,0x0e,0xe8,0x84, -0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0x07,0x00,0xc2,0xa4,0xe8,0x84,0xe8,0x84, -0xe8,0x84,0xe8,0x84,0xe8,0x87,0xf8,0xbf,0xc0,0x84,0xa2,0xdb,0x2e,0x58,0xff,0xff, -0x5a,0xf1,0x59,0xf3,0x64,0x45,0xd4,0x84,0x80,0x65,0xc4,0x87,0x01,0x05,0x00,0x64, -0xff,0xb4,0x58,0xfb,0x2e,0x58,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x00,0x60, -0x08,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60, -0xb0,0x62,0xa2,0xd1,0x00,0x60,0x10,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x00,0x60,0x20,0x64,0xb0,0x84, -0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x2e,0x60,0xc1,0x78,0xff,0xff, -0xcb,0xf3,0xff,0xff,0x60,0x40,0x03,0x36,0x2e,0x00,0x1e,0x60,0xb2,0x62,0xa2,0xd3, -0xff,0xff,0x60,0x40,0x40,0x22,0xf1,0x00,0x66,0x60,0xb8,0x62,0xa2,0xd3,0xff,0xff, -0xff,0xa0,0xff,0xff,0x11,0x02,0x26,0x46,0x00,0xf4,0x57,0x60,0x58,0x4e,0x59,0x78, -0xff,0xff,0x66,0x60,0xbe,0x62,0xa2,0xd9,0x66,0x60,0xbc,0x63,0xa3,0xd3,0xff,0xff, -0xd0,0x80,0xff,0xff,0x01,0x06,0xa3,0xd9,0x58,0x60,0x58,0x4e,0x6c,0x78,0xff,0xff, -0x65,0x44,0x00,0xa0,0xff,0xff,0x01,0x03,0xe1,0xfb,0x00,0x65,0x2e,0x60,0x58,0x4e, -0xd4,0x78,0xff,0xff,0x09,0x00,0x6d,0xf3,0xff,0xff,0x04,0xb4,0x04,0xbc,0x03,0x03, -0x2e,0x60,0xc1,0x78,0xff,0xff,0x6d,0xfb,0x26,0x46,0x20,0xf2,0xa0,0x65,0x01,0x37, -0x50,0x65,0x02,0x37,0x1e,0x65,0x03,0x37,0x0f,0x65,0x28,0x60,0xda,0x63,0x00,0xf4, -0x02,0xf2,0xff,0xff,0xd4,0x84,0xbd,0xdb,0x03,0xf2,0x01,0x05,0xcc,0x84,0xbd,0xdb, -0x04,0xf2,0x01,0x05,0xcc,0x84,0xbd,0xdb,0x05,0xf2,0x01,0x05,0xcc,0x84,0xa3,0xdb, -0xfa,0xa3,0x26,0x46,0x00,0x60,0x00,0x65,0xa3,0xd3,0x23,0xf0,0x00,0x61,0xd0,0x84, -0xf1,0x81,0xd4,0x84,0xf1,0x81,0xbd,0xdb,0xa3,0xd3,0x03,0xb1,0x03,0xa9,0x24,0xf0, -0x42,0xfe,0x01,0x03,0xcc,0x84,0xf1,0x81,0xd0,0x84,0xf1,0x81,0xbd,0xdb,0xa3,0xd3, -0x03,0xb1,0x03,0xa9,0x27,0xf0,0x42,0xfe,0x01,0x03,0xcc,0x84,0xf1,0x81,0xd0,0x84, -0xf1,0x81,0xbd,0xdb,0xa3,0xd3,0x03,0xb1,0x03,0xa9,0x28,0xf0,0x01,0x03,0xcc,0x84, -0xd0,0x84,0xa3,0xdb,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x92,0x64,0xa2,0xdb, -0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x5e,0xf3,0xcb,0xf3,0x04,0xb0,0xff,0xff, -0x35,0x03,0x03,0x3a,0x35,0x00,0x73,0xf3,0xff,0xff,0x60,0x40,0x04,0x26,0x30,0x00, -0xa3,0xd3,0x4b,0xd1,0x4b,0xd3,0xc0,0x9c,0xc0,0x84,0x4b,0xd1,0x00,0xa0,0x03,0xa0, -0x01,0x03,0x1f,0x02,0x80,0x60,0x00,0x65,0x64,0x44,0xa4,0x85,0xe8,0x84,0xb4,0x84, -0xe8,0x84,0xb4,0x84,0xa3,0xdb,0x60,0x45,0xfa,0x64,0xd4,0x80,0xff,0x60,0x06,0x64, -0xd4,0x80,0x14,0x07,0x13,0x04,0x66,0x60,0xa0,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x4d,0xf3,0xff,0xff,0x60,0x40,0x00,0x3a,0x03,0x00,0x01,0x64,0x4d,0xfb, -0x07,0x00,0x66,0x60,0x9a,0x62,0x10,0x64,0xa2,0xdb,0x06,0x00,0x00,0x64,0x4d,0xfb, -0x01,0x64,0x23,0xfb,0xff,0xff,0x1a,0xff,0x5e,0xf3,0xff,0xff,0x04,0xb0,0x08,0xb0, -0x06,0x03,0x7e,0x02,0x5f,0xf3,0xff,0xff,0xff,0xa4,0x5f,0xfb,0x7b,0x02,0x26,0x46, -0x00,0xf4,0x02,0xf2,0x5a,0xd2,0x40,0x48,0x40,0x4c,0x5a,0xd2,0x5a,0xd2,0x40,0x4d, -0x60,0x41,0x5a,0xd0,0x80,0xf9,0x40,0x63,0xad,0x80,0xf0,0xa3,0x09,0x02,0x3c,0x03, -0x2d,0x41,0x2c,0x44,0x40,0x4d,0x28,0x44,0x40,0x4c,0x00,0x64,0x40,0x48,0xf4,0x00, -0xd1,0x80,0x01,0x02,0x31,0x04,0x10,0xa3,0x80,0x60,0x00,0x65,0xa5,0x80,0xcf,0x83, -0x08,0x02,0x28,0x44,0x60,0x88,0x2c,0x44,0x70,0x8c,0x2d,0x44,0x70,0x8d,0xf1,0x81, -0xf5,0x00,0xe7,0xa3,0x64,0x44,0x00,0xa0,0x00,0x62,0x02,0x02,0x00,0x61,0x1c,0x00, -0xe0,0x84,0xde,0x82,0xfd,0x04,0x42,0xfe,0xf8,0x84,0x62,0x45,0xc7,0x83,0x60,0x45, -0x02,0xfe,0xd5,0x84,0x02,0x05,0x01,0x05,0x61,0x44,0xcf,0x83,0x60,0x41,0x08,0x03, -0x28,0x44,0x60,0x88,0x2c,0x44,0x70,0x8c,0x2d,0x44,0x70,0x8d,0xf1,0x81,0xf1,0x00, -0xce,0x82,0xe9,0x81,0xfd,0x02,0xf1,0x81,0x02,0xf2,0xff,0xff,0x60,0x47,0xe8,0x84, -0xe8,0x84,0x5a,0xd2,0x3f,0xb5,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0xb4,0x84,0x61,0x45,0xd4,0x84,0xc0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0x60,0x53,0x80,0xf3,0x60,0x41,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0x60,0x45,0x61,0x44,0xd4,0x84,0xa4,0xfb,0x04,0x60,0x00,0x71,0x60,0x45,0x68,0x60, -0xcc,0x62,0x90,0x60,0x95,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb, -0x05,0x64,0x5f,0xfb,0x5e,0xf3,0x26,0x46,0x0c,0xbc,0xa2,0xdb,0xff,0x60,0x00,0x65, -0x25,0xf2,0xff,0xff,0x24,0x88,0x60,0x47,0x24,0x8c,0x2c,0x60,0x58,0x4e,0xf8,0x78, -0xff,0xff,0x0c,0x48,0x2d,0x60,0x58,0x4e,0x08,0x78,0xff,0xff,0x2d,0x60,0x58,0x4e, -0x1e,0x78,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x00,0x60,0x40,0x64,0xb0,0x84, -0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x3c,0x60,0xb2,0x62,0x28,0x60,0xce,0x64,0xa2,0xdb, -0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0xff,0x60, -0xdf,0x64,0xa0,0x84,0xa2,0xdb,0x26,0x46,0x2f,0x58,0xff,0xff,0x65,0x44,0x00,0xa0, -0x40,0x48,0x13,0x03,0x66,0x60,0x2a,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xf6,0xa0, -0xa2,0xdb,0x0f,0x04,0x00,0x64,0xa2,0xdb,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60, -0x40,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x66,0x60,0x2a,0x62,0x00,0x64, -0xa2,0xdb,0x66,0x60,0x2c,0x62,0xa2,0xd3,0x28,0x45,0xc4,0x84,0xa2,0xdb,0x66,0x60, -0x2e,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xce,0xa0,0xa2,0xdb,0x14,0x06,0x32,0x64, -0xa2,0xdb,0x66,0x60,0x30,0x62,0xa2,0xd1,0x66,0x60,0x32,0x64,0xc0,0x82,0xa2,0xd1, -0x66,0x60,0x2c,0x62,0xa2,0xd3,0xff,0xff,0xd0,0x84,0xa2,0xdb,0xe0,0x85,0x59,0x60, -0x9c,0x62,0x65,0x44,0xa2,0xdb,0x66,0x60,0x30,0x62,0xa2,0xd1,0x66,0x60,0x32,0x64, -0xc0,0x82,0x28,0x44,0xa2,0xdb,0x66,0x60,0x30,0x62,0x64,0x44,0x9e,0xa0,0x02,0xa4, -0x01,0x02,0x00,0x64,0xa2,0xdb,0x2e,0x58,0xff,0xff,0x7b,0xf5,0xff,0xff,0x81,0xf1, -0x2b,0xf8,0x31,0xf8,0xff,0xff,0x82,0xf1,0x2c,0xf8,0x32,0xf8,0xff,0xff,0x83,0xf1, -0x2d,0xf8,0x33,0xf8,0xff,0xff,0xbd,0xf1,0x2e,0xf8,0xbe,0xf1,0xff,0xff,0x2f,0xf8, -0xbf,0xf1,0x30,0xf8,0xff,0xff,0x00,0x64,0x22,0xfa,0x06,0x60,0x20,0x64,0x0e,0xfa, -0x65,0x44,0x29,0xfa,0x2e,0x58,0xff,0xff,0x66,0x60,0xcc,0x62,0x2e,0x44,0xa2,0xdb, -0x1e,0x60,0xb0,0x62,0x00,0x64,0xa2,0xdb,0x3c,0x60,0x82,0x62,0x3c,0x60,0x2e,0x64, -0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xc1,0xfe, -0x1e,0x60,0xb2,0x62,0x00,0x60,0x01,0x64,0xa2,0xdb,0x2f,0x60,0x61,0x64,0x5a,0xdb, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0xff,0x60,0xfe,0x61, -0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0x66,0x60,0xcc,0x62,0xa2,0xd3, -0xff,0xff,0x40,0x4e,0x2e,0x58,0xff,0xff,0x27,0x42,0xa2,0xd3,0xa2,0xd1,0xac,0x86, -0x0e,0xf2,0x57,0x03,0x60,0x40,0x02,0x2a,0x54,0x00,0x0b,0xf2,0xff,0xff,0x00,0xa4, -0x44,0x45,0x39,0x02,0x21,0x44,0xf7,0xa0,0xff,0xff,0x35,0x07,0x5c,0x81,0x22,0x44, -0x00,0x7c,0xd0,0x80,0xff,0xff,0x01,0x02,0x46,0x42,0x48,0xf3,0xff,0xff,0x60,0x41, -0x02,0xfa,0x40,0xa1,0x7c,0x63,0x84,0xa1,0x00,0xf2,0x03,0x06,0x01,0xfc,0x60,0x46, -0xfa,0x00,0x80,0x60,0x7c,0x64,0x01,0xfa,0x66,0x43,0x25,0x46,0x05,0xfc,0x06,0xfc, -0x01,0xf0,0x03,0x67,0xb0,0x84,0x00,0xf0,0x3c,0x7e,0x01,0xfa,0x04,0x64,0x03,0xfa, -0x04,0xf8,0x00,0x64,0x0b,0xfa,0x0c,0xfa,0xff,0xff,0x0e,0xfa,0x0f,0xfa,0x3c,0x60, -0x88,0x62,0x3c,0x60,0x64,0x64,0xa2,0xdb,0x25,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xb9,0x00,0x0f,0x4e,0x44,0x45,0x64,0x46,0x3c,0x60,0x88,0x62, -0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff, -0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0xd1,0xfe,0x0e,0x4f, -0xa3,0x00,0x2f,0x58,0xff,0xff,0x3c,0x60,0x6a,0x64,0x40,0x47,0x58,0x4f,0x9c,0x00, -0x3c,0x60,0x46,0x64,0x40,0x47,0x58,0x4f,0x08,0x00,0x3c,0x60,0x70,0x64,0x40,0x47, -0x58,0x4f,0x03,0x00,0x30,0x60,0x7f,0x78,0xff,0xff,0x27,0x42,0xa2,0xd3,0xa2,0xd1, -0xac,0x86,0x0e,0xf2,0x46,0x03,0x60,0x40,0x02,0x2a,0x43,0x00,0x95,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x28,0x03,0x3c,0x60,0x46,0x64,0x27,0x45,0xd4,0x80,0xff,0xff, -0x22,0x02,0x00,0x64,0x13,0xfb,0x22,0xf2,0xff,0xff,0xff,0xff,0x10,0x26,0x0f,0x00, -0x1c,0xf2,0xff,0xff,0x03,0xb4,0xff,0xff,0x00,0x36,0x15,0x00,0x01,0x36,0x13,0x00, -0x02,0x36,0x05,0x00,0x22,0xf2,0xff,0xff,0x00,0xa8,0xff,0xff,0x0c,0x03,0x3c,0x60, -0x88,0x62,0x3c,0x60,0x40,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0x16,0x00,0x0f,0x4e,0x44,0x45,0x64,0x46,0x3c,0x60,0x88,0x62, -0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff, -0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0xd1,0xfe,0x0e,0x4f, -0xb4,0x00,0x2f,0x58,0xff,0xff,0x02,0x64,0x01,0x00,0x01,0x64,0x40,0x55,0x3b,0xff, -0x48,0x00,0xb2,0xfe,0xff,0xff,0xf9,0x05,0xb3,0xfe,0xff,0xff,0xf4,0x05,0xb0,0xfe, -0xff,0xff,0x91,0x05,0xb1,0xfe,0xff,0xff,0x26,0x05,0x3b,0x00,0x48,0xf1,0x0f,0x4e, -0x64,0x41,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff, -0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe, -0x0e,0x4f,0x26,0x03,0x3c,0x60,0x88,0x62,0x3c,0x60,0x64,0x64,0xa2,0xdb,0x66,0x44, -0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x22,0x41,0x00,0xb9,0x21,0x44, -0x08,0x24,0x46,0x42,0x5c,0x81,0x3e,0x41,0x22,0x44,0x00,0xb9,0xac,0x86,0x09,0x02, -0xd5,0x03,0x31,0x40,0x01,0x2a,0x05,0x00,0x09,0xf0,0x02,0x5e,0x44,0x42,0x21,0x44, -0x4c,0x81,0x96,0xf3,0x21,0x45,0xd4,0x80,0xff,0xff,0xc8,0x07,0x58,0x4f,0x04,0x00, -0x00,0x00,0xa1,0xff,0xff,0xff,0xbe,0x3f,0x3c,0x60,0x34,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa8,0x60,0x46,0x40,0x03,0x46,0x48,0x03,0x60,0x3c,0x64,0x01,0xfa,0x02,0xf0, -0x0f,0x4e,0x64,0x41,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78, -0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff, -0x08,0xfe,0x0e,0x4f,0x76,0x03,0x3c,0x60,0x88,0x62,0x3c,0x60,0x3a,0x64,0xa2,0xdb, -0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x00,0xf2,0x00,0x63, -0x00,0xfc,0x05,0xf0,0x06,0xfc,0x66,0x43,0x05,0xfc,0x28,0x46,0x00,0xfa,0x04,0xfa, -0x04,0x64,0x03,0xfa,0x05,0xf8,0x06,0xf8,0x08,0x64,0x0e,0xfa,0x3c,0x60,0x88,0x62, -0x3c,0x60,0x40,0x64,0xa2,0xdb,0x28,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0xd1,0xfe,0x4b,0x00,0x20,0x44,0x01,0x2a,0x4b,0x00,0x02,0x2a,0x22,0x00, -0x0f,0x4e,0x00,0x60,0x3c,0x61,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60,0x58,0x4f, -0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f,0xc4,0x78, -0xff,0xff,0x08,0xfe,0x0e,0x4f,0x35,0x03,0x3c,0x60,0x88,0x62,0x3c,0x60,0x3a,0x64, -0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x20,0x44, -0xfd,0xb4,0x40,0x40,0x91,0xf1,0x0f,0x4e,0x64,0x41,0x41,0x4d,0x40,0xa1,0xa2,0xff, -0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60, -0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x13,0x03,0x3c,0x60,0x88,0x62, -0x3c,0x60,0x40,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0x08,0x64,0x0e,0xfa,0x20,0x44,0xfe,0xb4,0x40,0x40,0x04,0x64,0x40,0x55, -0x3b,0xff,0x2f,0x58,0xff,0xff,0xb8,0xfe,0xff,0xff,0x02,0x24,0x97,0xf7,0xff,0xff, -0xff,0xff,0xba,0xfe,0xff,0xff,0x05,0x05,0xb9,0xfe,0xbb,0xfe,0x30,0x60,0x7f,0x78, -0xff,0xff,0x36,0x44,0x00,0x7f,0xfc,0xa0,0x60,0x45,0x05,0x05,0x0e,0x60,0xd4,0x64, -0x44,0xd7,0xff,0xff,0xff,0xff,0x30,0x60,0x7f,0x78,0xff,0xff,0x7f,0x60,0xc0,0x64, -0x24,0x45,0xa4,0x80,0x7f,0x67,0x02,0x61,0x13,0x02,0x20,0x44,0x01,0x2a,0x03,0x00, -0x7f,0x67,0x07,0x61,0x0d,0x00,0x48,0xf1,0x25,0x44,0x64,0x45,0x91,0xfb,0xd4,0x80, -0x7f,0x67,0x05,0x61,0x05,0x07,0x20,0x44,0x03,0xbc,0x40,0x40,0xd1,0xfe,0x00,0x67, -0x23,0x58,0xff,0xff,0x24,0x44,0x36,0x60,0x58,0x4f,0x2b,0x78,0xff,0xff,0x03,0x61, -0x03,0x03,0x31,0x60,0xfa,0x78,0xff,0xff,0x24,0x44,0x40,0xb0,0xff,0xff,0x48,0x03, -0x25,0x46,0x66,0x5c,0xd1,0xf9,0x0e,0xf0,0xff,0xff,0x64,0x40,0x08,0x2a,0x1f,0x00, -0x3c,0x60,0x3a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x18,0x03,0x0f,0x4e, -0x46,0x45,0x3c,0x60,0x88,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64, -0x5a,0xdb,0xff,0xff,0x2b,0xff,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff, -0xa3,0xff,0xd1,0xfe,0x0e,0x4f,0x0e,0xf2,0xff,0xff,0xf7,0xb4,0x0e,0xfa,0xd1,0xf5, -0x22,0xf0,0xff,0x60,0xef,0x64,0xa0,0x84,0xa2,0xda,0x00,0x64,0x1c,0xfa,0x3c,0x60, -0x88,0x62,0x3c,0x60,0x46,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0x0e,0xf2,0xff,0xff,0x02,0xbc,0x0e,0xfa,0x3c,0x60,0x46,0x64, -0x40,0x47,0x2f,0x60,0x58,0x4f,0xe3,0x78,0xff,0xff,0x32,0x60,0xf0,0x78,0xff,0xff, -0x59,0x60,0xe4,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82, -0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x25,0x46,0x3c,0x60,0x28,0x65,0x08,0xf2, -0xff,0xff,0xd4,0x80,0x03,0x61,0x40,0x03,0x3c,0x60,0x88,0x62,0x00,0x64,0xa2,0xdb, -0x25,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x28,0xf0,0xfd,0x7f, -0x04,0x7e,0x64,0x40,0x02,0x26,0x40,0xbc,0x0e,0xf0,0x64,0x40,0x04,0x26,0x80,0xbc, -0xc0,0x22,0xff,0x7f,0x64,0x40,0x08,0x26,0x08,0xbc,0x0e,0xfa,0x3f,0xf0,0xff,0xff, -0x28,0xf2,0x38,0xf2,0x60,0x41,0x08,0x2a,0x64,0x47,0x38,0xfa,0x60,0x45,0x49,0xf3, -0x00,0x63,0xd4,0x80,0x22,0xfc,0x01,0x04,0x07,0x00,0x22,0xf0,0x08,0x64,0xb0,0x84, -0xa2,0xda,0x32,0x60,0x08,0x78,0xff,0xff,0x39,0x60,0x58,0x4f,0x90,0x78,0xff,0xff, -0x05,0x04,0x22,0xf0,0x04,0x64,0xb0,0x84,0xa2,0xda,0x14,0x00,0x32,0x60,0x58,0x4f, -0xf5,0x78,0xff,0xff,0x05,0x61,0x03,0x04,0x32,0x60,0xf2,0x78,0xff,0xff,0x25,0x46, -0xcb,0xf3,0x95,0xf3,0xfe,0xa0,0x00,0xa0,0x05,0x07,0x04,0x02,0x22,0xf0,0x04,0x64, -0xb0,0x84,0xa2,0xda,0x24,0x44,0x01,0x2b,0x3a,0x00,0x02,0x27,0x38,0x00,0x3c,0x60, -0x3a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x46,0x48,0x10,0x63,0x25,0x46, -0xbf,0xd0,0x28,0x46,0xff,0xd8,0x25,0x46,0xfb,0x1d,0x64,0x44,0x00,0xa8,0x28,0x44, -0x03,0x02,0x28,0x46,0x05,0xfa,0x06,0xfa,0x16,0x63,0x6a,0x61,0x25,0x46,0xa3,0xd0, -0x28,0x46,0xc9,0x81,0xbd,0xd8,0xfa,0x02,0x0e,0xf0,0xff,0x60,0xfc,0x64,0xa0,0x84, -0x0e,0xfa,0x00,0x64,0x0f,0xfa,0x00,0x64,0x25,0x46,0x00,0xfa,0x66,0x44,0x05,0xfa, -0x3c,0x60,0x88,0x62,0x3c,0x60,0x34,0x64,0xa2,0xdb,0x25,0x44,0x5a,0xdb,0x0a,0x64, -0x5a,0xdb,0xff,0xff,0x2b,0xff,0xd1,0xfe,0x00,0x64,0x0e,0xfa,0x28,0x46,0x0e,0xf0, -0xff,0x60,0xfb,0x64,0xa0,0x84,0x0e,0xfa,0x22,0xf2,0x66,0x43,0x00,0xa8,0x60,0x5c, -0x08,0x60,0x0a,0x64,0xa0,0xdd,0x64,0x44,0x69,0x02,0x95,0xf3,0xff,0xff,0x00,0xa0, -0xff,0xff,0x44,0x03,0x26,0x44,0x0a,0x36,0x00,0x63,0x14,0x36,0x01,0x63,0x37,0x36, -0x02,0x63,0x6e,0x36,0x03,0x63,0x13,0xfc,0x26,0x44,0xff,0x27,0x06,0x00,0x26,0xf2, -0x26,0xf2,0x60,0x45,0x60,0x47,0xd4,0x84,0x01,0x00,0x60,0x47,0xff,0x65,0xa4,0x84, -0x1d,0xfa,0x00,0x64,0x15,0xfa,0x27,0xf2,0xff,0xff,0x00,0xa0,0xff,0xff,0x15,0x02, -0x1e,0x60,0x98,0x65,0x25,0xf2,0xff,0xff,0x0f,0xb4,0xb8,0xf1,0x00,0x7f,0xd0,0x80, -0x60,0x5c,0x06,0x05,0x67,0x60,0x6e,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0xa5,0xd9,0x64,0x40,0x00,0x3a,0xb8,0xf9,0x11,0x00,0x29,0xf0,0x08,0x67,0xb0,0x84, -0xa2,0xda,0x1e,0x65,0x29,0xf2,0xff,0xff,0x60,0x40,0x03,0x2b,0x18,0x65,0x65,0x44, -0x04,0xa4,0x64,0x40,0x40,0x27,0x08,0xa4,0x21,0xfa,0x08,0x00,0x3a,0x60,0x58,0x4e, -0x14,0x78,0xff,0xff,0x3a,0x60,0x58,0x4e,0x72,0x78,0xff,0xff,0x95,0xf3,0xff,0xff, -0x00,0xa0,0x47,0xf3,0x03,0x03,0x24,0x47,0x0f,0xb4,0x02,0x00,0xe8,0x84,0xe8,0x84, -0x1c,0xfa,0x3c,0x60,0x88,0x62,0x3c,0x60,0x28,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb, -0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xc1,0xfe,0x0c,0x00,0x3c,0x60,0x88,0x62, -0x3c,0x60,0x46,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0xd3,0xfe,0x0e,0xf0,0x24,0x44,0x02,0x27,0x02,0x00,0x01,0x27,0x22,0x00, -0x64,0x40,0x08,0x2a,0x1f,0x00,0x3c,0x60,0x3a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8, -0x60,0x46,0x18,0x03,0x0f,0x4e,0x46,0x45,0x3c,0x60,0x88,0x62,0x00,0x64,0xa2,0xdb, -0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xa2,0xff,0x1a,0x60, -0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0xd1,0xfe,0x0e,0x4f,0x0e,0xf2,0xff,0xff, -0xf7,0xb4,0x0e,0xfa,0x00,0x67,0x01,0x00,0x7f,0x67,0x23,0x58,0xff,0xff,0x0f,0x4e, -0x25,0x46,0x38,0xf2,0x05,0x48,0x00,0xa8,0x60,0x41,0x66,0x44,0x0a,0x03,0x00,0xf2, -0x42,0xfe,0xac,0x86,0x01,0xf2,0x1e,0x03,0x7f,0xb5,0xd5,0x81,0x66,0x44,0xf7,0x07, -0x25,0x46,0x05,0xf0,0x06,0xfa,0x05,0xfa,0xd0,0x80,0x64,0x43,0x12,0x03,0x60,0x46, -0x01,0xf0,0x80,0x67,0xb0,0x84,0x01,0xfa,0x00,0xf0,0x00,0x64,0x00,0xfa,0x64,0x46, -0x05,0xfc,0x46,0x45,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff, -0x08,0x45,0x02,0xfe,0x2e,0x58,0xff,0xff,0x20,0x44,0x40,0xb0,0x7f,0x67,0x02,0x61, -0x03,0x03,0x34,0x60,0x2d,0x78,0xff,0xff,0x00,0x64,0x24,0x45,0x80,0x26,0x01,0x64, -0x95,0xfb,0x59,0x60,0x54,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb,0x4a,0xf1, -0x43,0xf1,0x64,0x40,0x01,0x2a,0x08,0x00,0x64,0x40,0x01,0x2a,0x05,0x00,0x1e,0x60, -0xa0,0x63,0x09,0x60,0x2b,0x64,0x19,0x00,0xc7,0xf1,0x1e,0x60,0xa0,0x63,0x64,0x45, -0x80,0x27,0x19,0x00,0x64,0x44,0x00,0xac,0xff,0xff,0x0d,0x02,0x02,0x60,0x52,0x64, -0xbd,0xdb,0x03,0x60,0x1c,0x64,0xbd,0xdb,0x7f,0x60,0xff,0x64,0xbd,0xdb,0x7f,0x60, -0xff,0x64,0xbd,0xdb,0x07,0x00,0xe8,0x84,0xe0,0x84,0xbd,0xdb,0xbd,0xdb,0xbd,0xdb, -0xff,0xff,0xbd,0xdb,0x36,0x00,0x80,0x67,0x94,0x81,0x61,0x44,0xe8,0x84,0xe8,0x84, -0xe8,0x84,0xe8,0x84,0xe0,0x84,0xbd,0xdb,0x61,0x44,0xe8,0x84,0xe8,0x84,0xe8,0x84, -0xe0,0x84,0xbd,0xdb,0x0d,0x60,0x18,0x65,0x61,0x44,0xd4,0x80,0xff,0xff,0x01,0x06, -0x65,0x44,0xe0,0x85,0xc4,0x85,0xe0,0x84,0xf4,0x66,0x7e,0x00,0x00,0x10,0xe0,0x84, -0xe0,0x84,0xc4,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe0,0x84, -0xbd,0xdb,0x06,0x60,0x8c,0x65,0x61,0x44,0xd4,0x80,0xff,0xff,0x01,0x06,0x65,0x44, -0xe0,0x85,0xc4,0x85,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xc4,0x84,0xe8,0x84,0xe8,0x84, -0xe8,0x84,0xe8,0x84,0xe0,0x84,0xbd,0xdb,0x1e,0x60,0xa0,0x63,0x04,0x61,0xbd,0xd1, -0x90,0x65,0x64,0x44,0xd4,0x80,0x65,0x44,0x01,0x05,0xbf,0xdb,0x09,0x60,0x2b,0x65, -0x64,0x44,0xd4,0x80,0xcd,0x81,0x02,0x06,0x65,0x44,0xbf,0xdb,0xf0,0x02,0x00,0x61, -0x41,0x56,0xc7,0xfe,0x30,0x60,0x7f,0x78,0xff,0xff,0x36,0x47,0xff,0x23,0x06,0x00, -0x00,0x7f,0x60,0x41,0x7f,0x67,0x34,0x60,0x2d,0x78,0xff,0xff,0x99,0xff,0x00,0x60, -0x00,0xeb,0x00,0x60,0x00,0xea,0x98,0xff,0x20,0x44,0x80,0xbc,0x40,0x40,0x59,0x60, -0x6a,0x63,0xc9,0xf3,0xa3,0xdb,0x00,0x63,0x60,0x40,0x01,0x26,0x09,0x00,0x01,0xa3, -0x60,0x40,0x02,0x26,0x05,0x00,0x01,0xa3,0x60,0x40,0x04,0x26,0x01,0x00,0x01,0xa3, -0x60,0x41,0x17,0x60,0xde,0x65,0xa5,0xdd,0x61,0x44,0x08,0x2a,0x03,0x00,0x03,0x63, -0x08,0x64,0x0c,0x00,0x04,0x2a,0x03,0x00,0x02,0x63,0x04,0x64,0x07,0x00,0x02,0x2a, -0x03,0x00,0x01,0x63,0x02,0x64,0x02,0x00,0x00,0x63,0x01,0x64,0x50,0xfb,0x51,0xfd, -0x95,0xf3,0xff,0xff,0x00,0xa0,0x00,0x64,0x2d,0x03,0xa1,0xfb,0xa2,0xfb,0xa3,0xfb, -0xff,0xff,0x80,0xf3,0x88,0xff,0x00,0x75,0x00,0x72,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0x60,0x53,0xed,0xe2,0xbf,0xf3,0xff,0xff,0xff,0xb4,0x60,0x52,0x8a,0xff, -0xbd,0xf1,0x81,0xf9,0xbe,0xf1,0xff,0xff,0x82,0xf9,0xbf,0xf1,0x83,0xf9,0x17,0x60, -0xdc,0x63,0xa3,0xd3,0x00,0x65,0x60,0x40,0x02,0x26,0x01,0x65,0x60,0x40,0x04,0x26, -0x02,0x65,0x60,0x40,0x08,0x26,0x03,0x65,0x59,0x60,0x68,0x62,0x65,0x44,0xa2,0xdb, -0x00,0x67,0x10,0x00,0xc9,0xf3,0x00,0x65,0x60,0x40,0x02,0x26,0x01,0x65,0x60,0x40, -0x04,0x26,0x02,0x65,0x60,0x40,0x08,0x26,0x03,0x65,0x59,0x60,0x68,0x62,0x65,0x44, -0xa2,0xdb,0x00,0x67,0x23,0x58,0xff,0xff,0x7f,0x60,0xc0,0x64,0x24,0x45,0xa4,0x80, -0x7f,0x67,0x02,0x61,0x3a,0x02,0x59,0x60,0x56,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4, -0xa2,0xdb,0xff,0x60,0xfe,0x64,0x32,0x45,0x24,0x92,0x02,0x61,0x41,0x56,0xc7,0xfe, -0x30,0x60,0x7f,0x78,0xff,0xff,0x94,0xf1,0x20,0x44,0x64,0x40,0xff,0x26,0x24,0x00, -0x7f,0xb4,0x40,0x40,0x00,0x64,0x40,0x5e,0x3c,0x60,0x64,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa8,0x60,0x46,0x0f,0xf2,0x18,0x03,0x00,0xa8,0xff,0xff,0x15,0x03,0x0f,0x4e, -0x46,0x45,0x3c,0x60,0x88,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64, -0x5a,0xdb,0xff,0xff,0x2b,0xff,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff, -0xa3,0xff,0xd1,0xfe,0x0e,0x4f,0xe0,0x00,0x00,0x67,0x23,0x58,0xff,0xff,0x00,0x61, -0x00,0x7c,0x08,0x60,0x0a,0x64,0xa0,0xd9,0x00,0x67,0x23,0x58,0xff,0xff,0x25,0x44, -0xa0,0xd1,0x08,0x60,0x0a,0x64,0xa0,0xd9,0x00,0x67,0x23,0x58,0xff,0xff,0x7f,0x60, -0xc0,0x64,0x24,0x45,0xa4,0x80,0x02,0x61,0x25,0x02,0x25,0x45,0x12,0x60,0xfc,0x63, -0x05,0x61,0xbd,0xd3,0xbd,0xd1,0xd4,0x80,0xbd,0xd3,0xcd,0x81,0x02,0x03,0x19,0x03, -0xf8,0x00,0x40,0x4c,0x0f,0x4e,0x64,0x41,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60, -0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f, -0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x01,0x03,0x2c,0x58,0x0c,0x61,0x05,0x67, -0x02,0x00,0x04,0x61,0x7f,0x67,0x23,0x58,0xff,0xff,0x03,0x4e,0x0c,0x60,0x6e,0x62, -0xa2,0xd7,0x58,0x43,0xff,0xff,0x0e,0x43,0x41,0x47,0x7e,0x60,0xc0,0x64,0x24,0x45, -0xa4,0x80,0x02,0x61,0x26,0x02,0x25,0x45,0xfc,0x2b,0x22,0x00,0x0e,0x60,0xd8,0x63, -0x6a,0x61,0x24,0x44,0x01,0x27,0x11,0x00,0xbd,0xd3,0xa3,0xd1,0xd4,0x80,0xcd,0x81, -0x08,0x24,0x64,0x58,0x08,0xa3,0xf8,0x02,0x15,0xf5,0x22,0xf2,0xff,0xff,0x00,0xa8, -0x00,0x61,0x01,0x02,0x04,0x61,0x00,0x67,0x0d,0x00,0x27,0x40,0x04,0x3a,0xfb,0x00, -0xbd,0xd3,0xbe,0xd1,0xd4,0x80,0xcd,0x81,0x08,0x24,0x64,0x58,0x08,0xa3,0xf5,0x02, -0x04,0x61,0x7f,0x67,0x23,0x58,0xff,0xff,0x4b,0xd3,0x15,0xf5,0x60,0x41,0x22,0xf0, -0xe9,0x85,0x64,0x44,0xff,0x22,0xdc,0x84,0xc4,0x84,0x22,0xfa,0x64,0x44,0xc2,0x82, -0x00,0xa8,0xc2,0x84,0x08,0x24,0xd8,0x84,0xbf,0xd1,0xd8,0x85,0x64,0x43,0x58,0x4f, -0x61,0x00,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x67,0x60,0x6a,0x62,0x01,0x64, -0xa2,0xdb,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x80,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x05,0x00,0x01,0x64,0x90,0xfb,0x01,0x67,0x85,0xfb,0xff,0xff, -0x15,0xf5,0xff,0xff,0x22,0xf2,0xbf,0xd1,0xff,0xff,0x62,0x43,0xcc,0x84,0xe0,0x85, -0x09,0x06,0xbf,0xd1,0x64,0x41,0xd5,0x80,0x64,0x43,0x01,0x06,0x65,0x41,0x48,0x65, -0x58,0x4f,0x55,0x00,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x58,0x60,0x5a,0x63, -0xa3,0xd3,0x15,0xf5,0x60,0x41,0xe8,0x84,0xdc,0x84,0x22,0xfa,0xfc,0x60,0x80,0x64, -0x5a,0xda,0xda,0x85,0x04,0xa3,0x58,0x4f,0x25,0x00,0x00,0x67,0x00,0x61,0x23,0x58, -0xff,0xff,0x15,0xf5,0x22,0xf2,0xbf,0xd1,0xff,0xff,0x62,0x43,0xcc,0x84,0xe0,0x81, -0x15,0x06,0xbf,0xd1,0x64,0x45,0xd5,0x80,0x64,0x43,0xfc,0xa3,0x04,0x06,0x65,0x41, -0xe9,0x84,0xdc,0x84,0x22,0xfa,0x44,0x65,0x04,0xa1,0x58,0x4f,0x28,0x00,0x58,0x60, -0x5a,0x62,0xa2,0xd3,0xff,0xff,0xcc,0x84,0xe0,0x84,0xa2,0xdb,0x00,0x67,0x00,0x61, -0x23,0x58,0xff,0xff,0x41,0x4d,0x00,0xa1,0x80,0x64,0x17,0x03,0x65,0x42,0xd4,0x85, -0x2d,0x41,0x55,0x8d,0xff,0xff,0x02,0x04,0x65,0x41,0x02,0x00,0x00,0x64,0x40,0x4d, -0xca,0x84,0xbd,0xd1,0xc9,0x81,0x58,0xd8,0xfc,0x02,0x2d,0x41,0x00,0xa1,0xd8,0x85, -0x04,0x03,0x00,0xf4,0x7c,0x65,0x04,0x62,0xeb,0x00,0x2f,0x58,0xff,0xff,0x41,0x4d, -0x01,0xf2,0x65,0x42,0x7f,0xb5,0x2d,0x41,0x00,0xa1,0x55,0x8d,0x0e,0x03,0x02,0x04, -0x65,0x41,0x02,0x00,0x00,0x64,0x40,0x4d,0xca,0x84,0x58,0xd0,0xc9,0x81,0xbd,0xd9, -0xfc,0x02,0x00,0xf4,0x01,0xf2,0x04,0x62,0xed,0x00,0x2f,0x58,0xff,0xff,0x66,0x44, -0x93,0xfb,0x8a,0xf1,0x02,0x64,0xc0,0x84,0xe8,0x84,0x22,0xfa,0xf1,0x60,0x01,0x64, -0x23,0xfa,0x5a,0x8d,0x89,0xf1,0x27,0x60,0xe0,0x63,0x44,0x4b,0x43,0x4c,0x2b,0x45, -0xd7,0x80,0xbe,0xd1,0x0b,0x05,0x2d,0x45,0x64,0x43,0x44,0x61,0x35,0x60,0x58,0x4f, -0x5d,0x78,0xff,0xff,0x45,0x4d,0x2c,0x43,0x04,0xa3,0xf0,0x00,0x93,0xf1,0x3c,0x60, -0x88,0x62,0x3c,0x60,0x70,0x64,0xa2,0xdb,0x5a,0xd9,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0x08,0x65,0x45,0x55,0x3b,0xff,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff, -0x66,0x44,0x92,0xfb,0xc6,0xfe,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x66,0x44, -0x93,0xfb,0x72,0xf1,0x01,0x60,0x00,0x64,0xc0,0x81,0x28,0x60,0xe2,0x63,0x00,0x64, -0x40,0x4b,0xf1,0x60,0x02,0x64,0x23,0xfa,0xda,0x85,0xa3,0xd3,0xff,0xff,0xff,0xff, -0x01,0x2a,0x0b,0x00,0x41,0x4c,0x10,0x61,0x35,0x60,0x58,0x4f,0x5d,0x78,0xff,0xff, -0x2b,0x44,0xdc,0x84,0x40,0x4b,0x2c,0x41,0xf0,0xa3,0xcd,0x81,0x10,0xa3,0xed,0x02, -0x93,0xf1,0xff,0xff,0x64,0x46,0x2b,0x44,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xdc,0x84, -0x22,0xfa,0x3c,0x60,0x88,0x62,0x3c,0x60,0x70,0x64,0xa2,0xdb,0x5a,0xd9,0x0a,0x64, -0x5a,0xdb,0xff,0xff,0x2b,0xff,0x08,0x65,0x45,0x55,0x3b,0xff,0x00,0x67,0x00,0x61, -0x23,0x58,0xff,0xff,0x66,0x44,0x93,0xfb,0x3d,0x60,0x4c,0x64,0xa0,0xd1,0x02,0x64, -0xc0,0x84,0xe8,0x84,0x22,0xfa,0xf1,0x60,0x04,0x64,0x23,0xfa,0xda,0x85,0x3d,0x60, -0x4e,0x63,0x64,0x41,0x35,0x60,0x58,0x4f,0x5d,0x78,0xff,0xff,0x93,0xf1,0x3c,0x60, -0x88,0x62,0x3c,0x60,0x70,0x64,0xa2,0xdb,0x5a,0xd9,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0x08,0x65,0x45,0x55,0x3b,0xff,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff, -0x25,0x44,0x1a,0xf1,0x1b,0xf1,0xd0,0x80,0xd0,0x80,0x0e,0x04,0x08,0x06,0x1c,0xf1, -0x1d,0xf1,0xd0,0x80,0xd0,0x80,0x08,0x04,0x02,0x06,0x48,0xfe,0x05,0x00,0x25,0x46, -0x01,0xf0,0x03,0x67,0xa0,0x85,0x94,0x80,0x2f,0x58,0xff,0xff,0x15,0xf5,0x00,0x60, -0xf1,0x64,0x22,0xfa,0x25,0x44,0x23,0xfa,0x01,0x60,0xa8,0x64,0x40,0x4d,0x46,0x4c, -0xfc,0x60,0x00,0x64,0x40,0x4b,0xfe,0x60,0x00,0x64,0x36,0x63,0x46,0x61,0xc8,0x84, -0x2b,0x46,0x58,0xd0,0x2c,0x46,0x59,0xd8,0xfb,0x1f,0x2d,0x41,0x00,0xb9,0x84,0xa1, -0x08,0x03,0x04,0x24,0x00,0x61,0x41,0x4d,0x00,0xf4,0x02,0x61,0x7a,0x63,0x46,0x4c, -0xef,0x00,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0xfc,0x60,0x00,0x64,0x40,0x4b, -0x4b,0xd3,0x15,0xf5,0x60,0x41,0xd8,0x84,0xe8,0x84,0x22,0xfa,0x25,0x44,0x23,0xfa, -0xbf,0xd3,0x66,0x45,0x48,0x63,0xc8,0x84,0x2b,0x46,0x58,0xd0,0x65,0x46,0xc9,0x81, -0xbd,0xd8,0xfa,0x02,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0xfc,0x60,0x00,0x64, -0x40,0x4b,0x4b,0xd3,0x15,0xf5,0x60,0x41,0x22,0xf0,0xe9,0x85,0x64,0x44,0xff,0x22, -0xdc,0x84,0xc4,0x84,0x22,0xfa,0x64,0x44,0xc2,0x82,0x00,0xa8,0xc2,0x84,0x08,0x24, -0xd8,0x84,0xbf,0xd1,0xc9,0x83,0x64,0x41,0xc9,0x81,0x66,0x45,0x2b,0x46,0x59,0xd0, -0x65,0x46,0x58,0xd8,0xfb,0x1f,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5, -0x02,0x64,0x22,0xfa,0xfc,0xa3,0xa3,0xd3,0x25,0x43,0xa0,0xd3,0x23,0xfc,0xdc,0x84, -0x24,0xfa,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x02,0x64,0x22,0xfa, -0x25,0x44,0x23,0xfa,0x65,0xf3,0xff,0xff,0x02,0xb4,0x01,0x64,0x08,0x24,0x02,0x64, -0x24,0xfa,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x02,0x64,0x22,0xfa, -0x25,0x44,0x23,0xfa,0x50,0xf3,0x24,0xfa,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff, -0x15,0xf5,0x04,0x64,0x22,0xfa,0x25,0x44,0x23,0xfa,0x58,0xf3,0x24,0xfa,0xff,0xff, -0x59,0xf3,0x5a,0xf1,0x80,0x65,0xc4,0x87,0x00,0x7f,0x25,0xfa,0x64,0x44,0xc4,0x87, -0x00,0x7f,0x26,0xfa,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x24,0xf0, -0x17,0x60,0xc6,0x65,0x22,0xf2,0xa5,0xd9,0x02,0xa8,0x64,0x41,0x0f,0x02,0x00,0xb9, -0xff,0xff,0x0c,0x03,0x16,0x60,0xbc,0x62,0xa2,0xd9,0x7f,0xf3,0xff,0xff,0xd0,0x80, -0xff,0xff,0x04,0x02,0x01,0x63,0x08,0x60,0x2a,0x64,0xa0,0xdd,0x00,0x67,0x00,0x61, -0x23,0x58,0xff,0xff,0x15,0xf5,0x20,0x63,0x17,0x60,0x0e,0x61,0x46,0x64,0x58,0xd0, -0x59,0xd9,0xfd,0x1f,0x24,0xf0,0x20,0x64,0xd0,0x81,0x17,0x60,0x12,0x64,0x0d,0x06, -0xc0,0x83,0x01,0x2a,0x06,0x00,0xcf,0x83,0xa3,0xd3,0xcd,0x81,0x00,0x7f,0xbd,0xdb, -0x04,0x03,0x00,0x64,0xc9,0x81,0xbd,0xdb,0xfd,0x02,0x00,0x67,0x00,0x61,0x23,0x58, -0xff,0xff,0x15,0xf5,0x22,0xf2,0x24,0xf0,0x02,0xa8,0x59,0x60,0x1e,0x62,0x09,0x02, -0xa2,0xd9,0x64,0x41,0x32,0x44,0x02,0xb5,0x00,0xb9,0xd4,0x84,0x08,0x28,0x02,0xbc, -0x40,0x52,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x22,0xf2,0x24,0xf0, -0x02,0xa8,0x01,0x60,0x92,0x65,0x37,0x02,0xa5,0xd9,0x17,0x60,0xd4,0x62,0x00,0x61, -0x00,0x64,0x01,0x65,0x64,0x40,0x01,0x2a,0x02,0x00,0x01,0xa1,0x02,0x7e,0x64,0x40, -0x02,0x2a,0x09,0x00,0x01,0xa1,0xa5,0x80,0xff,0xff,0x02,0x03,0x04,0x7e,0x03,0x00, -0x04,0x7f,0xa2,0xdb,0x02,0xa2,0x64,0x40,0x04,0x2a,0x09,0x00,0x01,0xa1,0xa5,0x80, -0xff,0xff,0x02,0x03,0x0b,0x7e,0x03,0x00,0x0b,0x7f,0xa2,0xdb,0x02,0xa2,0x64,0x40, -0x08,0x2a,0x08,0x00,0x01,0xa1,0xa5,0x80,0xff,0xff,0x02,0x03,0x16,0x7e,0x02,0x00, -0x16,0x7f,0xa2,0xdb,0xa5,0x80,0xff,0xff,0x02,0x03,0x00,0x7f,0xa2,0xdb,0x17,0x60, -0xd2,0x62,0x61,0x43,0xa2,0xdd,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x59,0x60, -0xa6,0x63,0x00,0x60,0xd5,0x61,0x00,0x64,0xcd,0x81,0xbd,0xdb,0xfd,0x02,0x00,0x67, -0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x24,0xf0,0x3d,0x60,0x20,0x62,0xa2,0xd9, -0x17,0x60,0x06,0x62,0xa2,0xd9,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5, -0x24,0xf0,0x66,0x60,0xb4,0x65,0x03,0x60,0xe8,0x64,0x64,0x40,0x00,0x36,0x03,0x00, -0xa5,0xdb,0x01,0x64,0x40,0x5a,0x17,0x60,0x74,0x64,0xa0,0xd9,0x00,0x67,0x00,0x61, -0x23,0x58,0xff,0xff,0x15,0xf5,0x24,0xf2,0x99,0xff,0x40,0x5b,0x98,0xff,0x00,0x67, -0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x24,0xf2,0x99,0xff,0x40,0x5a,0x98,0xff, -0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x01,0x65,0x67,0x60,0x8e,0x61,0x0b,0x00, -0x02,0x65,0x67,0x60,0x9c,0x61,0x07,0x00,0x04,0x65,0x67,0x60,0xaa,0x61,0x03,0x00, -0x08,0x65,0x67,0x60,0xb8,0x61,0x41,0xf3,0xff,0xff,0xb4,0x84,0x41,0xfb,0x15,0xf5, -0x46,0x64,0x00,0x60,0x0c,0x63,0x58,0xd0,0x59,0xd9,0xfd,0x1f,0x22,0xf2,0xff,0xff, -0xf8,0xa0,0x0f,0x64,0x01,0x03,0x07,0x64,0x45,0xfb,0x67,0x44,0xd9,0xfb,0xda,0xfb, -0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x02,0x64,0x22,0xfa,0x25,0x44, -0x23,0xfa,0x43,0xf3,0x83,0xb4,0x24,0xfa,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff, -0xbc,0xf3,0xff,0xff,0x00,0xa4,0xff,0xff,0x16,0x03,0x15,0xf5,0x43,0xf3,0x24,0xf2, -0x60,0x41,0x83,0xb5,0xff,0x60,0x7c,0x7c,0xa1,0x81,0xb5,0x84,0x43,0xfb,0xff,0xff, -0x01,0x2a,0x09,0x00,0x1e,0x60,0xa0,0x63,0x09,0x60,0x2b,0x64,0xbd,0xdb,0xbd,0xdb, -0xbd,0xdb,0xff,0xff,0xbd,0xdb,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5, -0x22,0xf2,0x24,0xf0,0x02,0xa8,0xff,0xff,0x05,0x02,0x00,0x64,0x64,0x40,0x00,0x3a, -0x03,0x64,0xd5,0xfb,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x66,0x60,0xd8,0x62, -0x01,0x64,0xa2,0xdb,0x17,0x60,0x06,0x62,0x05,0x64,0xa2,0xdb,0x01,0x60,0x7a,0x63, -0x66,0x60,0xda,0x65,0x03,0x61,0xbd,0xd1,0x00,0x7f,0x64,0x5e,0xa5,0xdb,0xda,0x85, -0x64,0x47,0x00,0x7f,0xa5,0xdb,0xcd,0x81,0xda,0x85,0xf5,0x02,0x00,0x67,0x00,0x61, -0x23,0x58,0xff,0xff,0x15,0xf5,0x22,0xf2,0x24,0xf0,0x02,0xa8,0x1f,0xf3,0x14,0x02, -0x60,0x40,0x10,0x2a,0x11,0x00,0x17,0x60,0x7e,0x62,0xa2,0xd9,0x00,0x64,0x64,0x40, -0x01,0x26,0x20,0x64,0xc5,0xfb,0x16,0x60,0x42,0x62,0xa2,0xd3,0xff,0xff,0x03,0xa8, -0xff,0xff,0x02,0x02,0xc5,0xf3,0x47,0xfb,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff, -0x15,0xf5,0x19,0x60,0x2a,0x65,0x26,0xf2,0x25,0xf0,0x60,0x41,0x64,0x43,0xeb,0x83, -0x00,0x7f,0xe0,0x84,0x44,0xd1,0x61,0x47,0x93,0x83,0x00,0x7f,0xe0,0x84,0x44,0xd1, -0xeb,0x83,0x93,0x83,0x0f,0x60,0xf0,0x65,0xa7,0x85,0x02,0x61,0x44,0x60,0x4e,0x63, -0xc7,0x83,0xa3,0xd3,0xff,0xff,0x60,0x40,0x80,0x2b,0x13,0x00,0x65,0x44,0xff,0xa1, -0x08,0xa5,0xf4,0x02,0x00,0x65,0x7e,0x61,0x54,0x60,0x4e,0x63,0xc7,0x83,0xa3,0xd3, -0xff,0xff,0x60,0x40,0x80,0x2b,0x05,0x00,0x65,0x44,0xff,0xa1,0x08,0xa5,0xf4,0x02, -0x2e,0x00,0x2d,0xf0,0xff,0xff,0x64,0x47,0x00,0x7f,0xe0,0x84,0x60,0x45,0xe0,0x84, -0xe0,0x81,0xc4,0x85,0xc5,0x85,0x80,0x67,0xb4,0x84,0xbd,0xdb,0x24,0xf2,0xbd,0xdb, -0xff,0xff,0x25,0xf2,0xbd,0xdb,0x26,0xf0,0xff,0xff,0xa3,0xd9,0x3d,0x60,0x4e,0x63, -0x27,0xf2,0xc7,0x83,0xbd,0xdb,0x28,0xf2,0xbd,0xdb,0xff,0xff,0x29,0xf2,0xbd,0xdb, -0x2a,0xf2,0xff,0xff,0xbd,0xdb,0x2b,0xf2,0xbd,0xdb,0xff,0xff,0x2c,0xf2,0xbd,0xdb, -0x2d,0xf2,0xff,0xff,0xbd,0xdb,0x41,0xf3,0x04,0x65,0xb4,0x84,0x41,0xfb,0x00,0x67, -0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5,0x19,0x60,0x2a,0x65,0x26,0xf2,0x25,0xf0, -0x60,0x41,0x64,0x43,0xeb,0x83,0x00,0x7f,0xe0,0x84,0x44,0xd1,0x61,0x47,0x93,0x83, -0x00,0x7f,0xe0,0x84,0x44,0xd1,0xeb,0x83,0x93,0x83,0x0f,0x60,0xf0,0x65,0xa7,0x85, -0x02,0x61,0x44,0x60,0x4e,0x63,0xc7,0x83,0xa3,0xd3,0x02,0xa3,0x60,0x40,0x80,0x2b, -0x0d,0x00,0x24,0xf0,0xbd,0xd3,0x50,0xfe,0x25,0xf0,0xd0,0x80,0xbd,0xd3,0x26,0xf0, -0xd0,0x80,0xa3,0xd3,0xff,0xff,0xd0,0x80,0xff,0xff,0x20,0x01,0x65,0x44,0xff,0xa1, -0x08,0xa5,0xe7,0x02,0x00,0x65,0x7e,0x61,0x54,0x60,0x4e,0x63,0xc7,0x83,0xa3,0xd3, -0x02,0xa3,0x60,0x40,0x80,0x2b,0x0d,0x00,0x24,0xf0,0xbd,0xd3,0x50,0xfe,0x25,0xf0, -0xd0,0x80,0xbd,0xd3,0x26,0xf0,0xd0,0x80,0xa3,0xd3,0xff,0xff,0xd0,0x80,0xff,0xff, -0x05,0x01,0x65,0x44,0xff,0xa1,0x08,0xa5,0xe7,0x02,0x06,0x00,0xfa,0xa3,0xa3,0xd3, -0xff,0xff,0xe0,0x84,0xe8,0x84,0xa3,0xdb,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff, -0x66,0x44,0x93,0xfb,0x00,0x60,0x92,0x64,0x22,0xfa,0xf1,0x60,0x03,0x64,0x23,0xfa, -0x48,0x65,0x38,0x64,0x40,0x4c,0x1d,0x60,0x90,0x63,0xbd,0xd3,0xff,0xff,0x00,0xa0, -0xbd,0xd1,0x12,0x03,0x43,0x48,0x60,0x43,0x64,0x41,0xbd,0xd3,0xa5,0xda,0x2c,0x44, -0xc8,0x84,0x40,0x4c,0x04,0x02,0x00,0xf4,0x78,0x64,0x40,0x4c,0x02,0x62,0xcd,0x81, -0xda,0x85,0xf3,0x02,0x28,0x43,0xe9,0x00,0x93,0xf1,0x3c,0x60,0x88,0x62,0x3c,0x60, -0x70,0x64,0xa2,0xdb,0x5a,0xd9,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x08,0x65, -0x45,0x55,0x3b,0xff,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x1f,0xf3,0x15,0xf5, -0x24,0xf0,0x60,0x40,0x20,0x2a,0x13,0x00,0x64,0x47,0x00,0x7f,0xfe,0xa4,0x82,0xa0, -0x60,0x45,0x0d,0x05,0x14,0x60,0x3e,0x62,0x46,0xd9,0x67,0x60,0x72,0x62,0xa2,0xd3, -0x64,0x40,0x12,0x37,0x01,0xbc,0x64,0x40,0x14,0x37,0x02,0xbc,0xa2,0xdb,0x00,0x67, -0x00,0x61,0x23,0x58,0xff,0xff,0x28,0x60,0xda,0x63,0x00,0x64,0xbd,0xdb,0xbd,0xdb, -0xff,0xff,0xbd,0xdb,0xbd,0xdb,0x01,0x64,0x23,0xfb,0xff,0xff,0x1a,0xff,0x23,0xf3, -0xff,0xff,0x00,0xa0,0xff,0xff,0xfb,0x02,0x15,0xf5,0x05,0x64,0x22,0xfa,0x25,0x44, -0x23,0xfa,0xd4,0xf3,0x24,0xfa,0xff,0xff,0xa1,0xf3,0x25,0xfa,0xa2,0xf3,0xff,0xff, -0x26,0xfa,0xa3,0xfb,0x27,0xfa,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x15,0xf5, -0x22,0xf2,0xff,0xff,0xfb,0xa0,0x28,0x60,0xda,0x63,0x0b,0x02,0x24,0xf2,0xbd,0xdb, -0x25,0xf2,0xff,0xff,0xbd,0xdb,0xbd,0xdb,0xbd,0xdb,0x01,0x64,0x23,0xfb,0xff,0xff, -0x1a,0xff,0x00,0x67,0x00,0x61,0x23,0x58,0xff,0xff,0x38,0xf2,0xff,0xff,0xff,0xa0, -0x02,0x64,0x03,0x02,0x38,0xfa,0x60,0x47,0x3f,0xfa,0x28,0xf2,0xff,0xff,0x08,0xb0, -0x60,0x47,0x07,0xb5,0x20,0x02,0xa6,0xf3,0x71,0x02,0x02,0xa8,0x01,0xa8,0x1c,0x02, -0x39,0xf0,0x2b,0xf8,0x3a,0xf0,0xff,0xff,0x2c,0xf8,0x3b,0xf0,0x2d,0xf8,0xff,0xff, -0x81,0xf1,0x2e,0xf8,0x82,0xf1,0xff,0xff,0x2f,0xf8,0x83,0xf1,0x30,0xf8,0xff,0xff, -0x3c,0xf0,0x31,0xf8,0x3d,0xf0,0xff,0xff,0x32,0xf8,0x3e,0xf0,0x85,0xf3,0xff,0xff, -0x33,0xf8,0x08,0xbc,0x29,0xfa,0x52,0x00,0x50,0xfe,0x3c,0xf0,0xbd,0xf3,0x2e,0xf8, -0xd0,0x80,0x3d,0xf0,0xbe,0xf3,0x2f,0xf8,0xd0,0x80,0x3e,0xf0,0xbf,0xf3,0x30,0xf8, -0xd0,0x80,0x85,0xf3,0x07,0x01,0x90,0xf3,0x60,0x41,0x04,0xb0,0x61,0x44,0x02,0x02, -0x42,0xfe,0x3d,0x00,0x4a,0xf1,0x43,0xf1,0x64,0x40,0x01,0x2a,0x0f,0x00,0x28,0xf0, -0x64,0x40,0x01,0x2a,0x0b,0x00,0x64,0x40,0x81,0x26,0x08,0x00,0x38,0xf2,0x60,0x5c, -0x00,0xa8,0x64,0x44,0x03,0x03,0x60,0x47,0x40,0xbc,0x60,0x47,0x08,0xbc,0x29,0xfa, -0x90,0xf3,0xff,0xff,0x04,0xb0,0x39,0xf0,0x21,0x02,0x02,0xb0,0x39,0xf0,0x0f,0x03, -0x2b,0xf8,0x3a,0xf0,0xff,0xff,0x2c,0xf8,0x3b,0xf0,0x2d,0xf8,0xff,0xff,0x81,0xf1, -0x31,0xf8,0x82,0xf1,0xff,0xff,0x32,0xf8,0x83,0xf1,0x33,0xf8,0x0f,0x00,0x31,0xf8, -0x3a,0xf0,0xff,0xff,0x32,0xf8,0x3b,0xf0,0x33,0xf8,0xff,0xff,0x81,0xf1,0x2b,0xf8, -0x82,0xf1,0xff,0xff,0x2c,0xf8,0x83,0xf1,0x2d,0xf8,0x00,0x00,0x02,0xfe,0x2f,0x58, -0xff,0xff,0x00,0x64,0x15,0xfa,0x16,0xfa,0x1c,0xfa,0xff,0xff,0x07,0xfa,0x19,0xfa, -0x1e,0x60,0xa0,0x65,0x95,0xf1,0x51,0xf3,0x64,0x40,0x01,0x2a,0x02,0x00,0x13,0xf2, -0xff,0xff,0xe0,0x84,0x44,0xd1,0xca,0xf9,0x1e,0x63,0x29,0xf0,0x73,0x60,0xff,0x64, -0xa0,0x84,0x03,0x2b,0x18,0x63,0x29,0xfa,0x04,0xa3,0x64,0x40,0x40,0x27,0x08,0xa3, -0x43,0x4b,0x21,0xfc,0x56,0x61,0x64,0x40,0x01,0x27,0x62,0x61,0x38,0xf0,0xa1,0xd2, -0x44,0x4d,0x60,0x40,0x01,0x26,0x22,0x00,0xca,0xf1,0xc3,0x81,0xd1,0x80,0x63,0x45, -0x20,0x06,0x64,0x43,0xd7,0x85,0x45,0x4c,0xc8,0xf1,0x0f,0xf2,0xd3,0x80,0x01,0x65, -0x01,0x05,0x00,0x65,0xb4,0x84,0x0f,0xfa,0x00,0x63,0x2d,0x44,0x2c,0x45,0x60,0x41, -0xd4,0x84,0xdf,0x83,0xfc,0x07,0x14,0xfc,0x61,0x44,0x17,0xfa,0x29,0xf0,0x04,0x64, -0x60,0x47,0xb0,0x84,0x29,0xfa,0x2c,0x43,0x16,0xfc,0x0f,0x00,0x2d,0x44,0x17,0xfa, -0x0a,0x00,0x2d,0x44,0x17,0xfa,0x2b,0x45,0xc8,0xf1,0xc4,0x81,0xd1,0x80,0x0f,0xf2, -0x01,0x04,0x01,0xbc,0x0f,0xfa,0x01,0x64,0x14,0xfa,0x2e,0x58,0xff,0xff,0xcb,0xf3, -0x2b,0xf2,0xfd,0xa0,0xff,0xff,0x4c,0x02,0x60,0x40,0x01,0x26,0x39,0x00,0x2b,0xf2, -0xff,0xff,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0xe1,0x81,0x5a,0xd2, -0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0xe1,0x81, -0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84, -0xe1,0x81,0xf0,0x84,0x0e,0x4c,0x3a,0x60,0x58,0x4e,0xc5,0x78,0xff,0xff,0x0c,0x4e, -0x14,0x03,0x19,0xfc,0x0a,0xa3,0x3c,0x64,0xa3,0xdb,0xfe,0xa3,0xa3,0xd3,0xff,0xff, -0xff,0xff,0x01,0x26,0x00,0x7f,0x02,0x26,0x01,0x7f,0x04,0x26,0x02,0x7f,0x08,0x26, -0x03,0x7f,0x1d,0xfa,0x00,0x64,0x0d,0xfa,0x13,0x00,0x19,0xfc,0x50,0xf3,0xf1,0x00, -0x17,0x60,0xdc,0x64,0xa0,0xd1,0x39,0x60,0xe2,0x64,0x19,0xfa,0x64,0x44,0x08,0x26, -0x03,0x7f,0x04,0x26,0x02,0x7f,0x02,0x26,0x01,0x7f,0x01,0x26,0x00,0x7f,0xe9,0x00, -0x2e,0x58,0xff,0xff,0x28,0x60,0xe2,0x65,0x00,0x7f,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0x44,0xd3,0x62,0x43,0x60,0x40,0x01,0x2a,0x10,0x00,0x02,0xa3,0x2b,0xf2, -0x50,0xfe,0xbd,0xd1,0x2c,0xf2,0xd0,0x80,0xbd,0xd1,0x2d,0xf2,0xd0,0x80,0xbd,0xd1, -0xff,0xff,0xd0,0x80,0xff,0xff,0x02,0x02,0xf8,0xa3,0x1e,0x00,0x72,0xf1,0x38,0x60, -0xe2,0x63,0x64,0x41,0xff,0x22,0x17,0x00,0xbd,0xd1,0x2b,0xf2,0x50,0xfe,0x64,0x40, -0x01,0x26,0x04,0x00,0xcd,0x81,0x0e,0xa3,0xf7,0x02,0x0d,0x00,0xbd,0xd1,0x2c,0xf2, -0xd0,0x80,0xbd,0xd1,0x2d,0xf2,0xd0,0x80,0xbd,0xd1,0xff,0xff,0xd0,0x80,0xcd,0x81, -0xe3,0x01,0x08,0xa3,0xe9,0x02,0x00,0x63,0x00,0xbb,0x2e,0x58,0xff,0xff,0x0f,0xf3, -0x2c,0x65,0x60,0x47,0xff,0xb4,0xd4,0x80,0xff,0xff,0x04,0x28,0x06,0x00,0xe0,0x85, -0x15,0x60,0xa0,0x64,0x44,0xd7,0xff,0xff,0xff,0xff,0xff,0x67,0x23,0x58,0xff,0xff, -0x3b,0x60,0x2d,0x64,0x97,0xfb,0xff,0xff,0x2d,0xff,0x30,0x60,0x7f,0x78,0xff,0xff, -0x10,0xf3,0x7f,0xfb,0x02,0x7f,0x99,0xfb,0x02,0x60,0xee,0x64,0x98,0xfb,0x07,0x64, -0x9a,0xfb,0x3b,0x60,0x2d,0x64,0x97,0xfb,0xdf,0xfe,0x00,0x64,0x19,0xff,0x30,0x60, -0x7f,0x78,0xff,0xff,0x00,0x67,0x23,0x58,0xff,0xff,0x68,0x60,0xdc,0x61,0x11,0xf3, -0xff,0xff,0xa1,0xdb,0x68,0x60,0xd2,0x61,0x10,0xf3,0xff,0xff,0xa1,0xdb,0x68,0x60, -0xd4,0x61,0xff,0xff,0x02,0x36,0x06,0x00,0x03,0x36,0x06,0x00,0x04,0x36,0x13,0x00, -0x00,0x64,0x16,0x00,0x00,0x64,0x14,0x00,0x16,0x60,0xb6,0x63,0xbd,0xd3,0x81,0xfb, -0xbd,0xd3,0xff,0xff,0x82,0xfb,0xa3,0xd3,0x83,0xfb,0x68,0x60,0xda,0x62,0xff,0x64, -0xa2,0xdb,0x01,0x64,0x05,0x00,0x68,0x60,0xda,0x62,0xff,0x64,0xa2,0xdb,0x01,0x64, -0xa1,0xdb,0x00,0x60,0x01,0x64,0x32,0x45,0x34,0x92,0x00,0x67,0x23,0x58,0xff,0xff, -0x00,0x60,0x02,0xe8,0x3c,0x60,0x6b,0x63,0x0e,0x60,0xac,0x64,0xa0,0xdd,0xff,0xff, -0x62,0xff,0xff,0xff,0x1a,0xff,0x00,0x67,0x23,0x58,0xff,0xff,0x99,0xff,0x3e,0x44, -0xfc,0xb4,0x00,0x7f,0x40,0x5e,0x98,0xff,0xbc,0xff,0x0d,0x63,0x58,0x4f,0xf4,0x76, -0x7e,0x00,0x00,0x10,0x46,0x00,0x99,0xff,0x3d,0x44,0xf7,0xb4,0x40,0x5d,0x98,0xff, -0x0d,0x63,0x58,0x4f,0x3e,0x00,0x99,0xff,0x3e,0x44,0x77,0xb4,0x08,0xbc,0x00,0x7f, -0x40,0x5e,0x98,0xff,0x0d,0x63,0x58,0x4f,0x34,0x00,0x99,0xff,0x3c,0x44,0x10,0xbc, -0x00,0x7f,0x40,0x5c,0x98,0xff,0x99,0xff,0x3d,0x44,0xef,0xb4,0x40,0x5d,0x98,0xff, -0xb5,0xff,0xff,0xff,0x6c,0x40,0x11,0x60,0x03,0xe8,0x01,0x60,0x03,0xe8,0xff,0xff, -0xff,0xff,0xff,0xff,0x0e,0x60,0x00,0x6b,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0x46,0xff,0x47,0xff,0xf9,0x60,0xfe,0x64,0x32,0x45,0x24,0x92,0x99,0xff,0x35,0x47, -0xff,0xb4,0x60,0x5c,0x08,0x60,0x0e,0x64,0xa0,0xd9,0x64,0x44,0x98,0xff,0x11,0x60, -0x8e,0x63,0x0e,0x60,0xac,0x64,0xa0,0xdd,0xff,0xff,0x62,0xff,0x00,0x67,0x23,0x58, -0xff,0xff,0xff,0xff,0xfe,0x1f,0x2f,0x58,0xff,0xff,0x99,0xff,0x1e,0x65,0x3d,0x44, -0xe1,0x81,0xf9,0xb4,0x02,0x24,0x04,0xbc,0x00,0x7f,0x40,0x5d,0x02,0x63,0xff,0xff, -0xfe,0x1f,0x02,0xbc,0x40,0x5d,0xf4,0x1f,0x98,0xff,0x99,0xff,0x10,0xf3,0xff,0xff, -0x60,0x47,0x60,0x45,0x60,0x47,0xa4,0x81,0x65,0x44,0xff,0xad,0x04,0x60,0xff,0xe5, -0x3c,0x44,0x04,0x60,0xff,0xe5,0xa4,0x85,0xb5,0x84,0x00,0x7f,0x40,0x5c,0x04,0x60, -0xff,0xe5,0x3c,0x44,0x04,0x60,0xff,0xe5,0x00,0x7f,0x60,0x5c,0x08,0x60,0x0a,0x64, -0xa0,0xd9,0x11,0xf3,0xff,0xff,0x60,0x47,0x60,0x45,0x60,0x47,0xa4,0x81,0x65,0x44, -0xff,0xad,0x3d,0x44,0xa4,0x85,0xb5,0x84,0x00,0x7f,0x40,0x5d,0x3d,0x44,0x00,0x7f, -0x60,0x5c,0x08,0x60,0x0c,0x64,0xa0,0xd9,0x12,0xf3,0xff,0xff,0x60,0x47,0x60,0x45, -0x60,0x47,0xa4,0x81,0x65,0x44,0xff,0xad,0x04,0x60,0xff,0xe5,0x3e,0x44,0x04,0x60, -0xff,0xe5,0xa4,0x85,0xb5,0x84,0x00,0x7f,0x40,0x5e,0x00,0x6b,0x04,0x60,0xff,0xe5, -0x3e,0x44,0x04,0x60,0xff,0xe5,0x00,0x7f,0x60,0x5c,0x08,0x60,0x0e,0x64,0xa0,0xd9, -0x98,0xff,0x00,0x67,0x23,0x58,0xff,0xff,0x10,0xf1,0x3c,0x60,0xa8,0x62,0xa2,0xd9, -0xca,0x82,0x22,0x64,0xa2,0xdb,0x3b,0x60,0x13,0x78,0xff,0xff,0x10,0xf1,0xff,0xff, -0x7f,0xf9,0x3c,0x60,0xa6,0x62,0x08,0x64,0xa2,0xdb,0x3b,0x60,0x13,0x78,0xff,0xff, -0x10,0xf1,0x3c,0x60,0xa8,0x62,0xa2,0xd9,0xca,0x82,0x1e,0x64,0xa2,0xdb,0x3b,0x60, -0x13,0x78,0xff,0xff,0x3c,0x60,0xa6,0x62,0x02,0x64,0xa2,0xdb,0x3b,0x60,0x13,0x78, -0xff,0xff,0x01,0x65,0x01,0x00,0x00,0x65,0x10,0xf1,0x15,0x60,0x46,0x63,0xbd,0xd9, -0x11,0xf1,0xbd,0xd9,0xff,0xff,0x12,0xf1,0xa3,0xd9,0x65,0x40,0x01,0x2a,0x06,0x00, -0x00,0x64,0x10,0xfb,0xff,0xff,0x3b,0x60,0x1b,0x78,0xff,0xff,0x00,0x67,0x23,0x58, -0xff,0xff,0x10,0xf1,0x67,0x60,0x50,0x62,0xa2,0xd9,0x00,0x67,0x23,0x58,0xff,0xff, -0x00,0x67,0x23,0x58,0xff,0xff,0x08,0xe1,0xa1,0xff,0xff,0xff,0x43,0xff,0x01,0xe1, -0x99,0xff,0x3c,0x44,0x7f,0xb4,0x10,0xbc,0x40,0x5c,0x98,0xff,0x99,0xff,0x3d,0x44, -0xef,0xb4,0x40,0x5d,0x98,0xff,0x0d,0x63,0x58,0x4f,0x76,0x00,0x99,0xff,0x3e,0x44, -0x77,0xb4,0x80,0xbc,0x00,0x7f,0x40,0x5e,0x98,0xff,0x0d,0x63,0x58,0x4f,0x6c,0x00, -0xff,0x6d,0x99,0xff,0x3e,0x44,0xfc,0xb4,0x01,0xbc,0x00,0x7f,0x40,0x5e,0x01,0x60, -0x00,0x6b,0x98,0xff,0x0d,0x63,0x58,0x4f,0x5f,0x00,0x99,0xff,0x3d,0x44,0xf7,0xb4, -0x40,0x5d,0x98,0xff,0x99,0xff,0x3d,0x44,0x08,0xbc,0x00,0x7f,0x40,0x5d,0x98,0xff, -0x10,0xf3,0xff,0xff,0x60,0x5c,0x99,0xff,0x07,0x60,0x00,0xe8,0x98,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x80,0xe8,0xff,0xff,0xff,0xff, -0xff,0xff,0x64,0x4d,0xa1,0xff,0x64,0x47,0x60,0x4d,0xff,0xff,0xff,0xff,0xa1,0xff, -0xbb,0xff,0x64,0x44,0xa1,0xff,0x60,0x4d,0xa1,0xff,0x60,0x47,0x60,0x4d,0x64,0x44, -0xa1,0xff,0x60,0x4d,0xa1,0xff,0x60,0x47,0x60,0x4d,0x64,0x44,0xa1,0xff,0x60,0x4d, -0xa1,0xff,0x60,0x47,0x60,0x4d,0x11,0xf3,0xff,0xff,0x00,0xa8,0x60,0x43,0x05,0x02, -0x64,0x44,0xa1,0xff,0xff,0xff,0x60,0x4c,0xfc,0x00,0x63,0x46,0x43,0x4f,0x3f,0xf2, -0xff,0xff,0x60,0x47,0x60,0x5c,0xff,0x65,0x2f,0x46,0x64,0x43,0x00,0xf4,0x01,0xf2, -0x04,0x62,0xa4,0x81,0xe2,0xd2,0xff,0xff,0xa1,0xff,0xda,0x82,0xc9,0x81,0x60,0x4c, -0xf9,0x1c,0xf4,0x1d,0xf1,0x1e,0x02,0x02,0x00,0xf4,0x04,0x62,0xa2,0xd2,0xff,0xff, -0xa1,0xff,0xff,0xff,0x60,0x4d,0xe8,0x00,0xff,0xff,0xfe,0x1f,0x2f,0x58,0xff,0xff, -0x6a,0x60,0x0c,0x78,0xff,0xff,0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x80,0x60,0x00,0x64, -0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x2b,0x00,0x74,0xf3,0x60,0xf1,0x00,0xa0,0xb0,0x84, -0x0c,0x03,0x60,0xfb,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60,0x20,0x64,0xb0,0x84, -0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x00,0x64,0x74,0xfb,0x75,0xf3,0xff,0xff,0x00,0xa0, -0x00,0x64,0x15,0x03,0x75,0xfb,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x02,0x64, -0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x0a,0x00,0xab,0xfe,0xff,0xff,0xd0,0x05, -0xaa,0xfe,0xff,0xff,0xd0,0x05,0xa9,0xfe,0xff,0xff,0xd6,0x05,0xff,0xff,0xa1,0xff, -0xff,0xff,0xbd,0x3f,0x0e,0x57,0x67,0x60,0xca,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff, -0x01,0x26,0x0c,0x65,0x45,0x48,0x0f,0x4e,0x00,0x60,0x06,0x61,0x41,0x4d,0x40,0xa1, -0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41, -0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x15,0x03,0x02,0x64, -0x22,0xfa,0xf2,0x60,0x00,0x64,0x5a,0xda,0x28,0x44,0x5a,0xda,0x08,0x65,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x70,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0x45,0x54,0x3b,0xff,0x37,0x58,0xff,0xff,0x92,0xf3,0x15,0x61, -0x00,0xa8,0x60,0x46,0x15,0x02,0x0f,0x4e,0x00,0x60,0x2e,0x61,0x41,0x4d,0x40,0xa1, -0xa2,0xff,0x19,0x60,0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41, -0x19,0x60,0x58,0x4f,0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x21,0x03,0x15,0x61, -0x00,0x64,0x92,0xfb,0x58,0x60,0x2e,0x63,0x16,0x64,0x22,0xfa,0xf1,0x60,0x00,0x64, -0x23,0xfa,0x48,0x65,0x00,0x64,0xa3,0xd1,0xbd,0xdb,0xa5,0xd8,0xcd,0x81,0xda,0x85, -0xfa,0x02,0x3c,0x60,0x82,0x62,0x3c,0x60,0x70,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb, -0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x08,0x65,0x45,0x54,0x3b,0xff,0xa6,0xfe, -0x8e,0x00,0xa6,0xfe,0xff,0xff,0xc2,0x05,0xa7,0xfe,0xff,0xff,0x08,0x05,0xa5,0xfe, -0xff,0xff,0x1f,0x05,0xa4,0xfe,0xff,0xff,0x01,0x05,0x81,0x00,0x80,0x00,0x36,0x45, -0x0e,0x60,0xd0,0x64,0x44,0xd7,0xff,0xff,0xff,0xff,0x94,0xf3,0xff,0xff,0x01,0xb0, -0x00,0x64,0x0f,0x03,0x94,0xfb,0x31,0x44,0xfe,0xb4,0x40,0x51,0x1e,0x60,0xe0,0x62, -0xa2,0xd1,0x00,0x60,0x20,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x3d,0x60,0x2f,0x78, -0xff,0xff,0x3e,0x60,0x8d,0x78,0xff,0xff,0x16,0x60,0xb6,0x63,0xbd,0xd3,0xbd,0xd1, -0xbd,0xd1,0xb0,0x84,0xb0,0x84,0xff,0xff,0x0b,0x02,0x8c,0xfb,0x31,0x44,0xfe,0xb4, -0x40,0x51,0x0d,0x7c,0x08,0x60,0x0a,0x64,0xa0,0xd9,0x3e,0x60,0x8d,0x78,0xff,0xff, -0x0f,0xf3,0x94,0xf1,0x60,0x47,0x07,0xb4,0x01,0x61,0x03,0x03,0xcc,0x84,0xe1,0x81, -0xfd,0x02,0xa1,0x80,0xb1,0x83,0x03,0x03,0x3e,0x60,0x8d,0x78,0xff,0xff,0x94,0xfd, -0x31,0x44,0x01,0xbc,0x40,0x51,0xd1,0xfe,0x1f,0xf3,0xff,0xff,0xff,0xff,0x20,0x26, -0x18,0x00,0x17,0x60,0x7c,0x62,0xa2,0xd3,0xff,0xff,0x60,0x40,0x01,0x3a,0x03,0x00, -0xe4,0x65,0xbb,0x63,0x0b,0x00,0x60,0x40,0x02,0x3a,0x03,0x00,0xe0,0x65,0xb9,0x63, -0x05,0x00,0xb8,0x63,0xe6,0x65,0x60,0x40,0x03,0x36,0xe4,0x65,0x13,0x60,0x6c,0x62, -0x15,0x00,0x17,0x60,0x7c,0x62,0xa2,0xd3,0xff,0xff,0x60,0x40,0x01,0x3a,0x03,0x00, -0xe4,0x65,0xcb,0x63,0x0b,0x00,0x60,0x40,0x02,0x3a,0x03,0x00,0xe0,0x65,0xc9,0x63, -0x05,0x00,0xc8,0x63,0xe6,0x65,0x60,0x40,0x03,0x36,0xe4,0x65,0x67,0x60,0x72,0x62, -0xa2,0xd3,0xff,0xff,0x14,0x60,0x4e,0x62,0x60,0x41,0x01,0x26,0x03,0x00,0x65,0x5e, -0x12,0x7f,0xa2,0xdb,0x61,0x40,0x02,0x26,0x03,0x00,0x63,0x5e,0x14,0x7f,0x5a,0xdb, -0x00,0x64,0x65,0xfb,0x17,0x60,0x44,0x62,0xa2,0xd3,0xff,0xff,0xfc,0xa0,0xff,0xff, -0x01,0x06,0x04,0x64,0xa2,0xdb,0x3e,0x60,0x58,0x4e,0xae,0x78,0xff,0xff,0x95,0xf3, -0xff,0xff,0x00,0xa0,0xff,0xff,0x26,0x03,0x00,0x60,0x08,0x63,0x01,0x60,0x78,0x61, -0x16,0x60,0xb4,0x64,0x58,0xd1,0x59,0xd9,0xfd,0x1f,0x00,0x60,0x72,0x63,0x16,0x60, -0x40,0x61,0x16,0x60,0xbe,0x64,0x58,0xd1,0x59,0xd9,0xfd,0x1f,0x00,0x60,0x1a,0x63, -0x01,0x60,0x00,0x61,0x00,0x64,0x59,0xdb,0xfe,0x1f,0x00,0x60,0xfa,0x64,0xe3,0xfb, -0xc0,0xf1,0x3c,0x60,0xa2,0x62,0xa2,0xd9,0xca,0x82,0x1e,0x64,0xa2,0xdb,0xff,0xff, -0x2d,0xff,0x1b,0x00,0x0d,0x60,0xac,0x64,0xe3,0xfb,0x32,0x40,0x01,0x26,0x0f,0x00, -0x16,0x60,0xbc,0x62,0xa2,0xd3,0xa5,0xf3,0x60,0x41,0x00,0x36,0x04,0x00,0xcd,0x81, -0xe8,0x84,0xfd,0x02,0x04,0x05,0xc0,0xf1,0x16,0x60,0xbc,0x62,0xa2,0xd9,0x0f,0x4e, -0x42,0x60,0x58,0x4f,0x60,0x78,0xff,0xff,0x0e,0x4f,0xda,0xfe,0x3d,0x60,0x2f,0x78, -0xff,0xff,0x66,0x44,0x00,0xa8,0x0e,0x57,0x17,0x03,0x00,0x64,0x40,0x46,0xcb,0xfe, -0x0f,0x4e,0x46,0x45,0x3c,0x60,0x82,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb, -0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78, -0xff,0xff,0xa3,0xff,0xd1,0xfe,0x0e,0x4f,0x37,0x58,0xff,0xff,0x1f,0xf3,0xff,0xff, -0xff,0xff,0x10,0x2a,0x34,0x00,0x17,0x60,0x44,0x62,0xa2,0xd3,0xff,0xff,0x60,0x45, -0xd5,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x19,0x03,0x17,0x60,0x80,0x62,0xa2,0xd3, -0xff,0xff,0x60,0x45,0x17,0x60,0x48,0x63,0xff,0x60,0xff,0x61,0xbd,0xd3,0xdd,0x81, -0xd4,0x80,0x61,0x44,0x03,0x06,0xfc,0xa0,0xff,0xff,0xf8,0x02,0x17,0x60,0x44,0x62, -0xa2,0xd3,0x61,0x45,0xd4,0x80,0xff,0xff,0x01,0x06,0x60,0x45,0x66,0x60,0xd4,0x62, -0x65,0x44,0xa2,0xdb,0xe0,0x85,0x17,0x60,0x3a,0x64,0x44,0xd3,0xff,0xff,0x13,0x60, -0x98,0x62,0x3e,0x7f,0xa2,0xdb,0x14,0x60,0x7a,0x62,0x3e,0x7f,0xa2,0xdb,0x2e,0x58, -0xff,0xff,0x3c,0x60,0x4c,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x0e,0xf2, -0x62,0x03,0x60,0x47,0xfd,0x37,0x3a,0x00,0xff,0x36,0x17,0x00,0xf0,0x36,0x0a,0x00, -0xff,0xb5,0x1e,0x60,0xaa,0x62,0x46,0xd1,0x00,0x60,0x01,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x3c,0x60,0x82,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb, -0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xdc,0x00,0x0f,0x4e,0x46,0x45,0x3c,0x60, -0x82,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0xd1,0xfe, -0x0e,0x4f,0x59,0x60,0xe8,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0xbb,0x00,0x3c,0x60,0x82,0x62, -0x3c,0x60,0x46,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0xd3,0xfe,0x59,0x60,0xe8,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0xa2,0x00,0xac,0xfe, -0xff,0xff,0x0c,0x05,0xad,0xfe,0xff,0xff,0x12,0x05,0xae,0xfe,0xff,0xff,0x99,0x05, -0xaf,0xfe,0xff,0xff,0x3a,0x05,0x3d,0x60,0x2f,0x78,0xff,0xff,0x1e,0x60,0xa8,0x62, -0xa2,0xd1,0x20,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0xf4,0x00,0x1e,0x60, -0xf4,0x65,0x0a,0x61,0x07,0x00,0xa2,0xdd,0x58,0x4f,0x64,0x58,0xff,0xff,0x00,0xb9, -0xff,0xff,0x08,0x03,0x00,0x63,0xa5,0xd1,0x5a,0xd3,0xda,0x85,0x00,0xa8,0xcd,0x81, -0xf2,0x02,0xf8,0x02,0xe0,0x00,0x1e,0x60,0xa6,0x62,0x1e,0x60,0xde,0x65,0x3f,0x60, -0x8b,0x63,0x00,0x64,0x5a,0xdb,0xd6,0x80,0xff,0xff,0x04,0x03,0x5a,0xdb,0x5a,0xdb, -0x5a,0xdd,0xf9,0x00,0x1e,0x60,0xf2,0x65,0x00,0x64,0x5a,0xdb,0xd6,0x80,0xff,0xff, -0x02,0x03,0x5a,0xdd,0xfb,0x00,0x2f,0x58,0xff,0xff,0x1e,0x60,0xaa,0x64,0x40,0x41, -0x1e,0x60,0xa8,0x63,0xa3,0xd1,0x00,0x64,0xd0,0x80,0x09,0x61,0x08,0x03,0xbd,0xdb, -0xa3,0xd3,0xff,0xff,0xb0,0x84,0xcd,0x81,0xa3,0xdb,0x06,0xa3,0xf9,0x02,0x1e,0x60, -0xe0,0x63,0xa3,0xd1,0x00,0x64,0xd0,0x80,0x0a,0x61,0x16,0x03,0xbd,0xdb,0x64,0x44, -0xfe,0xa3,0x02,0xa3,0xcd,0x81,0xe8,0x84,0xe3,0x03,0x02,0x05,0xe1,0x03,0xf9,0x00, -0x40,0x42,0xa3,0xd3,0x43,0x44,0x00,0xa8,0x41,0x43,0x02,0x03,0x58,0x4f,0x60,0x58, -0x22,0x44,0x23,0x41,0x24,0x43,0xed,0x00,0x21,0x43,0x1e,0x60,0xe0,0x65,0xd7,0x80, -0xbd,0xd1,0xbd,0xd3,0x01,0x02,0x8f,0x00,0xa0,0x84,0xbd,0xd1,0x43,0x41,0xf7,0x03, -0x3f,0x60,0x90,0x64,0x64,0x58,0x40,0x4f,0x29,0xf2,0xff,0xff,0x60,0x40,0x08,0x26, -0x03,0x00,0x40,0x60,0x2e,0x78,0xff,0xff,0x60,0x40,0x18,0x36,0x17,0x00,0x0c,0x60, -0x44,0x64,0xa0,0xd7,0x58,0x4f,0xff,0xff,0x0f,0xf0,0xbd,0xf1,0x64,0x44,0x60,0x22, -0x10,0x00,0x31,0xf2,0x32,0xf2,0xd0,0x80,0xbe,0xf1,0x0b,0x02,0xd0,0x80,0x33,0xf2, -0x08,0x02,0xbf,0xf1,0xff,0xff,0xd0,0x80,0x0f,0xf0,0x03,0x02,0x41,0x60,0x76,0x78, -0xff,0xff,0x00,0xf4,0xaa,0x60,0xaa,0x65,0x02,0xf2,0x03,0xf0,0xd4,0x80,0x03,0x64, -0x16,0x02,0xd0,0x80,0x00,0x64,0x04,0xf0,0x12,0x02,0xd0,0x80,0xf8,0x7f,0x06,0x02, -0x26,0x46,0x22,0xf0,0x20,0x67,0xb0,0x84,0xa2,0xda,0x09,0x00,0xd0,0x80,0xff,0xff, -0x06,0x02,0x26,0x46,0x22,0xf0,0x40,0x67,0xb0,0x84,0xa2,0xda,0x00,0x00,0x26,0x46, -0x0f,0xf2,0x81,0xf1,0x29,0xf2,0x60,0x40,0x20,0x2a,0x11,0x00,0x5c,0x63,0x60,0x40, -0x02,0x2b,0x62,0x63,0xbd,0xd2,0xbd,0xd2,0xd0,0x80,0x82,0xf1,0x5c,0x02,0xd0,0x80, -0xa3,0xd2,0x83,0xf1,0x58,0x02,0xd0,0x80,0xff,0xff,0x55,0x02,0x00,0x00,0x64,0x60, -0x58,0x4f,0x5a,0x78,0xff,0xff,0x41,0x60,0x4c,0x78,0xff,0xff,0x26,0x46,0x29,0xf2, -0xff,0xff,0xff,0xff,0x0c,0x26,0x47,0x00,0x95,0xf1,0x00,0x63,0xd3,0x80,0xff,0xff, -0xf2,0x02,0x60,0x40,0xb0,0x3a,0x07,0x00,0x5a,0x60,0xa8,0x64,0xa0,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x23,0x00,0x10,0x3a,0x07,0x00,0x5a,0x60,0xac,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1a,0x00,0x30,0x3a,0x07,0x00,0x5a,0x60,0xac,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x11,0x00,0xc0,0x3a,0x07,0x00,0x5a,0x60, -0xae,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x08,0x00,0xa0,0x3a,0x1e,0x00, -0x5a,0x60,0xb0,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x0c,0x60,0x48,0x64, -0xa0,0xd7,0x58,0x4f,0xff,0xff,0x2d,0x00,0xcb,0xf3,0xff,0xff,0x60,0x40,0x03,0x3a, -0x0a,0x00,0x68,0x60,0x58,0x4e,0x89,0x78,0xff,0xff,0x26,0x46,0x04,0x02,0x41,0x60, -0x58,0x4e,0x8c,0x78,0xff,0xff,0x41,0x60,0x76,0x78,0xff,0xff,0x50,0x3a,0x0c,0x00, -0x5a,0x60,0xb6,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x0c,0x60,0x50,0x64, -0xa0,0xd7,0x58,0x4f,0xff,0xff,0x0d,0x00,0x40,0x3a,0x0e,0x00,0x5a,0x60,0xb2,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x0c,0x60,0x4a,0x64,0xa0,0xd7,0x58,0x4f, -0xff,0xff,0x41,0x60,0x72,0x78,0xff,0xff,0x90,0x3a,0x10,0x00,0x41,0x60,0x58,0x4e, -0x7d,0x78,0xff,0xff,0x0c,0x60,0x52,0x64,0xa0,0xd7,0x58,0x4f,0xff,0xff,0x5a,0x60, -0xa4,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0xeb,0x00,0x80,0x3a,0x6e,0x00, -0xcb,0xf3,0x20,0x40,0x40,0x26,0x32,0x00,0xfd,0xa0,0xfc,0xa0,0x01,0x03,0x29,0x02, -0x81,0xf1,0x31,0xf2,0x32,0xf2,0xd0,0x80,0x82,0xf1,0xae,0x02,0xd0,0x80,0x33,0xf2, -0x83,0xf1,0xaa,0x02,0xd0,0x80,0x70,0xf3,0xa7,0x02,0xdc,0x84,0xcb,0xf1,0x70,0xfb, -0x00,0x64,0x71,0xfb,0x0a,0x60,0x02,0x64,0x6e,0xfb,0x64,0x40,0x03,0x36,0x50,0x00, -0x5a,0x60,0x9c,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x0c,0x60,0x4c,0x64, -0xa0,0xd7,0x58,0x4f,0xff,0xff,0x0c,0x60,0x4e,0x64,0xa0,0xd7,0x58,0x4f,0xff,0xff, -0x3d,0x00,0xd5,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x08,0x04,0x0c,0x60,0x50,0x64, -0xa0,0xd7,0x58,0x4f,0xff,0xff,0x41,0x60,0x72,0x78,0xff,0xff,0x16,0x60,0x42,0x62, -0xa2,0xd3,0xff,0xff,0xfc,0xa0,0x81,0xf3,0x29,0x02,0x00,0xa0,0x31,0xf0,0x13,0x03, -0xd0,0x80,0x82,0xf3,0x32,0xf0,0x0f,0x02,0xd0,0x80,0x83,0xf3,0x33,0xf0,0x0b,0x02, -0xd0,0x80,0x70,0xf3,0x08,0x02,0xdc,0x84,0x70,0xfb,0x00,0x64,0x71,0xfb,0x0a,0x60, -0x02,0x64,0x6e,0xfb,0x13,0x00,0x59,0x60,0x20,0x64,0xa0,0xd3,0xff,0xff,0x60,0x40, -0xff,0x22,0x0c,0x00,0x68,0x60,0x58,0x4e,0x89,0x78,0xff,0xff,0x07,0x02,0x0f,0x4e, -0x26,0x46,0x67,0x60,0x58,0x4f,0x13,0x78,0xff,0xff,0x0e,0x4f,0x26,0x46,0x56,0x00, -0x29,0xf0,0x3d,0x60,0x0e,0x65,0x0a,0x64,0x64,0x40,0x10,0x2b,0xa5,0xdb,0x68,0x60, -0xcc,0x62,0x90,0x60,0x30,0x64,0xa2,0xdb,0x41,0x60,0x58,0x4e,0x7d,0x78,0xff,0xff, -0xa4,0xf3,0x5e,0xf1,0x60,0x45,0x73,0x44,0x64,0x40,0x04,0x2a,0x04,0x00,0xd4,0x84, -0xe7,0xa0,0x96,0x0e,0x95,0x04,0x5a,0x60,0x9c,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x0c,0x60,0x4c,0x64,0xa0,0xd7,0x58,0x4f,0xff,0xff,0x0c,0x60,0x4e,0x64, -0xa0,0xd7,0x58,0x4f,0xff,0xff,0xd2,0x00,0x66,0x60,0xd8,0x62,0xa2,0xd3,0xff,0xff, -0x81,0xa0,0xff,0xa0,0x23,0x03,0x0f,0x02,0x41,0x60,0x58,0x4e,0xee,0x78,0xff,0xff, -0xff,0xa1,0x26,0x46,0x1b,0x02,0x66,0x60,0xd8,0x62,0x7f,0x64,0xa2,0xdb,0xba,0xff, -0xff,0xff,0xaf,0xff,0x13,0x00,0x3c,0x60,0x82,0x62,0x3c,0x60,0x6a,0x64,0xa2,0xdb, -0x26,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x00,0x64,0x40,0x46, -0xd2,0xfe,0x08,0x00,0x66,0x44,0x00,0xbc,0xff,0xff,0x04,0x03,0x3e,0x60,0x58,0x4e, -0x91,0x78,0xff,0xff,0x56,0xf7,0xff,0xff,0xff,0xff,0x76,0xf3,0x3c,0x45,0xd4,0x80, -0x28,0x60,0x60,0x62,0x07,0x02,0x80,0x64,0xa2,0xdb,0xff,0xff,0xc0,0xfe,0x00,0x64, -0xa2,0xdb,0x71,0xfb,0x2e,0x58,0xff,0xff,0x26,0x46,0x28,0x60,0xda,0x63,0x00,0xf4, -0x02,0xf2,0xbd,0xdb,0xff,0xff,0x03,0xf2,0xbd,0xdb,0x04,0xf2,0xff,0xff,0xbd,0xdb, -0x05,0xf2,0xa3,0xdb,0xfa,0xa3,0x26,0x46,0x00,0x60,0x00,0x65,0xa3,0xd3,0x23,0xf0, -0x00,0x61,0xd0,0x84,0xf1,0x81,0xd4,0x84,0xf1,0x81,0xbd,0xdb,0xa3,0xd3,0x03,0xb1, -0x03,0xa9,0x24,0xf0,0x42,0xfe,0x01,0x03,0xcc,0x84,0xf1,0x81,0xd0,0x84,0xf1,0x81, -0xbd,0xdb,0xa3,0xd3,0x03,0xb1,0x03,0xa9,0x27,0xf0,0x42,0xfe,0x01,0x03,0xcc,0x84, -0xf1,0x81,0xd0,0x84,0xf1,0x81,0xbd,0xdb,0xa3,0xd3,0x03,0xb1,0x03,0xa9,0x28,0xf0, -0x01,0x03,0xcc,0x84,0xd0,0x84,0xa3,0xdb,0x26,0x0e,0x28,0x60,0xda,0x63,0xbd,0xd3, -0x00,0x65,0x00,0x61,0xd4,0x84,0xbd,0xd3,0xf1,0x81,0x01,0xa9,0x42,0xfe,0x01,0x03, -0xcc,0x84,0xf1,0x81,0x01,0x65,0xd4,0x84,0xf1,0x81,0xbd,0xd3,0x03,0xb1,0x03,0xa9, -0x42,0xfe,0x01,0x03,0xcc,0x84,0xf1,0x81,0x00,0x65,0xd4,0x84,0xf1,0x81,0xa3,0xd3, -0x03,0xb1,0x03,0xa9,0x42,0xfe,0x01,0x03,0xcc,0x84,0xd4,0x84,0x04,0x0e,0x66,0x60, -0x9a,0x62,0x01,0x64,0xa2,0xdb,0x26,0x46,0x2e,0x58,0xff,0xff,0x66,0x60,0xd6,0x62, -0x2e,0x44,0xa2,0xdb,0x00,0x64,0x38,0xf2,0x40,0x48,0x40,0x4c,0xa0,0xa0,0xff,0xff, -0x43,0x04,0x00,0xf4,0x01,0xf2,0x04,0x63,0x60,0x41,0x66,0x60,0xe6,0x62,0x00,0x64, -0xa2,0xdb,0x42,0x60,0x58,0x4e,0x44,0x78,0xff,0xff,0x36,0x03,0xff,0x65,0xd4,0x80, -0xff,0xff,0xf7,0x02,0x00,0x64,0xdc,0x84,0x40,0x4d,0x42,0x60,0x58,0x4e,0x44,0x78, -0xff,0xff,0x2a,0x03,0xff,0x65,0xd4,0x80,0x60,0x42,0x2d,0x44,0xf4,0x03,0xfa,0xa0, -0xff,0xff,0xe3,0x04,0x06,0x64,0x40,0x4d,0x66,0x60,0xda,0x65,0x62,0x44,0x05,0x00, -0x42,0x60,0x58,0x4e,0x44,0x78,0xff,0xff,0x17,0x03,0xa5,0xd1,0xda,0x85,0xd0,0x80, -0xff,0xff,0xdc,0x02,0x2d,0x44,0xcc,0x84,0x40,0x4d,0xf2,0x02,0x06,0x64,0x40,0x4d, -0x66,0x60,0xda,0x65,0x66,0x60,0xe6,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xf0,0xa0, -0xa2,0xdb,0xe6,0x02,0x01,0x61,0x01,0x00,0x00,0x61,0x66,0x60,0xd6,0x62,0xa2,0xd3, -0xff,0xff,0x40,0x4e,0x2e,0x58,0xff,0xff,0x2c,0x44,0xcc,0x84,0x40,0x4c,0x11,0x0e, -0xcd,0x81,0xff,0xff,0x05,0x0d,0x00,0xf4,0x01,0xf2,0x04,0x63,0xcc,0x84,0x60,0x41, -0x28,0x44,0x01,0xac,0x40,0x48,0x07,0x02,0xbd,0xd2,0x01,0xb8,0x60,0x47,0x00,0x7f, -0x05,0x00,0xdc,0x84,0x03,0x00,0xa3,0xd2,0xff,0xff,0x00,0x7f,0x2e,0x58,0xff,0xff, -0x01,0x64,0xcb,0xfb,0x1e,0x60,0xc8,0x62,0x00,0x64,0xa2,0xdb,0x00,0x60,0x08,0x63, -0x01,0x60,0x78,0x61,0x16,0x60,0xb4,0x64,0x58,0xd1,0x59,0xd9,0xfd,0x1f,0x00,0x60, -0x72,0x63,0x16,0x60,0x40,0x61,0x16,0x60,0xbe,0x64,0x58,0xd1,0x59,0xd9,0xfd,0x1f, -0xd5,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x14,0x03,0x18,0x60,0xd0,0x63,0x17,0x60, -0x82,0x61,0x13,0x64,0xbd,0xd1,0xa1,0xd9,0xff,0xa4,0x02,0xa1,0xfb,0x02,0x1f,0x60, -0x38,0x63,0x0a,0xa3,0x05,0x64,0xa3,0xdb,0x0c,0xa3,0xa3,0xdb,0x04,0xa3,0xa3,0xdb, -0x25,0x00,0x1f,0x60,0x56,0x62,0x00,0x64,0xa2,0xdb,0x1f,0x60,0x1c,0x63,0xa5,0xf3, -0x01,0x61,0x60,0x45,0x65,0x44,0xe8,0x85,0x05,0x64,0x02,0x28,0x00,0x64,0xbd,0xdb, -0x00,0xa0,0xff,0xff,0x0d,0x03,0x1f,0x60,0x56,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4, -0xa2,0xdb,0xff,0xa0,0xff,0xff,0x04,0x02,0x1f,0x60,0x54,0x62,0x61,0x44,0xa2,0xdb, -0xdd,0x81,0xff,0xff,0x61,0x44,0xf2,0xa0,0xff,0xff,0xe4,0x06,0x59,0x60,0x1e,0x61, -0x16,0x60,0x42,0x64,0x20,0x63,0x58,0xd1,0x59,0xd9,0xfd,0x1f,0xa8,0xf1,0x80,0xf9, -0x1f,0xf1,0x66,0x60,0xf6,0x65,0x0a,0x64,0x64,0x40,0x10,0x2a,0x04,0x64,0xa5,0xdb, -0x32,0x40,0x01,0x26,0x07,0x00,0x00,0x60,0x1a,0x63,0x01,0x60,0x00,0x61,0x00,0x64, -0x59,0xdb,0xfe,0x1f,0x40,0x40,0xc0,0xf3,0xff,0xff,0x40,0x4a,0x1e,0x60,0xc8,0x62, -0x00,0x64,0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xca,0x62,0x40,0x60, -0x00,0x64,0xa2,0xdb,0x42,0x60,0xd6,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x3c,0x60,0xa2,0x62,0x2a,0x44,0xa2,0xdb,0xca,0x82,0x08,0x64,0xa2,0xdb,0xff,0xff, -0x2d,0xff,0x1e,0x60,0xca,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x42,0x60,0xfc,0x64, -0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc8,0x62,0x00,0x64,0xa2,0xdb, -0xbe,0xfe,0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb, -0xcf,0xfe,0x61,0x60,0xc8,0x62,0x0c,0x64,0xa2,0xdb,0x64,0x60,0x58,0x62,0x01,0x64, -0xa2,0xdb,0xd5,0xf1,0x03,0x64,0x64,0x40,0x00,0x3a,0xd5,0xfb,0x95,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x02,0x02,0x00,0x64,0x62,0xfb,0x67,0x60,0x74,0x62,0xa2,0xd3, -0xff,0xff,0x60,0x40,0x00,0x3a,0x2b,0x00,0x01,0x64,0xa2,0xdb,0x12,0x60,0x34,0x65, -0x72,0x44,0xb4,0x83,0x00,0x7f,0x60,0x5c,0x10,0x61,0x40,0x60,0x0b,0x65,0x63,0x44, -0x00,0x63,0xe8,0x80,0xf8,0x84,0x02,0x24,0x94,0x84,0xf3,0x83,0xcd,0x81,0xff,0xff, -0xf8,0x02,0x60,0x47,0x60,0x45,0x00,0x7f,0x39,0xfb,0x65,0x44,0x00,0x7e,0xb0,0x84, -0x38,0xfb,0x66,0x60,0xaa,0x63,0xbd,0xf3,0xff,0xff,0x02,0xbc,0xbd,0xdb,0x39,0xf3, -0xbe,0xf1,0x60,0x47,0x00,0x7e,0xb0,0x84,0xbd,0xdb,0x38,0xf3,0xa3,0xdb,0x0f,0x4e, -0x5c,0x60,0x58,0x4f,0x1f,0x78,0xff,0xff,0x0e,0x4f,0x0f,0x4e,0x58,0x60,0x58,0x4f, -0xdd,0x78,0xff,0xff,0x0e,0x4f,0x0f,0x4e,0x5e,0x60,0x58,0x4f,0x53,0x78,0xff,0xff, -0x0e,0x4f,0x0f,0x4e,0x44,0x60,0x58,0x4f,0x1e,0x78,0xff,0xff,0x0e,0x4f,0x1e,0x60, -0xc8,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc8,0x62, -0x00,0x64,0xa2,0xdb,0x02,0x64,0x8b,0xfb,0xff,0xff,0xc1,0xfe,0x1e,0x60,0xe0,0x62, -0xa2,0xd1,0x00,0x60,0xf4,0x86,0x7e,0x00,0x00,0x10,0x1f,0x64,0xb0,0x84,0xa2,0xdb, -0xcf,0xfe,0x1e,0x60,0xc8,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x1e,0x60,0xca,0x62,0x00,0x60,0x08,0x64,0xa2,0xdb,0x43,0x60, -0x92,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x8b,0xf3,0x00,0x65,0xd4,0x80, -0xff,0xff,0x0b,0x03,0x1e,0x60,0xca,0x62,0x80,0x60,0x00,0x64,0xa2,0xdb,0x43,0x60, -0x92,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc8,0x62,0x00,0x64, -0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xca,0x62,0x20,0x60,0x00,0x64, -0xa2,0xdb,0x43,0x60,0xb4,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x3c,0x60, -0xa2,0x62,0xca,0x82,0x06,0x64,0xa2,0xdb,0xff,0xff,0x2d,0xff,0x1e,0x60,0xc8,0x62, -0x00,0x64,0xa2,0xdb,0x5a,0xdb,0xbe,0xfe,0x3c,0x60,0x28,0x61,0x43,0x60,0x58,0x4e, -0xef,0x78,0xff,0xff,0x3c,0x60,0x2e,0x61,0x43,0x60,0x58,0x4e,0xef,0x78,0xff,0xff, -0x3c,0x60,0x46,0x61,0x43,0x60,0x58,0x4e,0xef,0x78,0xff,0xff,0x3c,0x60,0x6a,0x61, -0x43,0x60,0x58,0x4e,0xef,0x78,0xff,0xff,0x3c,0x60,0x4c,0x61,0x43,0x60,0x58,0x4e, -0xef,0x78,0xff,0xff,0x3c,0x60,0x76,0x61,0x43,0x60,0x58,0x4e,0xef,0x78,0xff,0xff, -0xc5,0xfe,0x01,0x64,0xcb,0xfb,0x02,0x65,0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff, -0x2f,0x58,0xff,0xff,0xa1,0xd3,0x0e,0x57,0x00,0xa8,0x60,0x46,0x28,0x03,0x09,0xf0, -0x0e,0xf2,0x44,0x4c,0x20,0xb0,0x01,0xb0,0x0b,0x03,0x3c,0x60,0x82,0x62,0x00,0x64, -0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x15,0x00, -0x14,0x02,0x0f,0x4e,0x46,0x45,0x3c,0x60,0x82,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44, -0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xa2,0xff,0x1a,0x60,0x58,0x4f, -0x9e,0x78,0xff,0xff,0xa3,0xff,0xd1,0xfe,0x0e,0x4f,0x2c,0x44,0xd5,0x00,0x37,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0x00,0x60,0x02,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x1e,0x60,0xc4,0x62, -0x00,0x60,0x02,0x64,0xa2,0xdb,0x44,0x60,0x36,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x16,0x60,0x42,0x62,0xa2,0xd3, -0xff,0xff,0x03,0xa8,0x04,0xa8,0x02,0x03,0x04,0x03,0x06,0x00,0x45,0x60,0x25,0x78, -0xff,0xff,0x45,0x60,0x6b,0x78,0xff,0xff,0x02,0x64,0xcb,0xfb,0x00,0x64,0x81,0xfb, -0x82,0xfb,0x83,0xfb,0x66,0x60,0xc0,0x62,0x01,0x64,0xa2,0xdb,0x16,0x60,0x44,0x64, -0x5b,0xfb,0x0f,0x4e,0x52,0x60,0x58,0x4f,0xaa,0x78,0xff,0xff,0x0e,0x4f,0x1e,0x60, -0xc4,0x62,0x10,0x60,0x00,0x64,0xa2,0xdb,0x44,0x60,0x67,0x64,0x5a,0xdb,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x59,0x60,0xb4,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x88,0xf1,0x27,0x60,0xe0,0x63,0xd3,0x80, -0xff,0xff,0x03,0x03,0x4b,0x60,0x47,0x78,0xff,0xff,0xc0,0xf3,0xc6,0xf3,0x40,0x4a, -0x00,0xa8,0xff,0xff,0x03,0x03,0x45,0x60,0x6b,0x78,0xff,0xff,0x3e,0x60,0x58,0x4e, -0xae,0x78,0xff,0xff,0x02,0x64,0xcb,0xfb,0x64,0x60,0x58,0x62,0xa2,0xd3,0xff,0xff, -0x9d,0xa0,0x01,0xa4,0x03,0x05,0xec,0xa0,0xa2,0xdb,0x18,0x06,0xa9,0xf1,0x28,0x60, -0x7e,0x64,0xa0,0xd9,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64,0xa2,0xdb,0x02,0x64, -0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xc4,0x62,0x00,0x60,0x04,0x64,0xa2,0xdb, -0x44,0x60,0xc7,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0xe1,0xf3,0xff,0xff, -0x00,0xa0,0x60,0x5c,0x17,0x03,0x28,0x60,0x7e,0x64,0xa0,0xd9,0x3c,0x60,0xb2,0x62, -0x28,0x60,0x7a,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60, -0xc4,0x62,0x00,0x60,0x04,0x64,0xa2,0xdb,0x44,0x60,0xc7,0x64,0x5a,0xdb,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0xd5,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x18,0x03,0x66,0x60,0xc2,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0x88,0xa0,0xa2,0xdb,0x10,0x04,0x00,0x64,0xa2,0xdb,0x03,0x64,0xd5,0xfb,0x0a,0x65, -0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x1f,0x60,0x1c,0x63,0x0e,0x64,0x00,0x7c, -0xcc,0x84,0xbd,0xd9,0xfd,0x02,0x67,0x60,0x76,0x65,0xa5,0xd3,0xff,0xff,0x60,0x40, -0x03,0x22,0x33,0x00,0x01,0x2a,0x0c,0x00,0x1e,0x60,0x92,0x63,0xa3,0xd1,0x66,0x60, -0xf0,0x65,0xad,0xf3,0xa5,0xd3,0x60,0x45,0xc4,0x84,0xd0,0x80,0xff,0xff,0x25,0x0d, -0x67,0x60,0x76,0x65,0xa5,0xd3,0xff,0xff,0x60,0x45,0xfd,0xb4,0xa2,0xdb,0x20,0x44, -0xb4,0x84,0x40,0x40,0x59,0x60,0xbc,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x0f,0x4e,0x52,0x60,0x58,0x4f,0xaa,0x78,0xff,0xff,0x0e,0x4f,0x1e,0x60,0xc4,0x62, -0x10,0x60,0x00,0x64,0xa2,0xdb,0x45,0x60,0x1e,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x44,0x60,0x49,0x78,0xff,0xff, -0x05,0x64,0xcb,0xfb,0xc5,0xf3,0x47,0xfb,0x00,0x64,0xc0,0xf1,0x85,0xfb,0x44,0x4a, -0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60, -0xc4,0x62,0x40,0x60,0x00,0x64,0xa2,0xdb,0x45,0x60,0x2d,0x64,0x5a,0xdb,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x3c,0x60,0xa2,0x62,0x2a,0x44,0xa2,0xdb,0xca,0x82,0x1e,0x64, -0xa2,0xdb,0xff,0xff,0x2d,0xff,0x1e,0x60,0xc4,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb, -0x45,0x60,0x53,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62, -0x00,0x64,0xa2,0xdb,0xbe,0xfe,0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60,0x00,0x64, -0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x01,0x64,0x8c,0xfb,0x02,0x64,0x90,0xfb,0x01,0x65, -0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x2f,0x58,0xff,0xff,0xd5,0xf3,0xff,0xff, -0xfd,0xa0,0xff,0xff,0x05,0x05,0x0c,0x60,0x50,0x62,0x67,0x60,0x13,0x64,0xa2,0xdb, -0x0c,0x60,0x48,0x62,0x67,0x60,0xd6,0x64,0xa2,0xdb,0x59,0x60,0x74,0x62,0x28,0x60, -0xe2,0x64,0xa2,0xdb,0x77,0xf5,0x00,0x64,0x22,0xfa,0x38,0xfa,0x08,0x64,0x28,0xfa, -0x18,0x60,0x20,0x64,0x0e,0xfa,0x90,0x64,0x29,0xfa,0x66,0x60,0xa4,0x62,0x12,0x60, -0x34,0x65,0x72,0x44,0xb4,0x84,0xa2,0xdb,0xc0,0xf3,0x7f,0xfb,0x66,0x60,0x96,0x63, -0x00,0x64,0xbd,0xdb,0xbd,0xdb,0xa3,0xdb,0xff,0xff,0x71,0xfb,0x70,0xfb,0x81,0xfb, -0xff,0xff,0x82,0xfb,0x83,0xfb,0xff,0xff,0xc5,0xf3,0x47,0xfb,0x16,0x60,0xbe,0x64, -0xa0,0xd3,0x86,0xfb,0x66,0x60,0xa2,0x63,0x06,0x64,0xa3,0xdb,0x01,0x64,0x73,0xfb, -0x39,0x60,0xf2,0x62,0x00,0x64,0xa2,0xdb,0x5e,0xfb,0x68,0x60,0xcc,0x62,0x90,0x60, -0x90,0x64,0xa2,0xdb,0x66,0x60,0xa6,0x63,0x02,0x64,0xcb,0xfb,0xa3,0xdb,0x28,0x60, -0xd2,0x63,0x39,0x60,0xb2,0x7c,0x10,0x65,0x00,0x64,0x47,0xdb,0xd3,0x80,0x47,0xdb, -0xfc,0x04,0x16,0x60,0x44,0x64,0x5b,0xfb,0x0f,0x4e,0x52,0x60,0x58,0x4f,0xaa,0x78, -0xff,0xff,0x0e,0x4f,0x1e,0x60,0xc4,0x62,0x10,0x60,0x00,0x64,0xa2,0xdb,0x45,0x60, -0xda,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0x59,0x60,0xb4,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x39,0x60, -0xf2,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x09,0x03,0x4b,0x60,0x58,0x4e, -0x2b,0x78,0xff,0xff,0x04,0x02,0x46,0x60,0x97,0x78,0xff,0xff,0xd2,0x00,0x59,0x60, -0x20,0x62,0xa2,0xd3,0x01,0x63,0x60,0x40,0x00,0x3a,0x6e,0xfd,0x0a,0x61,0x66,0x60, -0xa4,0x62,0x40,0x60,0x0b,0x65,0xa2,0xd3,0x00,0x63,0xe8,0x80,0xf8,0x84,0x02,0x24, -0x94,0x84,0xf3,0x83,0xcd,0x81,0xff,0xff,0xf8,0x02,0xa2,0xdb,0x64,0xa3,0x28,0x60, -0x7e,0x62,0xa2,0xdd,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64,0xa2,0xdb,0x02,0x64, -0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xc4,0x62,0x00,0x60,0x04,0x64,0xa2,0xdb, -0x46,0x60,0x23,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62, -0x00,0x64,0xa2,0xdb,0x00,0x64,0x6e,0xfb,0x39,0x60,0xf2,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa0,0x60,0x45,0x67,0x02,0x66,0x60,0xa2,0x62,0xa2,0xd3,0xff,0xff,0xcc,0x84, -0xa2,0xdb,0xbc,0x02,0x59,0x60,0x20,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff, -0x10,0x03,0x66,0x60,0xa8,0x62,0xa2,0xd1,0x73,0xf3,0xff,0xff,0xfd,0xa0,0xfe,0xa0, -0x2e,0x03,0x07,0x03,0x64,0x44,0x00,0x3a,0x2a,0x00,0x65,0x44,0x00,0xa0,0xff,0xff, -0x26,0x03,0x16,0x60,0x88,0x62,0xa2,0xd1,0x04,0x7f,0x64,0x40,0xff,0x26,0x08,0x7f, -0x60,0x43,0x28,0x60,0x7e,0x62,0xa2,0xdd,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64, -0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xc4,0x62,0x00,0x60, -0x04,0x64,0xa2,0xdb,0x46,0x60,0x6d,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x45,0x60,0x93,0x78,0xff,0xff,0x66,0x60, -0xaa,0x63,0xbd,0xd3,0x81,0xfb,0xbd,0xd3,0xff,0xff,0x82,0xfb,0xa3,0xd3,0xff,0xff, -0xdc,0x84,0xa3,0xdb,0x83,0xfb,0xff,0xff,0xc1,0xf3,0x86,0xfb,0x73,0xf3,0xff,0xff, -0x04,0xbc,0x73,0xfb,0x04,0x64,0x5e,0xfb,0x68,0x60,0xcc,0x62,0x90,0x60,0x91,0x64, -0xa2,0xdb,0x66,0x60,0x9e,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x47,0x60, -0x1a,0x78,0xff,0xff,0x39,0x60,0xf2,0x63,0xbd,0xd1,0x81,0xf9,0xbd,0xd1,0xff,0xff, -0x82,0xf9,0xbd,0xd1,0x83,0xf9,0x08,0xa3,0xbd,0xd1,0x80,0xf9,0xff,0xff,0xbd,0xd1, -0xbd,0xd1,0x59,0x60,0x20,0x65,0xa5,0xd9,0x02,0xa2,0x62,0x45,0x64,0x41,0xdd,0x81, -0xe9,0x81,0xbd,0xd1,0xa5,0xd9,0xda,0x82,0xcd,0x81,0x62,0x45,0xfa,0x02,0x3a,0x60, -0x26,0x63,0xbd,0xd3,0x00,0x61,0x60,0x45,0xbd,0xd3,0xff,0xff,0x7f,0xb4,0x02,0x36, -0x01,0xb9,0x04,0x36,0x02,0xb9,0x0b,0x36,0x04,0xb9,0x16,0x36,0x08,0xb9,0x65,0x44, -0xcc,0x84,0x60,0x45,0xf1,0x02,0xc9,0xf1,0x61,0x44,0xa0,0x84,0xc9,0xfb,0x00,0x61, -0x60,0x45,0x3a,0x60,0x28,0x63,0x65,0x40,0x01,0x2a,0x03,0x00,0x02,0x64,0xbd,0xdb, -0xdd,0x81,0x65,0x40,0x02,0x2a,0x03,0x00,0x04,0x64,0xbd,0xdb,0xdd,0x81,0x65,0x40, -0x04,0x2a,0x03,0x00,0x0b,0x64,0xbd,0xdb,0xdd,0x81,0x65,0x40,0x08,0x2a,0x03,0x00, -0x16,0x64,0xbd,0xdb,0xdd,0x81,0x3a,0x60,0x26,0x63,0x61,0x44,0xbd,0xdb,0x17,0x60, -0xd2,0x65,0x61,0x44,0xa5,0xdb,0xda,0x82,0x62,0x45,0xbd,0xd3,0xbd,0xd1,0x60,0x47, -0xb0,0x87,0xa5,0xda,0xda,0x85,0xcd,0x81,0xcd,0x81,0x01,0x03,0xf6,0x02,0x3a,0x60, -0x32,0x63,0xbd,0xd1,0x17,0x60,0xdc,0x62,0xa2,0xd3,0xff,0xff,0xa0,0x84,0xa2,0xdb, -0x60,0x45,0xbd,0xd3,0x7f,0xfb,0xff,0xff,0xbd,0xd3,0x86,0xfb,0x65,0x44,0x00,0x65, -0x60,0x40,0x02,0x26,0x01,0x65,0x60,0x40,0x04,0x26,0x02,0x65,0x60,0x40,0x08,0x26, -0x03,0x65,0x59,0x60,0x68,0x62,0x65,0x44,0xa2,0xdb,0x16,0x60,0x88,0x63,0xa3,0xd1, -0x17,0x60,0x06,0x63,0xa3,0xd9,0x86,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x02,0x02, -0xa3,0xdb,0x05,0x00,0xfd,0xa0,0xff,0xff,0x02,0x05,0x03,0x64,0x86,0xfb,0xff,0x60, -0xff,0x64,0x62,0xfb,0x76,0xf5,0x66,0x60,0x58,0x4e,0x3a,0x78,0xff,0xff,0x17,0x60, -0xdc,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff,0x01,0x2a,0x02,0x00,0x00,0x64,0x09,0x00, -0x02,0x2a,0x02,0x00,0x01,0x64,0x05,0x00,0x04,0x2a,0x02,0x00,0x02,0x64,0x01,0x00, -0x03,0x64,0x13,0xfa,0x77,0xf5,0x13,0xfa,0xff,0xff,0xbd,0xf1,0x2e,0xf8,0xbe,0xf1, -0xff,0xff,0x2f,0xf8,0xbf,0xf1,0x30,0xf8,0xff,0xff,0x81,0xf1,0x31,0xf8,0x82,0xf1, -0xff,0xff,0x32,0xf8,0x83,0xf1,0x33,0xf8,0x66,0x60,0xa6,0x63,0x03,0x64,0xcb,0xfb, -0xa3,0xdb,0x00,0x64,0x7f,0xf1,0x85,0xfb,0x44,0x4a,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xc4,0x62,0x40,0x60,0x00,0x64, -0xa2,0xdb,0x47,0x60,0x62,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x3c,0x60, -0xa2,0x62,0x2a,0x44,0xa2,0xdb,0xca,0x82,0x1e,0x64,0xa2,0xdb,0xff,0xff,0x2d,0xff, -0x1e,0x60,0xc4,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x47,0x60,0x88,0x64,0x5a,0xdb, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0xbe,0xfe, -0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe, -0x01,0x64,0x8c,0xfb,0x02,0x64,0x90,0xfb,0x68,0x60,0xcc,0x62,0x90,0x60,0x70,0x64, -0xa2,0xdb,0x20,0x44,0x10,0x26,0x05,0x00,0x01,0x65,0x3d,0x60,0x58,0x4e,0x32,0x78, -0xff,0xff,0x20,0x44,0xef,0xb4,0x40,0x40,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60, -0x80,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x1e,0x60,0xc4,0x62,0x00,0x60, -0x02,0x64,0xa2,0xdb,0x47,0x60,0xbd,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x3d,0x60,0x1c,0x62,0xa2,0xd3,0x10,0x61, -0x00,0x63,0x60,0x45,0xe0,0x84,0xa2,0xdb,0x65,0x44,0x01,0x26,0xdf,0x83,0xcd,0x81, -0xe8,0x84,0xfb,0x02,0x63,0x44,0xfc,0xa0,0xff,0xff,0x0d,0x04,0x3d,0x60,0x1e,0x62, -0x32,0x64,0xa2,0xdb,0x62,0xf3,0xff,0xff,0x60,0x40,0x00,0x36,0x13,0x00,0x17,0x60, -0x06,0x62,0x00,0x64,0xa2,0xdb,0x3d,0x60,0x1e,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0, -0xcc,0x84,0x08,0x03,0xa2,0xdb,0x06,0x02,0x3d,0x60,0x20,0x62,0xa2,0xd1,0x17,0x60, -0x06,0x62,0xa2,0xd9,0x65,0xf1,0x00,0x64,0x6a,0xfb,0x6b,0xfb,0xff,0xff,0x6d,0xfb, -0x6f,0xfb,0x64,0x40,0x02,0x26,0x03,0x00,0x4a,0x60,0xfc,0x78,0xff,0xff,0x1e,0x60, -0xd4,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe, -0x66,0x60,0xb2,0x65,0x86,0xf3,0xa4,0xf1,0xa5,0xdb,0xff,0xff,0xff,0x22,0x06,0x00, -0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xc0,0x84,0x6c,0xfb,0x5e,0xf3,0xff,0xff, -0x04,0xb0,0xff,0xff,0x15,0x03,0x02,0x64,0x8c,0xfb,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0x7f,0x60,0xff,0x64,0xa0,0x84,0xa2,0xdb,0x1e,0x60,0xc4,0x62,0x80,0x60,0x00,0x64, -0xa2,0xdb,0x48,0x60,0x30,0x64,0x5a,0xdb,0xcf,0xfe,0xc1,0xfe,0x2f,0x58,0xff,0xff, -0x49,0x60,0xcc,0x78,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x64, -0xa0,0x84,0xa2,0xdb,0x8c,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0xef,0x02,0x1e,0x60, -0xc2,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84, -0x5a,0xdb,0x6e,0xf3,0x60,0x40,0x02,0x26,0x32,0x00,0x76,0xf5,0x80,0x64,0x29,0xfa, -0x00,0x63,0x38,0xf2,0x22,0xfc,0x17,0xfa,0x1c,0x64,0x21,0xfa,0x15,0xfc,0x16,0xfc, -0x01,0x64,0x14,0xfa,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x3c,0x60,0x82,0x62, -0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0xc1,0xfe,0x1e,0x60,0xc4,0x62,0x00,0x60,0x01,0x64,0xa2,0xdb,0x48,0x60, -0x72,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0xff,0x60,0xfe,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0x86,0xf3, -0xff,0xff,0x00,0xa0,0xff,0xff,0x2f,0x03,0x3c,0x60,0x28,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa8,0x60,0x46,0x25,0x03,0x40,0x48,0x00,0x64,0x40,0x4c,0x3c,0x60,0x2a,0x62, -0xa2,0xd3,0x28,0x45,0xd4,0x80,0x60,0x46,0x23,0x03,0x2b,0xf2,0xff,0xff,0xff,0xff, -0x01,0x2a,0x14,0x00,0x09,0xf2,0xff,0xff,0x40,0x4d,0x3c,0x60,0x82,0x62,0x3c,0x60, -0x28,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0e,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff, -0x01,0x64,0x40,0x4c,0x2d,0x44,0x00,0xbc,0x60,0x46,0xe0,0x03,0x0a,0xf2,0xe1,0x00, -0x49,0x60,0x99,0x78,0xff,0xff,0x01,0x64,0x6d,0xfb,0x49,0x60,0xc2,0x78,0xff,0xff, -0x2c,0x44,0x01,0x2a,0x11,0x00,0x28,0x46,0x2b,0xf2,0xff,0xff,0xff,0xff,0x01,0x2a, -0x0b,0x00,0x3c,0x60,0x82,0x62,0x3c,0x60,0x28,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb, -0x0e,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x3c,0x60,0x28,0x62,0xa2,0xd3,0xff,0xff, -0x00,0xa8,0x60,0x46,0x2b,0xf2,0xff,0xff,0xff,0xff,0x01,0x2a,0x31,0x00,0x4b,0x60, -0x58,0x4e,0x03,0x78,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xc1,0xfe,0x1e,0x60,0xc4,0x62,0x00,0x60,0x01,0x64,0xa2,0xdb, -0x48,0x60,0xf3,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62, -0xa2,0xd1,0xff,0x60,0xfe,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb, -0x77,0xf5,0x22,0xf2,0xff,0xff,0xff,0xff,0x0f,0x26,0x02,0x00,0x01,0x64,0x6d,0xfb, -0x01,0x64,0x6f,0xfb,0x3c,0x60,0x28,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46, -0x40,0x48,0x00,0xbc,0x60,0x46,0x03,0x02,0x49,0x60,0x99,0x78,0xff,0xff,0x6c,0xf3, -0xa4,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x7f,0x0e,0x2b,0xf2,0xff,0xff,0x01,0xb0, -0x19,0xf2,0x77,0x02,0x00,0xbc,0x60,0x43,0x6b,0x03,0xa3,0xd3,0xff,0xff,0xff,0xff, -0x02,0x2a,0x63,0x00,0x69,0x60,0x58,0x4e,0x9b,0x78,0xff,0xff,0x6a,0x03,0x69,0x60, -0x58,0x4e,0xb5,0x78,0xff,0xff,0x65,0x03,0x66,0x44,0x69,0xfb,0x4b,0x60,0x58,0x4e, -0x0a,0x78,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x3c,0x60,0x82,0x62, -0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0xc1,0xfe,0x1e,0x60,0xc4,0x62,0x00,0x60,0x01,0x64,0xa2,0xdb,0x49,0x60, -0x52,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0xff,0x60,0xfe,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0x77,0xf5, -0x22,0xf2,0x69,0xf5,0x0f,0xb0,0x46,0x48,0x07,0x02,0x69,0x60,0x58,0x4e,0xb9,0x78, -0xff,0xff,0x00,0x64,0x15,0xfa,0x21,0x00,0x69,0x60,0x58,0x4e,0xcc,0x78,0xff,0xff, -0x15,0xf2,0xff,0xff,0x01,0xa4,0xe7,0xa0,0x15,0xfa,0x23,0x04,0x66,0x60,0xb0,0x62, -0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x09,0xf2,0xff,0xff,0x40,0x48,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x4c,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xce,0xfe,0x28,0x44,0x83,0x00,0x01,0x64,0x6f,0xfb,0x09,0x00, -0x69,0x60,0x58,0x4e,0x9b,0x78,0xff,0xff,0x04,0x03,0x69,0x60,0x58,0x4e,0xb9,0x78, -0xff,0xff,0x28,0x46,0x09,0xf2,0xf0,0x00,0x6c,0xf3,0xa4,0xf1,0xff,0xff,0xd0,0x84, -0xff,0xff,0x23,0x0e,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0x60,0x40,0xff,0x22, -0x01,0x64,0x60,0x43,0x28,0x60,0x7e,0x62,0xa2,0xdd,0x3c,0x60,0xb2,0x62,0x28,0x60, -0x7a,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xc4,0x62, -0x00,0x60,0x04,0x64,0xa2,0xdb,0x49,0x60,0xbe,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x6d,0xf3,0xff,0xff,0x02,0xbc, -0x6d,0xfb,0x00,0x64,0x6a,0xfb,0x01,0x64,0x8c,0xfb,0xff,0xff,0xc1,0xfe,0x66,0x60, -0x9a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x3c,0x03,0x10,0xb4,0x20,0x45, -0xb4,0x84,0x40,0x40,0x66,0x60,0x9c,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x8c,0xf3,0xff,0xff,0x00,0xa0,0x02,0x64,0x2a,0x03,0x8c,0xfb,0x1e,0x60,0xc2,0x62, -0xa2,0xd1,0x7f,0x60,0xff,0x64,0xa0,0x84,0xa2,0xdb,0x1e,0x60,0xc4,0x62,0x80,0x60, -0x00,0x64,0xa2,0xdb,0x49,0x60,0xf6,0x64,0x5a,0xdb,0xcf,0xfe,0xc1,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x64,0xa0,0x84,0xa2,0xdb, -0x8c,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0xf2,0x02,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0x7f,0x60,0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0x45,0x60, -0x93,0x78,0xff,0xff,0x67,0x60,0x76,0x65,0xa5,0xd3,0xff,0xff,0x60,0x40,0x03,0x22, -0x3d,0x00,0x01,0x2a,0x0c,0x00,0x1e,0x60,0x92,0x63,0xa3,0xd1,0x66,0x60,0xf0,0x65, -0xad,0xf3,0xa5,0xd3,0x60,0x45,0xc4,0x84,0xd0,0x80,0xff,0xff,0x26,0x0d,0x67,0x60, -0x76,0x65,0xa5,0xd3,0xff,0xff,0x60,0x45,0xfd,0xb4,0xa2,0xdb,0x20,0x44,0xb4,0x84, -0x40,0x40,0x59,0x60,0xbc,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x0c,0x60, -0x50,0x62,0x56,0x60,0x53,0x64,0xa2,0xdb,0x0f,0x4e,0x52,0x60,0x58,0x4f,0xaa,0x78, -0xff,0xff,0x0e,0x4f,0x1e,0x60,0xc4,0x62,0x10,0x60,0x00,0x64,0xa2,0xdb,0x4a,0x60, -0x4a,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0x0c,0x60,0x50,0x62,0x67,0x60,0x13,0x64,0xa2,0xdb,0x71,0xf3,0x70,0xf3, -0x9c,0xa0,0xff,0xff,0x7f,0x04,0x64,0x64,0x71,0xfb,0x66,0x60,0xa8,0x62,0xa2,0xd3, -0xff,0xff,0x00,0xa0,0xff,0xff,0x76,0x02,0xcb,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff, -0x44,0x02,0x8c,0xf3,0xff,0xff,0xff,0xa0,0x02,0x64,0x2a,0x02,0x8c,0xfb,0x1e,0x60, -0xc2,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x64,0xa0,0x84,0xa2,0xdb,0x1e,0x60,0xc4,0x62, -0x80,0x60,0x00,0x64,0xa2,0xdb,0x4a,0x60,0x7f,0x64,0x5a,0xdb,0xcf,0xfe,0xc1,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x7f,0x60,0xff,0x64,0xa0,0x84, -0xa2,0xdb,0x8c,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0xf2,0x02,0x1e,0x60,0xc2,0x62, -0xa2,0xd1,0x7f,0x60,0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb, -0x68,0x60,0xcc,0x62,0x90,0x60,0x71,0x64,0xa2,0xdb,0x66,0x60,0xa6,0x64,0xa0,0xd3, -0xff,0xff,0xfd,0xa0,0xff,0xff,0x09,0x02,0x02,0x64,0xa2,0xdb,0x00,0x64,0x70,0xfb, -0x02,0x65,0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x66,0x60,0x96,0x65,0xa5,0xd1, -0x01,0x60,0xf4,0x64,0x64,0x43,0xdf,0x83,0xd0,0x80,0xa5,0xdd,0x48,0x05,0x66,0x60, -0x98,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0x00,0x64,0xa5,0xdb,0x40,0x03,0xd5,0xf3, -0x03,0x7c,0x00,0xa0,0xff,0xff,0x13,0x03,0xd5,0xf9,0x0a,0x65,0x3d,0x60,0x58,0x4e, -0x32,0x78,0xff,0xff,0x0c,0x60,0x50,0x62,0x56,0x60,0x53,0x64,0xa2,0xdb,0x1f,0x60, -0x1c,0x63,0x0e,0x64,0x00,0x7c,0xbd,0xd9,0xcc,0x84,0xff,0xff,0xfc,0x02,0x45,0x60, -0x93,0x78,0xff,0xff,0xfd,0xa0,0xff,0xff,0x22,0x04,0x66,0x60,0x96,0x62,0x00,0x64, -0xa2,0xdb,0x70,0xfb,0x66,0x60,0x98,0x62,0x01,0x64,0xa2,0xdb,0x66,0x60,0xa6,0x64, -0xa0,0xd3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x12,0x03,0x03,0x64,0xa2,0xdb,0x03,0x64, -0xcb,0xfb,0x01,0x64,0x8c,0xfb,0xff,0xff,0xc1,0xfe,0x68,0x60,0xcc,0x62,0x90,0x60, -0x70,0x64,0xa2,0xdb,0x01,0x65,0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x69,0x60, -0x58,0x4e,0x58,0x78,0xff,0xff,0x47,0x60,0xb2,0x78,0xff,0xff,0x77,0xf5,0xff,0x60, -0xff,0x64,0x2b,0xfa,0x2c,0xfa,0x2d,0xfa,0x0b,0x00,0x77,0xf1,0x2b,0xf2,0x2c,0xf2, -0x60,0x43,0x64,0x46,0x2c,0xfa,0x2b,0xfc,0x28,0x46,0x2d,0xf2,0x64,0x46,0x2d,0xfa, -0x90,0x64,0x29,0xfa,0x47,0xf3,0xff,0xff,0xe8,0x84,0xe8,0x84,0x1c,0xfa,0x00,0x63, -0x38,0xf2,0x22,0xfc,0xff,0xff,0x19,0xfc,0x16,0xfc,0x17,0xfa,0x1c,0x64,0x21,0xfa, -0x0e,0x64,0x15,0xfa,0x01,0x64,0x14,0xfa,0x2e,0x58,0xff,0xff,0x3a,0x60,0x02,0x62, -0xa2,0xd3,0x43,0xf1,0x60,0x41,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0x90,0x84, -0x01,0xb4,0xc5,0xf1,0x0d,0x02,0x61,0x44,0x90,0x84,0x20,0xb4,0xff,0xff,0x08,0x03, -0x64,0x44,0x20,0x2a,0x04,0x00,0x00,0x64,0x47,0xfb,0x00,0xbc,0x01,0x00,0x01,0xbc, -0x2e,0x58,0xff,0xff,0x4c,0x60,0x3f,0x78,0xff,0xff,0x78,0xf5,0x51,0x60,0x58,0x4e, -0x28,0x78,0xff,0xff,0x51,0x60,0x58,0x4e,0xb2,0x78,0xff,0xff,0x85,0xf1,0x10,0x67, -0xa0,0x84,0xb0,0xbc,0x29,0xfa,0x51,0x60,0x58,0x4e,0xa3,0x78,0xff,0xff,0x06,0x63, -0x38,0xfc,0x00,0x64,0x22,0xfa,0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff,0x66,0x45, -0x00,0xf4,0x04,0x61,0x7d,0xf1,0x00,0x64,0x64,0x40,0x02,0x26,0x01,0x64,0xa1,0xda, -0x01,0x63,0x59,0xdc,0x00,0x64,0x59,0xda,0xa7,0xf1,0x28,0x60,0x7e,0x62,0xa2,0xd9, -0x3c,0x60,0x82,0x62,0x3c,0x60,0x2e,0x64,0xa2,0xdb,0xf4,0x96,0x7e,0x00,0x00,0x10, -0x65,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xc1,0xfe,0x01,0x64, -0x5d,0xfb,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb, -0xff,0xff,0x1d,0xff,0x1e,0x60,0xc4,0x62,0x00,0x60,0x0c,0x64,0xa2,0xdb,0x4b,0x60, -0x97,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0x00,0x60,0x08,0x64,0xa0,0x80,0x9c,0x84,0x2e,0x03,0xa0,0x84,0xa2,0xdb,0x3c,0x60, -0xb2,0x62,0x28,0x60,0x7a,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x00,0x64,0x5d,0xfb,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x26,0x46, -0x38,0xf2,0x00,0xf4,0x04,0xf2,0x60,0x41,0x00,0xa8,0xff,0xff,0x03,0x03,0x4c,0x60, -0x30,0x78,0xff,0xff,0x7d,0xf3,0xff,0xff,0x02,0xb4,0x03,0xf2,0x03,0x02,0x4c,0x60, -0x02,0x78,0xff,0xff,0x02,0xa8,0x88,0x65,0x38,0x02,0xd5,0x80,0xff,0xff,0x04,0x05, -0x4c,0x60,0x30,0x78,0xff,0xff,0x43,0x00,0x26,0x46,0x51,0x60,0x58,0x4e,0x28,0x78, -0xff,0xff,0xff,0x7f,0x00,0x7e,0x0e,0xfa,0x08,0x64,0x28,0xfa,0x85,0xf1,0x10,0x67, -0xa0,0x84,0xb0,0xbd,0x40,0x67,0xb4,0x84,0x29,0xfa,0x2b,0xf0,0x2e,0xf2,0xff,0xff, -0x2e,0xf8,0x2b,0xfa,0x2c,0xf0,0xff,0xff,0x2f,0xf2,0x2f,0xf8,0x2c,0xfa,0xff,0xff, -0x2d,0xf0,0x30,0xf2,0x30,0xf8,0xff,0xff,0x2d,0xfa,0x00,0x64,0x22,0xfa,0x3a,0x60, -0x58,0x4e,0x14,0x78,0xff,0xff,0x66,0x45,0x00,0xf4,0x04,0x61,0x01,0x64,0xa1,0xda, -0x03,0x63,0x59,0xdc,0x4b,0x60,0x71,0x78,0xff,0xff,0x04,0xa8,0xff,0xff,0x2e,0x02, -0x26,0x46,0x3e,0x60,0x58,0x4e,0x91,0x78,0xff,0xff,0x20,0x44,0x08,0xb0,0xff,0xff, -0x03,0x03,0x4c,0x60,0xde,0x78,0xff,0xff,0x4f,0x60,0xbb,0x78,0xff,0xff,0x00,0x60, -0x04,0x64,0xa0,0x80,0x9c,0x84,0x17,0x03,0xa0,0x84,0xa2,0xdb,0x00,0x64,0x5d,0xfb, -0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x51,0x60,0x58,0x4e,0xc1,0x78, -0xff,0xff,0x20,0x44,0x08,0xb0,0xff,0xff,0x03,0x03,0x4c,0x60,0xde,0x78,0xff,0xff, -0x4f,0x60,0xbb,0x78,0xff,0xff,0x4b,0x60,0x95,0x78,0xff,0xff,0x26,0x46,0x3e,0x60, -0x58,0x4e,0x91,0x78,0xff,0xff,0x20,0x44,0x08,0xb0,0xff,0xff,0x03,0x03,0x4c,0x60, -0x59,0x78,0xff,0xff,0x4e,0x60,0xac,0x78,0xff,0xff,0xa7,0xf1,0x28,0x60,0x7e,0x62, -0xa2,0xd9,0x79,0xf5,0x51,0x60,0x58,0x4e,0xb2,0x78,0xff,0xff,0x00,0x60,0xb8,0x63, -0x27,0x60,0xde,0x64,0xa3,0xdb,0x61,0x60,0xbc,0x63,0xbd,0xd3,0xbd,0xd1,0xff,0xff, -0xb0,0x84,0xa3,0xd1,0xff,0xff,0xb0,0x83,0x61,0x60,0xba,0x62,0xa2,0xdd,0x00,0x60, -0xb8,0x63,0x01,0x60,0x10,0x65,0xa3,0xd3,0xa5,0xd1,0x04,0xa4,0xa3,0xdb,0xd0,0x80, -0xa0,0xd3,0x07,0x07,0x40,0x47,0x52,0x60,0x58,0x4e,0x11,0x78,0xff,0xff,0xef,0x02, -0x0c,0x00,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x66,0x60,0xc2,0x65, -0x00,0x64,0xa5,0xdb,0x44,0x60,0x83,0x78,0xff,0xff,0x27,0x43,0x3c,0xa3,0xa3,0xd1, -0x67,0x60,0x48,0x63,0xc9,0xf3,0xa3,0xd9,0xa0,0x84,0xd0,0x80,0xff,0xff,0xd7,0x02, -0x27,0x43,0x40,0xa3,0xa3,0xd3,0xff,0xff,0x01,0xa0,0x60,0x41,0x05,0x02,0x3e,0x60, -0x58,0x4e,0xae,0x78,0xff,0xff,0x0d,0x00,0x17,0x60,0x46,0x62,0xa2,0xd3,0xff,0xff, -0x60,0x45,0xd5,0x84,0x60,0x45,0x01,0x0d,0x00,0x65,0x3e,0x60,0x58,0x4e,0xd6,0x78, -0xff,0xff,0xcb,0xf3,0xe1,0xf3,0xfc,0xa0,0x00,0xa0,0x05,0x03,0x04,0x03,0x67,0x60, -0x80,0x62,0x01,0x64,0xa2,0xdb,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0xde,0xfe, -0xff,0xff,0x0b,0x04,0x1e,0x60,0xc4,0x62,0x40,0x60,0x00,0x64,0xa2,0xdb,0x4c,0x60, -0x77,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x27,0xd1,0x3c,0x60,0xa2,0x62, -0xa2,0xd9,0xca,0x82,0x1e,0x64,0xa2,0xdb,0xff,0xff,0x2d,0xff,0x1e,0x60,0xc4,0x62, -0x20,0x60,0x00,0x64,0xa2,0xdb,0x4c,0x60,0xcb,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0xbe,0xfe,0x1e,0x60,0xa8,0x62, -0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x20,0x44,0x08,0xbc, -0x40,0x40,0x4b,0x60,0x4a,0x78,0xff,0xff,0x79,0xf5,0x51,0x60,0x58,0x4e,0x28,0x78, -0xff,0xff,0x00,0x64,0x29,0xfa,0x51,0x60,0x58,0x4e,0xa3,0x78,0xff,0xff,0xff,0xff, -0x47,0xf1,0x00,0xf4,0x04,0x62,0x00,0x60,0x01,0x64,0xb0,0x84,0xa2,0xda,0x0f,0x63, -0x04,0x61,0x59,0xdc,0x50,0x60,0x58,0x4e,0xef,0x78,0xff,0xff,0x79,0xf5,0x2d,0x44, -0x08,0xa4,0x38,0xfa,0x00,0x64,0x22,0xfa,0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff, -0x3c,0x60,0x82,0x62,0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64, -0x5a,0xdb,0xff,0xff,0x2b,0xff,0xc1,0xfe,0x06,0x64,0x5d,0xfb,0x3c,0x60,0xb2,0x62, -0x28,0x60,0x7a,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60, -0xc4,0x62,0x00,0x60,0x1c,0x64,0xa2,0xdb,0x4d,0x60,0x24,0x64,0x5a,0xdb,0xcf,0xfe, -0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xa0,0x80, -0x9c,0x84,0x21,0x03,0xa0,0x84,0xa2,0xdb,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64, -0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x00,0x63,0x5d,0xfd,0x1e,0x60, -0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x26,0x46,0x00,0xf4,0x03,0xf2,0xff,0xff, -0x00,0xb8,0xff,0xff,0x3d,0x03,0x26,0x46,0x3e,0x60,0x58,0x4e,0x91,0x78,0xff,0xff, -0x4c,0x60,0x59,0x78,0xff,0xff,0x00,0x60,0x10,0x64,0xa0,0x80,0x9c,0x84,0x1a,0x03, -0xa0,0x84,0xa2,0xdb,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64,0xa2,0xdb,0x03,0x64, -0x4a,0xdb,0xff,0xff,0x1d,0xff,0x26,0x46,0x3e,0x60,0x58,0x4e,0x91,0x78,0xff,0xff, -0x00,0x64,0x5d,0xfb,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x4c,0x60, -0xd8,0x78,0xff,0xff,0x00,0x60,0x04,0x64,0xa0,0x80,0x9c,0x84,0x10,0x03,0xa0,0x84, -0xa2,0xdb,0x00,0x64,0x5d,0xfb,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb, -0x51,0x60,0x58,0x4e,0xc1,0x78,0xff,0xff,0x4c,0x60,0x59,0x78,0xff,0xff,0xa0,0x00, -0x1e,0x60,0xda,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff, -0xcf,0xfe,0x51,0x60,0x58,0x4e,0x3d,0x78,0xff,0xff,0x51,0x60,0x58,0x4e,0x54,0x78, -0xff,0xff,0x5a,0x60,0x58,0x4e,0xdb,0x78,0xff,0xff,0x52,0x60,0x58,0x4e,0x48,0x78, -0xff,0xff,0x51,0x60,0x58,0x4e,0xd4,0x78,0xff,0xff,0x27,0x43,0x11,0x61,0x10,0x65, -0xc7,0x83,0x59,0x60,0x1e,0x64,0xbd,0xd1,0xcd,0x81,0x58,0xd9,0xfc,0x02,0x26,0x46, -0x3e,0x60,0x58,0x4e,0x91,0x78,0xff,0xff,0x01,0x64,0x8c,0xfb,0xff,0xff,0xc1,0xfe, -0x01,0x64,0x90,0xfb,0x01,0x67,0x85,0xfb,0x04,0x64,0xcb,0xfb,0x01,0x65,0x3d,0x60, -0x58,0x4e,0x32,0x78,0xff,0xff,0x52,0x60,0x58,0x4e,0x74,0x78,0xff,0xff,0x1e,0x60, -0xb0,0x62,0xa2,0xd1,0x00,0x60,0x02,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe, -0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60,0x80,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff, -0xcf,0xfe,0x0c,0x64,0x5d,0xfb,0x1e,0x60,0xc4,0x62,0x00,0x60,0xf0,0x64,0xa2,0xdb, -0x4d,0x60,0xe0,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62, -0xa2,0xd1,0x00,0x60,0x80,0x64,0xa0,0x80,0x9c,0x84,0x07,0x03,0xa0,0x84,0xa2,0xdb, -0x61,0x60,0xc8,0x62,0x0e,0x64,0xa2,0xdb,0x17,0x00,0x00,0x60,0x40,0x64,0xa0,0x80, -0x9c,0x84,0x07,0x03,0xa0,0x84,0xa2,0xdb,0x61,0x60,0xc8,0x62,0x00,0x64,0xa2,0xdb, -0x0b,0x00,0x00,0x60,0x10,0x64,0xa0,0x80,0x9c,0x84,0x49,0x03,0xa0,0x84,0xa2,0xdb, -0x61,0x60,0xc8,0x62,0x0a,0x64,0xa2,0xdb,0x5e,0xf3,0xff,0xff,0x01,0xb0,0xff,0xff, -0x14,0x03,0x1e,0x60,0xb0,0x62,0xa2,0xd1,0x00,0x60,0x04,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x1e,0x60,0xc4,0x62,0x08,0x60,0x00,0x64,0xa2,0xdb,0x4e,0x60, -0x1f,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0x5a,0xdb,0x00,0x64,0x5d,0xfb,0x1e,0x60,0x92,0x62,0xa2,0xd1,0x61,0x60, -0xd2,0x62,0xa2,0xd9,0x1e,0x60,0x94,0x62,0xa2,0xd1,0x61,0x60,0xd4,0x62,0xa2,0xd9, -0x4e,0x60,0x58,0x4e,0x5d,0x78,0xff,0xff,0x02,0x64,0x8c,0xfb,0xff,0xff,0xc1,0xfe, -0x02,0x65,0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x66,0x60,0xc2,0x65,0x64,0x60, -0x58,0x62,0x00,0x64,0xa2,0xdb,0xa5,0xdb,0x44,0x60,0x83,0x78,0xff,0xff,0x00,0x60, -0x20,0x64,0xa0,0x80,0x9c,0x84,0x0a,0x03,0xa0,0x84,0xa2,0xdb,0x00,0x63,0x5d,0xfd, -0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x1b,0x00,0x4d,0x60,0xde,0x78, -0xff,0xff,0x2f,0x58,0xff,0xff,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64,0xa2,0xdb, -0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x00,0x64,0x5d,0xfb,0x1e,0x60,0xc2,0x62, -0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x01,0x64,0x8c,0xfb,0xff,0xff,0xc1,0xfe,0x2e,0x58, -0xff,0xff,0x02,0x64,0x8c,0xfb,0x47,0xf3,0x46,0xfb,0x00,0x60,0xfe,0x65,0x00,0x60, -0xfc,0x63,0xa5,0xd3,0xa3,0xdb,0xa7,0xf1,0x28,0x60,0x7e,0x62,0xa2,0xd9,0x8c,0xf3, -0x00,0x65,0xd4,0x80,0xff,0xff,0x0c,0x03,0x1e,0x60,0xc4,0x62,0x80,0x60,0x00,0x64, -0xa2,0xdb,0x4e,0x60,0x81,0x64,0x5a,0xdb,0xcf,0xfe,0xc1,0xfe,0x2f,0x58,0xff,0xff, -0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x00,0x60,0xb8,0x63,0x27,0x60, -0xde,0x64,0xa3,0xdb,0x64,0x60,0x5a,0x62,0x00,0x64,0xa2,0xdb,0x61,0x60,0xbc,0x63, -0xbd,0xd3,0xbd,0xd1,0xff,0xff,0xb0,0x84,0xa3,0xd1,0xff,0xff,0xb0,0x83,0x61,0x60, -0xba,0x62,0xa2,0xdd,0x00,0x60,0xb8,0x63,0x01,0x60,0x10,0x65,0xa3,0xd3,0xff,0xff, -0x02,0xa4,0xa0,0xd1,0xff,0xff,0x64,0x41,0xa5,0xd1,0x02,0xa4,0xa3,0xdb,0xd0,0x80, -0xa0,0xd3,0x49,0x07,0x40,0x47,0xc4,0xf1,0x58,0xf3,0xff,0xff,0xc0,0x85,0xd5,0x80, -0x60,0x45,0x0e,0x05,0x61,0x60,0xc8,0x62,0xa2,0xd3,0x1f,0xf1,0xfc,0xa0,0x65,0x44, -0x3a,0x02,0x64,0x40,0x10,0x2a,0x37,0x00,0x03,0xa5,0xd5,0x80,0x34,0x04,0x07,0x00, -0x61,0x60,0xc8,0x62,0xa2,0xd3,0xff,0xff,0xfc,0xa0,0xff,0xff,0x13,0x02,0x66,0x60, -0xbe,0x62,0xa2,0xd1,0x27,0x44,0x3e,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x41,0x02,0xa4, -0xd0,0x80,0xff,0xff,0xc7,0x07,0xe1,0x85,0xc5,0x85,0x64,0x44,0xe0,0x84,0xd4,0x80, -0xff,0xff,0xc0,0x04,0x52,0x60,0x58,0x4e,0x11,0x78,0xff,0xff,0xbb,0x02,0x27,0x44, -0x06,0xa4,0x60,0x41,0xa1,0xd1,0x81,0xf3,0xff,0xff,0xd0,0x80,0x82,0xf1,0x59,0xd3, -0x68,0x02,0xd0,0x80,0x83,0xf3,0x59,0xd1,0x64,0x02,0xd0,0x80,0xff,0xff,0x61,0x02, -0x4e,0x60,0xac,0x78,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0xde,0xfe, -0xff,0xff,0x0b,0x04,0x1e,0x60,0xc4,0x62,0x40,0x60,0x00,0x64,0xa2,0xdb,0x4f,0x60, -0x05,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x46,0xf3,0x47,0xfb,0x00,0x60, -0xfc,0x63,0xa3,0xd1,0x3c,0x60,0xa2,0x62,0xa2,0xd9,0xca,0x82,0x1e,0x64,0xa2,0xdb, -0xff,0xff,0x2d,0xff,0x1e,0x60,0xc4,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x4f,0x60, -0x2f,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0xbe,0xfe,0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84, -0xa2,0xdb,0xcf,0xfe,0x64,0x60,0x5a,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff, -0x10,0x02,0x3c,0x60,0x28,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8,0x60,0x46,0x09,0x02, -0x1e,0x60,0xda,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff, -0xcf,0xfe,0x01,0x63,0x8c,0xfd,0xff,0xff,0xc1,0xfe,0x1e,0x60,0xb0,0x62,0xa2,0xd1, -0x00,0x60,0x02,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x4d,0x60,0xd3,0x78, -0xff,0xff,0x27,0x43,0x3c,0xa3,0xa3,0xd1,0xc9,0xf3,0xff,0xff,0xa0,0x84,0xd0,0x80, -0xff,0xff,0x03,0x03,0x4e,0x60,0xac,0x78,0xff,0xff,0x27,0x43,0x40,0xa3,0xa3,0xd3, -0xff,0xff,0x01,0xa0,0x60,0x41,0x05,0x02,0x3e,0x60,0x58,0x4e,0xae,0x78,0xff,0xff, -0x0d,0x00,0x17,0x60,0x46,0x62,0xa2,0xd3,0xff,0xff,0x60,0x45,0xd5,0x84,0x60,0x45, -0x01,0x0d,0x00,0x65,0x3e,0x60,0x58,0x4e,0xd6,0x78,0xff,0xff,0x1e,0x60,0xc2,0x62, -0x00,0x64,0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xc4,0x62,0x40,0x60, -0x00,0x64,0xa2,0xdb,0x4f,0x60,0x6f,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x27,0xd1,0x3c,0x60,0xa2,0x62,0xa2,0xd9,0xca,0x82,0x1e,0x64,0xa2,0xdb,0xff,0xff, -0x2d,0xff,0x1e,0x60,0xc4,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x4f,0x60,0xae,0x64, -0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb, -0xbe,0xfe,0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb, -0xcf,0xfe,0x79,0xf5,0x51,0x60,0x58,0x4e,0x28,0x78,0xff,0xff,0x00,0x60,0x20,0x64, -0x29,0xfa,0x51,0x60,0x58,0x4e,0xa3,0x78,0xff,0xff,0x51,0x60,0x58,0x4e,0xb2,0x78, -0xff,0xff,0x00,0xf4,0x04,0x61,0x47,0xf1,0x01,0x64,0xb0,0x84,0xa1,0xda,0x0f,0x64, -0x59,0xda,0x81,0xf1,0xff,0xff,0x59,0xd8,0x82,0xf1,0x59,0xd8,0xff,0xff,0x83,0xf1, -0x59,0xd8,0x50,0x60,0x58,0x4e,0xef,0x78,0xff,0xff,0x79,0xf5,0x2d,0x44,0x0e,0xa4, -0x38,0xfa,0x00,0x64,0x22,0xfa,0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xc1,0xfe,0x14,0x64,0x5d,0xfb,0x3c,0x60,0xb2,0x62,0x28,0x60, -0x7a,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xc4,0x62, -0x00,0x60,0x1c,0x64,0xa2,0xdb,0x50,0x60,0x0b,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x04,0x64,0xa0,0x80,0x9c,0x84, -0x14,0x03,0xa0,0x84,0xa2,0xdb,0x00,0x64,0x5d,0xfb,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0x5a,0xdb,0x51,0x60,0x58,0x4e,0xc1,0x78,0xff,0xff,0x64,0x60,0x5a,0x62, -0x01,0x64,0xa2,0xdb,0x4e,0x60,0xac,0x78,0xff,0xff,0x00,0x60,0x10,0x64,0xa0,0x80, -0x9c,0x84,0x15,0x03,0xa0,0x84,0xa2,0xdb,0x3c,0x60,0xb2,0x62,0x28,0x60,0x7a,0x64, -0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x00,0x64,0x5d,0xfb,0x1e,0x60, -0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x50,0x60,0xad,0x78,0xff,0xff,0x00,0x60, -0x08,0x64,0xa0,0x80,0x9c,0x84,0x22,0x03,0xa0,0x84,0xa2,0xdb,0x3c,0x60,0xb2,0x62, -0x28,0x60,0x7a,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x00,0x64, -0x5d,0xfb,0x1e,0x60,0xc2,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x26,0x46,0x00,0xf4, -0xff,0xff,0x03,0xf2,0xff,0xff,0x00,0xb8,0xff,0xff,0x09,0x03,0x26,0x46,0x3e,0x60, -0x58,0x4e,0x91,0x78,0xff,0xff,0x4e,0x60,0xac,0x78,0xff,0xff,0xa0,0x00,0x1e,0x60, -0xda,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe, -0x51,0x60,0x58,0x4e,0x3d,0x78,0xff,0xff,0x51,0x60,0x58,0x4e,0x54,0x78,0xff,0xff, -0x5a,0x60,0x58,0x4e,0xdb,0x78,0xff,0xff,0x52,0x60,0x58,0x4e,0x48,0x78,0xff,0xff, -0x51,0x60,0x58,0x4e,0xd4,0x78,0xff,0xff,0x26,0x46,0x3e,0x60,0x58,0x4e,0x91,0x78, -0xff,0xff,0x03,0x65,0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x52,0x60,0x58,0x4e, -0x74,0x78,0xff,0xff,0x01,0x63,0x8c,0xfd,0xff,0xff,0xc1,0xfe,0x1e,0x60,0xb0,0x62, -0xa2,0xd1,0x00,0x60,0x02,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x1e,0x60, -0xd4,0x62,0xa2,0xd1,0x00,0x60,0x80,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe, -0x4d,0x60,0xd3,0x78,0xff,0xff,0x20,0x44,0xf7,0xb4,0x40,0x40,0x4b,0x60,0x4a,0x78, -0xff,0xff,0x5d,0xf1,0x29,0xf2,0x64,0x41,0x60,0x40,0xa0,0x3a,0x0d,0x00,0x08,0xb1, -0xff,0xff,0x31,0x03,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x10,0x64,0xb0,0x84, -0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x27,0x00,0xc0,0x3a,0x0d,0x00,0x04,0xb1,0xff,0xff, -0x22,0x03,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x10,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x18,0x00,0xb0,0x3a,0x02,0x00,0x01,0x65,0x07,0x00,0x10,0x3a, -0x02,0x00,0x02,0x65,0x03,0x00,0x30,0x3a,0x0e,0x00,0x10,0x65,0xa5,0x80,0xff,0xff, -0x0a,0x03,0x1e,0x60,0xc2,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x00,0x66,0x2f,0x58,0xff,0xff,0x27,0x43,0x12,0xa3,0xbf,0xd1, -0xff,0xff,0x64,0x47,0x59,0xda,0x64,0x41,0xdd,0x81,0xe9,0x81,0x62,0x44,0x04,0x03, -0xbd,0xd1,0xcd,0x81,0x58,0xd8,0xfc,0x02,0x58,0x8d,0x17,0x60,0xd2,0x63,0xa3,0xd1, -0x2d,0x44,0xc8,0x84,0x64,0x45,0x64,0x41,0x03,0xa1,0xe9,0x81,0x41,0x4c,0xbd,0xd1, -0xcd,0x81,0x58,0xd8,0xfc,0x02,0x2d,0xd2,0x2d,0x43,0x60,0x47,0x01,0x7e,0xa3,0xda, -0x27,0x44,0x10,0xa4,0xa0,0xd3,0xcb,0x83,0x44,0x8d,0xf8,0x84,0x2c,0x41,0x0c,0x04, -0xbe,0xd2,0xff,0xff,0x60,0x47,0xbe,0xda,0x00,0x7e,0xa3,0xd2,0x60,0x45,0x00,0x7f, -0xb4,0x84,0xcd,0x81,0xbd,0xda,0xf4,0x02,0x2e,0x58,0xff,0xff,0x67,0x60,0x48,0x62, -0xa2,0xd3,0xff,0xff,0xff,0xff,0x01,0x2a,0x02,0x00,0x00,0x64,0x09,0x00,0x02,0x2a, -0x02,0x00,0x01,0x64,0x05,0x00,0x04,0x2a,0x02,0x00,0x02,0x64,0x01,0x00,0x03,0x64, -0x13,0xfa,0x2e,0x58,0xff,0xff,0xff,0x60,0xff,0x65,0x66,0x60,0xbe,0x63,0x27,0x42, -0x3e,0xa2,0xa2,0xd3,0x7f,0x7c,0xa3,0xdb,0xd4,0x80,0x01,0x61,0x02,0x02,0x00,0x61, -0x65,0x5c,0x66,0x60,0xc0,0x62,0x61,0x44,0xa2,0xdb,0x66,0x60,0xbc,0x62,0xa2,0xd9, -0x2e,0x58,0xff,0xff,0x27,0x42,0x32,0xa2,0x00,0x61,0x00,0x63,0xa2,0xd3,0xff,0xff, -0x00,0xbc,0xe0,0x84,0x24,0x03,0x04,0x3a,0x02,0x00,0x01,0xb9,0x1e,0x00,0x08,0x3a, -0x0a,0x00,0x02,0xb9,0x60,0x40,0x01,0x2b,0x18,0x00,0x01,0x65,0xd7,0x80,0xff,0xff, -0x14,0x05,0x01,0x63,0x12,0x00,0x16,0x3a,0x0a,0x00,0x04,0xb9,0x60,0x40,0x01,0x2b, -0x0c,0x00,0x02,0x65,0xd7,0x80,0xff,0xff,0x08,0x05,0x02,0x63,0x06,0x00,0x2c,0x3a, -0x04,0x00,0x08,0xb9,0x60,0x40,0x01,0x27,0x03,0x63,0x02,0xa2,0xd7,0x00,0x59,0x60, -0x68,0x62,0xa2,0xdd,0xc9,0xf1,0x59,0x60,0x6a,0x63,0xa1,0x84,0xa3,0xdb,0x60,0x40, -0x08,0x2a,0x03,0x00,0x03,0x63,0x08,0x64,0x0c,0x00,0x04,0x2a,0x03,0x00,0x02,0x63, -0x04,0x64,0x07,0x00,0x02,0x2a,0x03,0x00,0x01,0x63,0x02,0x64,0x02,0x00,0x00,0x63, -0x01,0x64,0x50,0xfb,0x51,0xf1,0x61,0x60,0xd0,0x62,0xa2,0xd9,0x51,0xfd,0x2e,0x58, -0xff,0xff,0x27,0x43,0x06,0xa3,0xbd,0xd1,0x2b,0xf8,0x31,0xf8,0xff,0xff,0xbd,0xd1, -0x2c,0xf8,0x32,0xf8,0xff,0xff,0xa3,0xd1,0x2d,0xf8,0x33,0xf8,0x2e,0x58,0xff,0xff, -0xbd,0xf1,0xff,0xff,0x2e,0xf8,0xbe,0xf1,0x2f,0xf8,0xff,0xff,0xbf,0xf1,0x30,0xf8, -0xf0,0x60,0x20,0x64,0x0e,0xfa,0x08,0x64,0x28,0xfa,0x2e,0x58,0xff,0xff,0x67,0x60, -0x66,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xff,0xff,0xa2,0xdb,0x28,0x60,0x60,0x62, -0x01,0x64,0xa2,0xdb,0xff,0xff,0xc0,0xfe,0x28,0x60,0x60,0x62,0x00,0x64,0xa2,0xdb, -0x2e,0x58,0xff,0xff,0x27,0x43,0x02,0x65,0xc7,0x85,0xa5,0xd3,0xff,0xff,0x60,0x47, -0x5a,0xfb,0x04,0x65,0xc7,0x85,0xa5,0xd3,0xff,0xff,0x60,0x47,0x59,0xfb,0x0c,0x65, -0xc7,0x85,0xa5,0xd3,0x80,0xfb,0xf1,0xa4,0xab,0xfb,0xab,0xf1,0x28,0x60,0xd2,0x62, -0xa2,0xd9,0x3c,0x60,0xd2,0x65,0x04,0xf0,0x3f,0x60,0xff,0x64,0x84,0xf9,0xa0,0x84, -0x60,0x41,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xa5,0xdb,0x3c,0x60,0xd0,0x65,0x01,0x64, -0x07,0xb1,0x03,0x00,0xe0,0x84,0xcd,0x81,0xff,0xff,0xfc,0x02,0xa5,0xdb,0x61,0x60, -0xca,0x63,0x26,0x46,0x31,0xf0,0x81,0xf9,0xbd,0xd9,0xff,0xff,0x32,0xf0,0x82,0xf9, -0xbd,0xd9,0xff,0xff,0x33,0xf0,0x83,0xf9,0xa3,0xd9,0x2e,0x58,0xff,0xff,0x27,0x44, -0x0e,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x41,0xe8,0x84,0xe8,0x84,0xe8,0x84,0x43,0xf3, -0xe8,0x85,0x94,0x84,0x01,0x26,0x26,0x00,0xc5,0xf1,0x1f,0xf3,0x91,0x80,0x20,0x2a, -0x05,0x00,0x60,0x40,0x10,0x2a,0x1e,0x00,0x20,0xb1,0x61,0x5c,0x47,0xf9,0x61,0x60, -0xba,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x12,0x03,0x50,0xfe,0x27,0x41, -0x06,0xa1,0x61,0x60,0xbc,0x63,0xa1,0xd3,0xbd,0xd1,0x59,0xd3,0xd0,0x80,0xbd,0xd1, -0x59,0xd3,0xd0,0x80,0xbd,0xd1,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x01,0x02,0x00, -0x00,0x64,0x01,0x00,0x01,0x64,0x00,0xbc,0x2e,0x58,0xff,0xff,0x66,0x60,0xfa,0x63, -0x00,0x64,0xbd,0xdb,0x01,0x64,0xbd,0xdb,0xa3,0xdb,0x67,0x60,0x00,0x63,0x00,0x64, -0xbd,0xdb,0x01,0x64,0xbd,0xdb,0xa3,0xdb,0x27,0x44,0x02,0xa4,0xa0,0xd1,0x27,0x44, -0x04,0xa4,0xa0,0xd3,0xff,0xff,0xd0,0x81,0xff,0xff,0x01,0x05,0x00,0x61,0x66,0x60, -0xf2,0x63,0x61,0x44,0xbd,0xdb,0xa3,0xdb,0x66,0x60,0xf6,0x62,0xa2,0xd1,0xff,0xff, -0xd1,0x81,0xff,0xff,0x01,0x05,0x00,0x61,0x66,0x60,0xf8,0x62,0x61,0x44,0xa2,0xdb, -0x2e,0x58,0xff,0xff,0x59,0x60,0x9c,0x62,0x66,0x60,0x2a,0x63,0x00,0x64,0xa2,0xdb, -0xbd,0xdb,0xff,0xff,0xbd,0xdb,0xbd,0xdb,0xbd,0xdb,0x67,0x60,0x84,0x62,0x00,0x64, -0xa2,0xdb,0x2e,0x58,0xff,0xff,0x00,0x64,0x5d,0xfb,0x3c,0x60,0xb0,0x63,0x21,0x44, -0xbd,0xdb,0xff,0xff,0x1d,0xff,0x01,0x64,0xcb,0xfb,0x1e,0x60,0xc2,0x62,0x00,0x64, -0xa2,0xdb,0x5a,0xdb,0x00,0x60,0x2a,0x63,0x0c,0x60,0x40,0x61,0x0e,0x60,0x7e,0x64, -0x58,0xd1,0x59,0xd9,0xfd,0x1f,0x2f,0x58,0xff,0xff,0x1e,0x60,0xc2,0x62,0xa2,0xd1, -0x00,0x60,0x04,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x7a,0xf5,0xbd,0xf1,0x2e,0xf8,0xff,0xff,0xbe,0xf1,0x2f,0xf8,0xbf,0xf1,0xff,0xff, -0x30,0xf8,0x1e,0x60,0x92,0x62,0x67,0x60,0x12,0x63,0xa2,0xd3,0xa3,0xdb,0x7f,0xf3, -0x00,0x65,0x7e,0xfb,0xcb,0xf3,0xe1,0xf3,0xfc,0xa0,0x00,0xa0,0x05,0x03,0x04,0x03, -0x67,0x60,0x80,0x62,0x01,0x64,0xa2,0xdb,0xcb,0xf3,0x14,0x7c,0xfc,0xa0,0x0f,0x64, -0x0a,0x03,0xd5,0xf3,0x28,0x7c,0xfd,0xa0,0x60,0x45,0x2d,0x64,0x04,0x04,0x01,0x60, -0x86,0x64,0x01,0x03,0x78,0x64,0xaf,0xf9,0xb1,0xfb,0x1e,0x60,0xbc,0x62,0x00,0x64, -0xa2,0xdb,0x20,0x44,0x03,0x26,0x07,0x00,0x00,0x64,0x8a,0xfb,0x27,0x60,0xe0,0x64, -0x88,0xfb,0x89,0xfb,0x0a,0x00,0x40,0x2a,0x04,0x00,0x18,0x60,0xf6,0x62,0xa2,0xd3, -0xb1,0xfb,0x3d,0x60,0x4c,0x62,0x00,0x64,0xa2,0xdb,0x65,0x44,0xfd,0xa0,0xff,0xff, -0x71,0x05,0x20,0x40,0x40,0x26,0x6e,0x00,0x10,0x60,0x00,0x65,0x85,0xf3,0x7a,0xf5, -0xa4,0x84,0x40,0x7e,0x29,0xfa,0x17,0x60,0xde,0x64,0xa0,0xd1,0x13,0xf8,0xff,0xff, -0x5b,0xf3,0x00,0xf4,0x60,0x43,0xbd,0xd1,0x04,0x65,0x20,0x40,0x80,0x26,0x00,0x7c, -0x64,0x47,0xa5,0xda,0x64,0x41,0xdd,0x81,0xe9,0x81,0x62,0x44,0x04,0x03,0xbd,0xd1, -0xcd,0x81,0x58,0xd8,0xfc,0x02,0x58,0x8d,0x17,0x60,0xd2,0x63,0xa3,0xd1,0x2d,0x44, -0xc8,0x84,0x64,0x45,0x64,0x41,0x03,0xa1,0xe9,0x81,0x41,0x4c,0xbd,0xd1,0xcd,0x81, -0x58,0xd8,0xfc,0x02,0x2d,0xd2,0x2d,0x43,0x60,0x47,0x01,0x7e,0x5b,0xf1,0xa3,0xda, -0xa4,0xd3,0xcb,0x83,0x20,0x40,0x80,0x26,0x00,0x64,0x44,0x8d,0xf8,0x84,0x2c,0x41, -0x0c,0x04,0xbe,0xd2,0xff,0xff,0x60,0x47,0xbe,0xda,0x00,0x7e,0xa3,0xd2,0x60,0x45, -0x00,0x7f,0xb4,0x84,0xcd,0x81,0xbd,0xda,0xf4,0x02,0x7a,0xf5,0x2d,0x44,0x04,0xa4, -0x38,0xfa,0x66,0x60,0xc0,0x62,0xa2,0xd1,0x66,0x60,0xb8,0x62,0xa2,0xd9,0x1f,0x60, -0x5a,0x63,0xbf,0xf3,0x71,0x5c,0x60,0x47,0xc0,0x84,0x1f,0xb5,0x01,0xb4,0xa3,0xdb, -0x1f,0x60,0x56,0x62,0xa2,0xd3,0x65,0x41,0x60,0x45,0x61,0x44,0xd4,0x80,0xff,0xff, -0x02,0x04,0xd4,0x84,0xfb,0x00,0x60,0x45,0x1f,0x60,0x54,0x62,0xa2,0xd3,0xff,0xff, -0xc4,0x84,0x40,0x4a,0x1f,0x60,0x58,0x62,0x00,0x64,0xa2,0xdb,0x13,0x00,0xd5,0xf3, -0xff,0xff,0xfd,0xa0,0xfc,0xa0,0x09,0x03,0x05,0x02,0x01,0x60,0x86,0x64,0xb1,0xfb, -0x03,0x64,0xd5,0xfb,0x54,0x60,0xfb,0x78,0xff,0xff,0x04,0x64,0xd5,0xfb,0x52,0x60, -0xf4,0xa6,0x7e,0x00,0x00,0x10,0xb3,0x78,0xff,0xff,0xd5,0xf1,0x1f,0x60,0x58,0x62, -0xa2,0xd3,0xff,0xff,0xf2,0xa0,0xff,0xff,0xe5,0x03,0x01,0xa4,0xa2,0xdb,0x1f,0x60, -0x5a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x07,0x03,0x2a,0x44,0xdc,0x84, -0xf2,0xa0,0xff,0xff,0x08,0x06,0x01,0x64,0x06,0x00,0x2a,0x44,0xcc,0x84,0xff,0xa0, -0xff,0xff,0x01,0x05,0x0e,0x64,0x40,0x4a,0x1f,0x60,0x1a,0x63,0x20,0x40,0x40,0x26, -0x0e,0x00,0x64,0x44,0x04,0x36,0x0b,0x00,0x03,0x3a,0x02,0x00,0x1f,0x60,0x36,0x63, -0x2a,0x44,0xe0,0x85,0x47,0xd3,0xff,0xff,0x01,0xb0,0xff,0xff,0xce,0x03,0x1e,0x60, -0xbc,0x62,0x00,0x64,0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xbe,0x62, -0x40,0x60,0x00,0x64,0xa2,0xdb,0x53,0x60,0xae,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x3c,0x60,0xa2,0x62,0x2a,0x44,0xa2,0xdb,0xca,0x82,0x1e,0x64,0xa2,0xdb, -0xff,0xff,0x2d,0xff,0x1e,0x60,0xbe,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x53,0x60, -0xd4,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0xbe,0xfe,0x1e,0x60,0xa8,0x62, -0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x02,0x0a,0x00,0x64, -0x57,0xfb,0x20,0x44,0x40,0x2a,0x09,0x00,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60, -0x80,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x20,0x44,0x40,0x22,0x03,0x00, -0x54,0x60,0x72,0x78,0xff,0xff,0xd5,0xf3,0xff,0xff,0xfd,0xa0,0x7a,0xf5,0x7b,0x05, -0x00,0x64,0x22,0xfa,0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff,0x3c,0x60,0x82,0x62, -0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff, -0x2b,0xff,0x1e,0x60,0xbc,0x62,0x00,0x64,0xa2,0xdb,0xaf,0xf1,0x28,0x60,0x66,0x62, -0xa2,0xd9,0x3c,0x60,0xba,0x62,0x28,0x60,0x62,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb, -0xff,0xff,0x1d,0xff,0xc1,0xfe,0x1e,0x60,0xbe,0x62,0x00,0x60,0x05,0x64,0xa2,0xdb, -0x54,0x60,0x25,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xbc,0x62, -0xa2,0xd1,0x00,0x60,0x01,0x64,0xa0,0x80,0x9c,0x84,0x0c,0x03,0xa0,0x84,0xa2,0xdb, -0x3c,0x60,0xba,0x62,0x28,0x60,0x62,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff, -0x1d,0xff,0x11,0x00,0x67,0x60,0x10,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb, -0x28,0x60,0x60,0x62,0x01,0x64,0xa2,0xdb,0xff,0xff,0xc0,0xfe,0x00,0x64,0xa2,0xdb, -0x53,0x60,0x7c,0x78,0xff,0xff,0x1e,0x60,0xbc,0x62,0x00,0x64,0xa2,0xdb,0xb1,0xf1, -0x28,0x60,0x66,0x62,0xa2,0xd9,0x3c,0x60,0xba,0x62,0x28,0x60,0x62,0x64,0xa2,0xdb, -0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xbe,0x62,0x00,0x60,0x04,0x64, -0xa2,0xdb,0x54,0x60,0x66,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60, -0xbc,0x62,0x00,0x64,0xa2,0xdb,0x57,0xf3,0xff,0xff,0x00,0xa8,0xff,0xff,0x2e,0x02, -0x53,0x60,0x7c,0x78,0xff,0xff,0x1e,0x60,0xbc,0x62,0x00,0x64,0xa2,0xdb,0xb1,0xf1, -0x28,0x60,0x66,0x62,0xa2,0xd9,0x3c,0x60,0xba,0x62,0x28,0x60,0x62,0x64,0xa2,0xdb, -0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xbe,0x62,0x00,0x60,0x04,0x64, -0xa2,0xdb,0x54,0x60,0x8e,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60, -0xbc,0x62,0x00,0x64,0xa2,0xdb,0xd5,0xf3,0xff,0xff,0xff,0xa0,0xff,0xff,0x03,0x03, -0x53,0x60,0x7c,0x78,0xff,0xff,0x52,0x60,0xb3,0x78,0xff,0xff,0xb1,0xf1,0x28,0x60, -0x66,0x62,0xa2,0xd9,0xb2,0xf1,0x28,0x60,0x72,0x62,0xa2,0xd9,0x3c,0x60,0xba,0x62, -0x28,0x60,0x62,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x3c,0x60, -0xbe,0x62,0x28,0x60,0x6e,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x1e,0x60,0xbe,0x62,0x00,0x60,0x0c,0x64,0xa2,0xdb,0x54,0x60,0xc2,0x64,0x5a,0xdb, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xbc,0x62,0xa2,0xd1,0x00,0x60,0x04,0x64, -0xa0,0x80,0x9c,0x84,0x0e,0x03,0xa0,0x84,0xa2,0xdb,0x3c,0x60,0xbe,0x62,0x28,0x60, -0x6e,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x53,0x60,0x7c,0x78, -0xff,0xff,0x00,0x60,0x08,0x64,0xa0,0x80,0x9c,0x84,0xe3,0x03,0xa0,0x84,0xa2,0xdb, -0x57,0xf3,0x10,0x0a,0x00,0xa0,0x00,0x64,0x0c,0x02,0x3c,0x60,0xba,0x62,0x28,0x60, -0x62,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x53,0x60,0x7c,0x78, -0xff,0xff,0x57,0xfb,0x3c,0x60,0xbe,0x62,0x28,0x60,0x6e,0x64,0xa2,0xdb,0x02,0x64, -0x4a,0xdb,0xff,0xff,0x1d,0xff,0xc5,0x00,0x1e,0x60,0x92,0x62,0x67,0x60,0x12,0x63, -0xa2,0xd3,0xa3,0xd1,0xff,0xff,0xd0,0x85,0x67,0x60,0x0e,0x62,0xa2,0xd3,0xff,0xff, -0xd4,0x80,0xff,0xff,0x02,0x05,0x65,0x44,0xa2,0xdb,0xcb,0xf3,0xe1,0xf3,0xfc,0xa0, -0x00,0xa0,0x05,0x03,0x04,0x03,0x67,0x60,0x80,0x62,0x41,0x64,0xa2,0xdb,0x1e,0x60, -0x94,0x62,0x66,0x60,0xb6,0x63,0xa2,0xd3,0xff,0xff,0x0c,0xa4,0xa3,0xdb,0x59,0x60, -0xb2,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1e,0x60,0xbc,0x62,0x00,0x64, -0xa2,0xdb,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xbe,0x62,0x40,0x60,0x00,0x64, -0xa2,0xdb,0x55,0x60,0x24,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x7e,0xf1, -0x3c,0x60,0xa2,0x62,0xa2,0xd9,0xca,0x82,0x1e,0x64,0xa2,0xdb,0xff,0xff,0x2d,0xff, -0x1e,0x60,0xbe,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x55,0x60,0x4a,0x64,0x5a,0xdb, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0xbe,0xfe,0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60, -0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x20,0x44,0x03,0x22,0x08,0x00,0x04,0x65, -0x3d,0x60,0x58,0x4e,0x32,0x78,0xff,0xff,0x56,0x60,0x1b,0x78,0xff,0xff,0x8a,0xf1, -0x1f,0x60,0x60,0x63,0xc3,0x85,0x45,0x4d,0x27,0x60,0xe0,0x65,0x89,0xf3,0x45,0x4c, -0x40,0x48,0x59,0x60,0x8a,0x62,0x28,0x44,0xd4,0x84,0xe8,0x84,0xe8,0x84,0xa2,0xdb, -0x2d,0x45,0xd7,0x80,0x02,0x65,0x18,0x05,0x47,0xd1,0x02,0x65,0x47,0xd3,0x0a,0x65, -0xd0,0x81,0x47,0xd3,0x01,0x05,0x00,0x61,0xf2,0xa3,0x01,0xb0,0x61,0x44,0x06,0x03, -0x2c,0x42,0xa2,0xdb,0x5a,0xdd,0x5a,0x8c,0x44,0xa3,0xea,0x00,0x28,0x42,0x4a,0xdd, -0x4a,0xdb,0x42,0x48,0x44,0xa3,0xe4,0x00,0x28,0x44,0x88,0xfb,0x88,0xf1,0x27,0x60, -0xe0,0x63,0x66,0x60,0xb8,0x62,0xa2,0xd3,0xff,0x65,0xff,0xa0,0xff,0xff,0x01,0x03, -0x00,0x65,0x45,0x4c,0x44,0x48,0x28,0x45,0xd7,0x80,0xa3,0xd1,0x36,0x05,0x5a,0xd3, -0xff,0xff,0x3e,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x45,0xff,0x64,0xd4,0x85,0x2c,0x44, -0xa4,0x85,0x64,0x47,0xb4,0x9c,0x63,0x42,0x04,0x65,0x46,0xd3,0x28,0x45,0xd6,0x80, -0xff,0xff,0x02,0x04,0x04,0xa3,0xe7,0x00,0x62,0x46,0x60,0x41,0x5a,0xd3,0xff,0xff, -0x3e,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x45,0xff,0x64,0xd4,0x85,0x2c,0x44,0xa4,0x85, -0x61,0x47,0xb4,0x84,0xd0,0x80,0x66,0x42,0xe7,0x06,0x60,0x41,0xa2,0xd3,0x5a,0xd1, -0xa3,0xd1,0x64,0x45,0xbd,0xdb,0xa3,0xd3,0x66,0x42,0xa2,0xd9,0x5a,0xdb,0x65,0x44, -0xa3,0xdb,0x61,0x5c,0xfe,0xa3,0x66,0x42,0xd7,0x00,0x88,0xf3,0x89,0xf1,0x60,0x43, -0x66,0x60,0xb8,0x62,0xa2,0xd3,0xff,0x65,0xff,0xa0,0xff,0xff,0x01,0x03,0x00,0x65, -0x45,0x4c,0x44,0x48,0x28,0x45,0xd7,0x80,0xa3,0xd1,0x36,0x05,0x5a,0xd3,0xff,0xff, -0x3e,0xa4,0xa0,0xd3,0xff,0xff,0x60,0x45,0xff,0x64,0xd4,0x85,0x2c,0x44,0xa4,0x85, -0x64,0x47,0xb4,0x9c,0x63,0x42,0x04,0x65,0x46,0xd3,0x28,0x45,0xd6,0x80,0xff,0xff, -0x02,0x04,0x04,0xa3,0xe7,0x00,0x62,0x46,0x60,0x41,0x5a,0xd3,0xff,0xff,0x3e,0xa4, -0xa0,0xd3,0xff,0xff,0x60,0x45,0xff,0x64,0xd4,0x85,0x2c,0x44,0xa4,0x85,0x61,0x47, -0xb4,0x84,0xd0,0x80,0x66,0x42,0xe7,0x06,0x60,0x41,0xa2,0xd3,0x5a,0xd1,0xa3,0xd1, -0x64,0x45,0xbd,0xdb,0xa3,0xd3,0x66,0x42,0xa2,0xd9,0x5a,0xdb,0x65,0x44,0xa3,0xdb, -0x61,0x5c,0xfe,0xa3,0x66,0x42,0xd7,0x00,0x20,0x44,0x3c,0xb4,0x40,0x40,0x1e,0x60, -0xa8,0x62,0xa2,0xd1,0x10,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x1e,0x60, -0xbc,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x2f,0x58,0xff,0xff,0x3c,0x60,0xb2,0x62, -0x28,0x60,0x62,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60, -0xbc,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x2f,0x58,0xff,0xff,0x1e,0x60,0xbc,0x62, -0xa2,0xd1,0x00,0x60,0x04,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x1e,0x60,0xbc,0x62,0xa2,0xd1,0x00,0x60,0x08,0x64,0xb0,0x84,0xa2,0xdb, -0xff,0xff,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x20,0x40,0x03,0x26,0x06,0x00,0x1f,0x60, -0x60,0x63,0x8a,0xf1,0x08,0x60,0x80,0x64,0x23,0x00,0x3d,0x60,0x4c,0x63,0xbd,0xd3, -0xff,0xff,0x00,0xa0,0x60,0x45,0x15,0x03,0xc7,0x85,0x63,0x5c,0x04,0x64,0xc0,0x81, -0x31,0xf2,0x50,0xfe,0x59,0xd1,0x32,0xf2,0xd0,0x80,0x59,0xd1,0x33,0xf2,0xd0,0x80, -0x59,0xd1,0xff,0xff,0xd0,0x80,0xff,0xff,0x76,0x03,0x44,0xa3,0xd7,0x80,0xff,0xff, -0xec,0x02,0x3d,0x60,0x4e,0x63,0x3d,0x60,0x4c,0x62,0xa2,0xd1,0x1a,0x60,0x90,0x64, -0xd0,0x80,0xff,0xff,0x68,0x06,0xc3,0x83,0x87,0xfd,0xff,0xff,0x7f,0xf3,0x25,0xf0, -0xbd,0xdb,0x64,0x44,0x00,0x7f,0xbd,0xdb,0x64,0x47,0x00,0x7f,0xbd,0xdb,0x31,0xf0, -0xbd,0xd9,0xff,0xff,0x32,0xf0,0xbd,0xd9,0x33,0xf0,0xff,0xff,0xbd,0xd9,0xff,0x60, -0xff,0x7c,0x38,0xf2,0x00,0xf4,0x05,0xa4,0xa0,0xd8,0x06,0xf0,0xff,0xff,0xbd,0xd9, -0x07,0xf0,0xbd,0xd9,0x20,0x44,0x03,0xb4,0xff,0xff,0x0a,0x02,0x16,0x60,0x42,0x62, -0xa2,0xd3,0xff,0xff,0x60,0x40,0x01,0x3a,0x03,0x00,0x64,0x40,0x01,0x2a,0x3b,0x00, -0x57,0x60,0x58,0x4e,0x59,0x78,0xff,0xff,0xff,0x60,0xfe,0x64,0xd0,0x80,0xff,0xff, -0x32,0x03,0xd5,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x2d,0x05,0x00,0x36,0x12,0x00, -0x66,0x60,0xc4,0x64,0xa0,0xd3,0xff,0xff,0x00,0xa0,0x60,0x43,0x0b,0x03,0x58,0x60, -0x58,0x4e,0xb5,0x78,0xff,0xff,0x17,0x60,0x82,0x64,0xa0,0xd1,0x65,0x44,0xd0,0x80, -0xff,0xff,0x60,0x02,0x87,0xf3,0xff,0xff,0x3e,0xa4,0x60,0x43,0xbd,0xd9,0x61,0x44, -0xbd,0xdb,0xff,0x60,0xff,0x64,0xd0,0x80,0xff,0xff,0x04,0x02,0x66,0x60,0xb8,0x62, -0x00,0x64,0xa2,0xdb,0x87,0xf3,0x10,0x65,0xc4,0x83,0x00,0x64,0x08,0xf0,0xa3,0xdb, -0x64,0x47,0x60,0x45,0x00,0x3b,0x46,0x00,0xbd,0xdb,0xdc,0x84,0xe8,0x81,0x10,0x64, -0x58,0xd0,0xcd,0x81,0xbd,0xd9,0xfc,0x02,0xd8,0x83,0x04,0x64,0x40,0x4d,0x07,0x61, -0x65,0x40,0x01,0x2a,0xbd,0xd0,0xff,0xff,0x64,0x44,0x00,0x7f,0x2d,0xda,0x5a,0x8d, -0x64,0x47,0x00,0x7f,0x2d,0xda,0xcd,0x81,0x5a,0x8d,0xf4,0x02,0x87,0xf1,0x32,0x63, -0xc3,0x83,0x04,0x61,0x65,0x40,0x01,0x26,0x02,0xa1,0xa1,0xd2,0xff,0xff,0x01,0xa8, -0x59,0xd2,0x20,0x02,0x59,0xd0,0xcc,0x84,0xbd,0xd9,0xfc,0x02,0x00,0x64,0xbd,0xdb, -0x59,0xd2,0x59,0xd0,0x03,0xa8,0x7f,0xf3,0x15,0x02,0x59,0xd0,0xff,0xff,0xd0,0x80, -0xff,0xff,0x10,0x02,0x87,0xf3,0x32,0x65,0xc4,0x83,0x00,0x61,0xa3,0xd3,0xff,0xff, -0x60,0x40,0xff,0x22,0x14,0x00,0x80,0x2a,0x10,0x00,0x60,0x40,0x82,0x3a,0x03,0x00, -0x01,0xb9,0x0b,0x00,0x24,0x00,0x84,0x3a,0x02,0x00,0x02,0xb9,0x06,0x00,0x8b,0x3a, -0x02,0x00,0x04,0xb9,0x02,0x00,0x96,0x36,0x08,0xb9,0x02,0xa3,0xe7,0x00,0x87,0xf3, -0x3c,0x65,0xc4,0x82,0x61,0x43,0xa2,0xdd,0x20,0x40,0x03,0x26,0x09,0x00,0x8a,0xf3, -0xff,0xff,0x44,0xa4,0x8a,0xfb,0x89,0xf3,0xff,0xff,0x04,0xa4,0xa2,0xdb,0x07,0x00, -0x3d,0x60,0x4c,0x62,0xa2,0xd3,0xff,0xff,0x44,0xa4,0xa2,0xdb,0xff,0xff,0x26,0x46, -0x2f,0x58,0xff,0xff,0x66,0x60,0xca,0x62,0x2e,0x44,0xa2,0xdb,0x66,0x60,0xce,0x65, -0x66,0x60,0xc4,0x62,0x00,0x64,0xa2,0xdb,0xa5,0xdb,0x01,0xf2,0x10,0x63,0x00,0x7f, -0xf4,0xa4,0x60,0x41,0x10,0x63,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2, -0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x60,0x5c,0x63,0x44, -0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2, -0x01,0xa3,0x00,0x7f,0x60,0x45,0x64,0x44,0xad,0xa8,0x07,0xa8,0x0c,0x03,0x15,0x03, -0xc9,0x81,0xd5,0x81,0x61,0x44,0x80,0x27,0x03,0x00,0xff,0xa0,0xc7,0x83,0xdb,0x07, -0x58,0x60,0x61,0x78,0xff,0xff,0x66,0x60,0xcc,0x62,0x5a,0xdd,0x65,0x44,0x5a,0xdb, -0x61,0x44,0x5a,0xdb,0x58,0x60,0x1e,0x78,0xff,0xff,0x66,0x60,0xc4,0x62,0xa2,0xdd, -0xd5,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0xe3,0x04,0x17,0x60,0x82,0x61,0x58,0x60, -0x58,0x4e,0xb5,0x78,0xff,0xff,0x65,0x44,0xa1,0xdb,0x08,0xa1,0xa1,0xdb,0x02,0xa1, -0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00, -0xa0,0xd2,0x01,0xa3,0x00,0x7f,0xa1,0xdb,0x1f,0x60,0x54,0x61,0x63,0x44,0x01,0x22, -0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3, -0x00,0x7f,0xa1,0xdb,0x1f,0x60,0x56,0x61,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac, -0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0xf2,0xa0, -0xff,0xff,0x01,0x06,0x0e,0x64,0xa1,0xdb,0x17,0x60,0x80,0x61,0x63,0x44,0x01,0x22, -0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3, -0x00,0x7f,0xa1,0xdb,0x3e,0x60,0x58,0x4e,0xae,0x78,0xff,0xff,0x1f,0x60,0x56,0x61, -0xa1,0xd1,0x1f,0x60,0x1c,0x63,0x1f,0x60,0x54,0x62,0xa2,0xd3,0x01,0x61,0x00,0x65, -0xff,0xa0,0xff,0xff,0x04,0x03,0xe1,0x81,0xcc,0x84,0x02,0xa3,0xf9,0x00,0x64,0x44, -0x05,0x7c,0xb5,0x85,0xbd,0xd9,0xcc,0x84,0x00,0xa0,0xe1,0x81,0xfa,0x02,0x65,0x44, -0xa5,0xfb,0x16,0x60,0x42,0x62,0xa2,0xd3,0x01,0x7c,0x04,0xa8,0xd5,0xf9,0x05,0x02, -0x0c,0x60,0x50,0x62,0x67,0x60,0x13,0x64,0xa2,0xdb,0x0b,0x65,0x3d,0x60,0x58,0x4e, -0x32,0x78,0xff,0xff,0xff,0x60,0xfe,0x7c,0x58,0x60,0x65,0x78,0xff,0xff,0x45,0x4d, -0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0xa0,0x60,0x00,0x64,0xd4,0x80,0xff,0xff, -0x39,0x02,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47, -0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0xf8,0x65,0xd4,0x80,0xff,0xff,0x2a,0x02, -0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x65,0x5c,0x58,0x60,0x58,0x4e,0xb5,0x78, -0xff,0xff,0x67,0x41,0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x2d,0x44,0xf1,0xa0, -0xff,0xff,0x1c,0x04,0x45,0x4d,0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x65,0x41, -0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x66,0x60,0xc6,0x62,0x65,0x44,0xa2,0xdb, -0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x66,0x60,0xc8,0x62,0x65,0x44,0xa2,0xdb, -0x2d,0x45,0x04,0x00,0xff,0x60,0xff,0x7c,0x64,0x41,0x00,0x65,0x66,0x60,0xca,0x62, -0xa2,0xd3,0xff,0xff,0x40,0x4e,0x2e,0x58,0xff,0xff,0x66,0x60,0xca,0x62,0x2e,0x44, -0xa2,0xdb,0x66,0x60,0xcc,0x62,0x5a,0xd3,0x5a,0xd1,0x00,0xa0,0x60,0x43,0x36,0x03, -0x5a,0xd3,0x64,0x45,0x60,0x41,0x1c,0x00,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac, -0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x60,0x5c, -0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00, -0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x60,0x45,0x64,0x44,0xae,0xa8,0xff,0xff,0x07,0x03, -0xc9,0x81,0xd5,0x81,0x61,0x44,0xff,0xa0,0xc7,0x83,0xde,0x07,0x0f,0x00,0xdf,0x83, -0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0xf8,0x60,0xa0,0x64,0xd4,0x80,0xff,0xff, -0x05,0x02,0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x01,0x00,0x00,0x65,0x66,0x60, -0xca,0x62,0xa2,0xd3,0xff,0xff,0x40,0x4e,0x2e,0x58,0xff,0xff,0x63,0x44,0x01,0x22, -0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3, -0x00,0x7f,0x60,0x45,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3, -0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x60,0x47,0xb4,0x85,0x2e,0x58, -0xff,0xff,0x2f,0x58,0xff,0xff,0x1e,0x60,0xda,0x62,0xa2,0xd1,0x00,0x60,0x04,0x64, -0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2f,0x58,0xff,0xff,0xbb,0xf1,0x28,0x60, -0xae,0x62,0xa2,0xd9,0x3c,0x60,0xc2,0x62,0x28,0x60,0xaa,0x64,0xa2,0xdb,0x02,0x64, -0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xdc,0x62,0x00,0x60,0x0c,0x64,0xa2,0xdb, -0x58,0x60,0xf5,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xda,0x62, -0xa2,0xd1,0x00,0x60,0x08,0x64,0xa0,0x80,0x9c,0x84,0x0c,0x03,0xa0,0x84,0xa2,0xdb, -0x0f,0x47,0x67,0x60,0x42,0x62,0x6f,0x60,0x00,0x64,0xa2,0xdb,0x58,0x4f,0x29,0x00, -0x07,0x4f,0xd4,0x00,0x1e,0x60,0xda,0x62,0xa2,0xd1,0xff,0x60,0xfb,0x61,0xa1,0x84, -0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0xcb,0xf3,0xff,0xff,0xfc,0xa0,0xff,0xff, -0xc5,0x02,0x17,0x60,0x7a,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff,0x02,0x2a,0xbe,0x00, -0x0f,0x47,0x67,0x60,0x42,0x62,0x66,0x60,0x00,0x64,0xa2,0xdb,0x58,0x4f,0x09,0x00, -0x67,0x60,0x42,0x62,0x69,0x60,0x00,0x64,0xa2,0xdb,0x58,0x4f,0x02,0x00,0x07,0x4f, -0xad,0x00,0x48,0xf1,0x0f,0x4e,0x64,0x41,0x41,0x4d,0x40,0xa1,0xa2,0xff,0x19,0x60, -0x58,0x4f,0xa2,0x78,0xff,0xff,0xa3,0xff,0x06,0x03,0x2d,0x41,0x19,0x60,0x58,0x4f, -0xc4,0x78,0xff,0xff,0x08,0xfe,0x0e,0x4f,0x03,0x02,0x5a,0x60,0xd9,0x78,0xff,0xff, -0x67,0x60,0x42,0x64,0xa0,0xd3,0xff,0xff,0x60,0x47,0xff,0xff,0x66,0x3a,0x59,0x00, -0x50,0xf1,0x5b,0x60,0x38,0x64,0xa0,0xd9,0x7f,0xf1,0x5b,0x60,0x3a,0x64,0xa0,0xd9, -0x84,0xf1,0x5b,0x60,0x42,0x64,0xa0,0xd9,0xcb,0xf1,0x5b,0x60,0x44,0x64,0xa0,0xd9, -0xbd,0xf1,0x5b,0x60,0x46,0x64,0xa0,0xd9,0xc7,0xf1,0x5b,0x60,0x4c,0x64,0xa0,0xd9, -0xc8,0xf1,0x5b,0x60,0x4e,0x64,0xa0,0xd9,0x5b,0x60,0x3c,0x63,0x81,0xf1,0xbd,0xd9, -0x81,0xf1,0xff,0xff,0xbd,0xd9,0x81,0xf1,0xa3,0xd9,0x59,0x60,0xa6,0x65,0x5b,0x60, -0x50,0x64,0x65,0x41,0xd4,0x85,0xfe,0xa1,0x65,0x43,0x0a,0xa3,0x38,0xfc,0x46,0x48, -0x00,0xf4,0x04,0x63,0x0a,0xa3,0x81,0x60,0x87,0x64,0x02,0xfa,0x67,0x60,0x42,0x64, -0xa0,0xd3,0xff,0xff,0x03,0xfa,0x65,0x47,0x05,0xfa,0x60,0x47,0x8e,0xa0,0xff,0xff, -0x09,0x04,0x8e,0xa5,0x72,0x64,0x07,0x00,0x84,0xa0,0xff,0xff,0x03,0x04,0x84,0xa5, -0x7c,0x64,0x01,0x00,0x00,0x65,0x59,0xd1,0xbd,0xd8,0xfe,0xa4,0xff,0xff,0xfb,0x07, -0x65,0x44,0x00,0xa0,0x00,0xf4,0x02,0x03,0x04,0x63,0xee,0x00,0x5a,0x60,0x8b,0x78, -0xff,0xff,0x6e,0x3a,0x00,0x00,0x67,0x3a,0x00,0x00,0x68,0x3a,0x00,0x00,0x69,0x36, -0x03,0x00,0x5a,0x60,0x4a,0x78,0xff,0xff,0x61,0x60,0xc2,0x63,0x61,0x60,0xc6,0x62, -0xa2,0xd3,0xa3,0xd1,0x00,0xa0,0xff,0xff,0x56,0x03,0x02,0x60,0x80,0x63,0x64,0x41, -0x61,0x60,0xd8,0x65,0xc5,0x81,0xfe,0xa1,0xd3,0x85,0x0a,0xa3,0x38,0xfc,0x46,0x48, -0x00,0xf4,0x81,0x60,0x87,0x64,0x02,0xfa,0x67,0x60,0x42,0x64,0xa0,0xd3,0xff,0xff, -0x03,0xfa,0x63,0x47,0x05,0xfa,0x04,0x63,0x0a,0xa3,0x65,0x44,0x8e,0xa0,0xff,0xff, -0x09,0x04,0x8e,0xa5,0x72,0x64,0x08,0x00,0x84,0xa0,0xff,0xff,0x03,0x04,0x84,0xa5, -0x7c,0x64,0x02,0x00,0x00,0x65,0x40,0x49,0x59,0xd1,0xbd,0xd8,0xfe,0xa4,0xff,0xff, -0xfb,0x07,0x65,0x44,0x00,0xa0,0xff,0xff,0x03,0x03,0x00,0xf4,0x04,0x63,0xec,0x00, -0x61,0x60,0xc2,0x62,0x61,0x60,0xd8,0x61,0xfe,0xa1,0xa2,0xd3,0x29,0x45,0x00,0xa0, -0x7c,0x62,0x4e,0x03,0xd6,0x85,0xd4,0x80,0x60,0x42,0x09,0x06,0x65,0x44,0xd6,0x85, -0x07,0x00,0x84,0xa0,0xff,0xff,0x03,0x04,0x84,0xa5,0x7c,0x64,0x01,0x00,0x00,0x65, -0x59,0xd1,0xbd,0xd8,0xfe,0xa4,0xff,0xff,0xfb,0x07,0x65,0x44,0x00,0xa0,0x00,0xf4, -0x37,0x03,0x04,0x63,0xee,0x00,0x00,0x64,0xd0,0x80,0xff,0xff,0x03,0x02,0x5a,0x60, -0xc5,0x78,0xff,0xff,0x64,0x45,0x64,0x44,0x0a,0xa4,0x38,0xfa,0x61,0x60,0xd8,0x61, -0xfe,0xa1,0x46,0x48,0x00,0xf4,0x04,0x63,0x81,0x60,0x87,0x64,0x02,0xfa,0x67,0x60, -0x42,0x64,0xa0,0xd3,0xff,0xff,0x03,0xfa,0x65,0x47,0x05,0xfa,0x0a,0xa3,0x65,0x44, -0x8e,0xa0,0xff,0xff,0x09,0x04,0x8e,0xa5,0x72,0x64,0x07,0x00,0x84,0xa0,0xff,0xff, -0x03,0x04,0x84,0xa5,0x7c,0x64,0x01,0x00,0x00,0x65,0x59,0xd1,0xbd,0xd8,0xfe,0xa4, -0xff,0xff,0xfb,0x07,0x65,0x44,0x00,0xa0,0x00,0xf4,0x02,0x03,0x04,0x63,0xee,0x00, -0x5a,0x60,0x8b,0x78,0xff,0xff,0x6a,0x3a,0x00,0x00,0x64,0x3a,0x0f,0x00,0x0a,0x63, -0x38,0xfc,0x46,0x48,0x00,0xf4,0x81,0x60,0x87,0x64,0x02,0xfa,0x67,0x60,0x42,0x64, -0xa0,0xd3,0xff,0xff,0x03,0xfa,0x63,0x47,0x05,0xfa,0x2e,0x00,0x6f,0x3a,0x66,0x00, -0x12,0x63,0x38,0xfc,0xa0,0x60,0x01,0x64,0x31,0xfa,0xf0,0x60,0xf8,0x64,0x32,0xfa, -0x04,0x60,0xf0,0x64,0x33,0xfa,0xff,0xff,0x81,0xf1,0x2b,0xf8,0x82,0xf1,0xff,0xff, -0x2c,0xf8,0x83,0xf1,0x2d,0xf8,0x46,0x48,0x00,0xf4,0xaa,0x60,0xaa,0x64,0x02,0xfa, -0x00,0x60,0x03,0x64,0x03,0xfa,0x00,0x60,0x00,0x64,0x04,0xfa,0x81,0x60,0x87,0x64, -0x05,0xfa,0x00,0x64,0x0a,0xfa,0x67,0x60,0x42,0x64,0xa0,0xd3,0xff,0xff,0x06,0xfa, -0x63,0x47,0x08,0xfa,0x28,0x46,0x0d,0x00,0x28,0x46,0x81,0xf1,0x2b,0xf8,0x31,0xf8, -0xff,0xff,0x82,0xf1,0x2c,0xf8,0x32,0xf8,0xff,0xff,0x83,0xf1,0x2d,0xf8,0x33,0xf8, -0xff,0xff,0xbd,0xf1,0x2e,0xf8,0xbe,0xf1,0xff,0xff,0x2f,0xf8,0xbf,0xf1,0x30,0xf8, -0xff,0xff,0x85,0xf3,0xff,0xff,0x08,0xbc,0x43,0xf1,0xff,0xff,0x64,0x40,0x01,0x2a, -0x03,0x00,0x60,0x47,0x40,0xbc,0x60,0x47,0x29,0xfa,0x00,0x63,0x28,0xfc,0x22,0xfc, -0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff,0xff,0x64,0x23,0xfa,0xff,0x7f,0x00,0x7e, -0x0e,0xfa,0x3c,0x60,0x82,0x62,0x3c,0x60,0x28,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb, -0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xc1,0xfe,0x14,0x00,0x0f,0x4e,0x46,0x45, -0x3c,0x60,0x82,0x62,0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff, -0xd1,0xfe,0x0e,0x4f,0x2f,0x58,0xff,0xff,0x61,0x60,0xc2,0x62,0xa2,0xd1,0x61,0x60, -0xd8,0x64,0xc0,0x83,0x61,0x60,0xc8,0x62,0xa2,0xd3,0xbd,0xdb,0xf6,0xa0,0x00,0xa0, -0x01,0x03,0x34,0x02,0x61,0x60,0xd6,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff, -0x2d,0x03,0x1e,0x60,0x92,0x62,0x61,0x60,0xd2,0x61,0xa2,0xd3,0xa1,0xd1,0xff,0xff, -0xd0,0x85,0x1e,0x60,0x94,0x62,0x61,0x60,0xd4,0x61,0xa2,0xd3,0xa1,0xd1,0x01,0x05, -0xff,0xa4,0xd0,0x84,0x65,0x44,0x02,0x02,0xfc,0x23,0x14,0x00,0x61,0x60,0xd2,0x62, -0xa2,0xd3,0xbd,0xdb,0x61,0x60,0xd4,0x62,0xa2,0xd3,0xbd,0xdb,0x00,0x64,0xbd,0xdb, -0xbd,0xdb,0xbd,0xdb,0xff,0xff,0xbd,0xdb,0xbd,0xdb,0xbd,0xdb,0xff,0xff,0xbd,0xdb, -0xbd,0xdb,0x2f,0x00,0x61,0x60,0xd6,0x62,0x02,0x64,0xa2,0xdb,0x1e,0x60,0x92,0x62, -0xa2,0xd3,0xbd,0xdb,0x1e,0x60,0x94,0x62,0xa2,0xd3,0xbd,0xdb,0x27,0x60,0xe0,0x65, -0x88,0xf3,0xff,0xff,0xd4,0x84,0xe8,0x84,0xe8,0x84,0xbd,0xdb,0x64,0x60,0x58,0x62, -0xa2,0xd1,0x00,0x64,0xa2,0xdb,0xbd,0xd9,0x27,0x41,0x06,0xa1,0xa1,0xd1,0xbd,0xd9, -0x59,0xd1,0xff,0xff,0xbd,0xd9,0x59,0xd1,0xbd,0xd9,0x27,0x41,0x04,0xa1,0xa1,0xd3, -0xbd,0xdb,0x27,0x41,0x02,0xa1,0xa1,0xd1,0xff,0xff,0xd0,0x84,0xbd,0xdb,0x51,0xf3, -0xbd,0xdb,0x61,0x60,0xd6,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff,0x05,0x02, -0x61,0x60,0xc4,0x62,0xa2,0xd3,0xbd,0xdb,0x09,0x00,0x61,0x60,0xc4,0x62,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0xff,0xa0,0xbd,0xdb,0x09,0x02,0x00,0x64,0xbd,0xdb, -0xbd,0xdb,0xbd,0xdb,0xff,0xff,0xbd,0xdb,0xbd,0xdb,0xbd,0xdb,0x20,0x00,0x61,0x60, -0xca,0x62,0xa2,0xd1,0xbd,0xd9,0x61,0x60,0xcc,0x62,0xa2,0xd1,0xbd,0xd9,0x61,0x60, -0xce,0x62,0xa2,0xd1,0xbd,0xd9,0xff,0xff,0x59,0xf3,0x80,0x65,0xc4,0x87,0xff,0xb4, -0xbd,0xdb,0x58,0xf3,0xbd,0xdb,0xf4,0xb6,0x7e,0x00,0x00,0x10,0x61,0x60,0xd0,0x62, -0xa2,0xd3,0xbd,0xdb,0x59,0x60,0x9c,0x62,0xa2,0xd3,0xbd,0xdb,0x59,0x60,0x9e,0x62, -0xa2,0xd3,0xbd,0xdb,0x61,0x60,0xc2,0x63,0x02,0x60,0x80,0x65,0xa3,0xd3,0xff,0xff, -0x28,0xa4,0xd4,0x80,0xff,0xff,0x05,0x04,0x61,0x60,0xc6,0x62,0x01,0x64,0xa2,0xdb, -0x00,0x64,0xa3,0xdb,0x61,0x60,0xc8,0x62,0xa2,0xd3,0xff,0xff,0xf6,0xa0,0x00,0xa0, -0x01,0x03,0x0f,0x02,0x61,0x60,0xd6,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xfe,0xa0, -0x06,0x03,0x05,0x03,0x01,0x64,0xa2,0xdb,0x5a,0x60,0xdb,0x78,0xff,0xff,0x00,0x64, -0xa2,0xdb,0x61,0x60,0xc8,0x62,0xa2,0xd1,0xff,0xff,0x64,0x44,0xf4,0xa0,0xff,0xff, -0x07,0x03,0x59,0x60,0xc0,0x64,0xc0,0x83,0xa3,0xd3,0xff,0xff,0xdc,0x84,0xa3,0xdb, -0x59,0x60,0xa6,0x62,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x2e,0x58,0xff,0xff, -0x64,0x60,0x5c,0x62,0xa2,0xd1,0x64,0x60,0x62,0x64,0xc0,0x83,0x64,0x60,0x5e,0x62, -0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb,0xbd,0xdb,0x1e,0x60,0x92,0x62,0xa2,0xd3, -0xbd,0xdb,0x1e,0x60,0x94,0x62,0xa2,0xd3,0xbd,0xdb,0x66,0x60,0x24,0x62,0xa2,0xd3, -0xbd,0xdb,0x66,0x60,0x26,0x62,0xa2,0xd3,0xbd,0xdb,0x66,0x60,0x28,0x62,0xa2,0xd3, -0xbd,0xdb,0x66,0x60,0x22,0x62,0xa2,0xd3,0xbd,0xdb,0x59,0x60,0x9c,0x62,0xa2,0xd3, -0xbd,0xdb,0xff,0xff,0x58,0xf3,0xbd,0xdb,0x59,0xf3,0x80,0x65,0xc4,0x87,0xff,0xb4, -0xbd,0xdb,0x5a,0xf3,0x80,0x65,0xc4,0x87,0xff,0xb4,0xbd,0xdb,0xff,0xff,0x81,0xf3, -0xbd,0xdb,0x82,0xf3,0xff,0xff,0xbd,0xdb,0x83,0xf3,0xa3,0xdb,0x64,0x60,0x5c,0x63, -0x01,0x60,0xc0,0x65,0xa3,0xd3,0xff,0xff,0x1c,0xa4,0xd4,0x80,0xff,0xff,0x05,0x04, -0x64,0x60,0x60,0x62,0x01,0x64,0xa2,0xdb,0x00,0x64,0xa3,0xdb,0x2e,0x58,0xff,0xff, -0x1e,0x60,0xce,0x62,0xa2,0xd1,0x00,0x60,0x04,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0xba,0xf1,0x28,0x60,0x96,0x62,0xa2,0xd9,0x3c,0x60, -0xc6,0x62,0x28,0x60,0x92,0x64,0xa2,0xdb,0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff, -0x1e,0x60,0xd0,0x62,0x00,0x60,0x04,0x64,0xa2,0xdb,0x5c,0x60,0x37,0x64,0x5a,0xdb, -0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xce,0x62,0x00,0x64,0xa2,0xdb,0xcb,0xf3, -0xff,0xff,0xfc,0xa0,0xff,0xff,0xdf,0x02,0x66,0x60,0x28,0x62,0x0f,0x64,0xa2,0xdb, -0x17,0x60,0xea,0x64,0xa0,0xd3,0xff,0xff,0x60,0x41,0x02,0xa4,0xff,0xff,0x9c,0xa0, -0xff,0xff,0x01,0x04,0x00,0x64,0x60,0x45,0x18,0x60,0x56,0x62,0xc6,0x82,0xa2,0xd1, -0x00,0x63,0xa2,0xdd,0x18,0x60,0x54,0x63,0xa3,0xd3,0xff,0xff,0xd0,0x84,0xa3,0xdb, -0x17,0x60,0xee,0x62,0xc6,0x82,0xa2,0xd1,0x00,0x63,0xa2,0xdd,0x17,0x60,0xec,0x63, -0xa3,0xd3,0xff,0xff,0xd0,0x84,0xa3,0xdb,0x17,0x60,0xea,0x63,0x65,0x44,0xa3,0xdb, -0x61,0x45,0x18,0x60,0xba,0x63,0xa3,0xd1,0x18,0x60,0x56,0x64,0xc4,0x84,0xa0,0xd3, -0xff,0xff,0x60,0x41,0xc0,0x84,0xa3,0xdb,0x18,0x60,0x54,0x63,0xa3,0xd1,0xff,0xff, -0xc1,0x84,0xa3,0xdb,0x18,0x60,0x52,0x63,0xa3,0xd1,0x17,0x60,0xee,0x64,0xc4,0x84, -0xa0,0xd3,0xff,0xff,0x60,0x41,0xc0,0x84,0xa3,0xdb,0x17,0x60,0xec,0x63,0xa3,0xd1, -0xff,0xff,0xc1,0x84,0xa3,0xdb,0xe2,0xa0,0x00,0x64,0x03,0x05,0x05,0x7c,0xb8,0xf9, -0x3f,0x00,0x00,0x63,0x18,0x60,0x52,0x64,0xa0,0xdd,0x18,0x60,0xba,0x64,0xa0,0xdd, -0x18,0x60,0xc6,0x64,0x64,0x63,0xa0,0xdd,0x18,0x60,0x54,0x63,0xa3,0xd3,0xff,0xff, -0x00,0xbc,0x60,0x41,0x2d,0x03,0x02,0x60,0x8f,0x65,0x17,0x60,0xec,0x62,0xa2,0xd3, -0xd5,0x80,0xff,0xff,0x03,0x06,0xe9,0x81,0xe8,0x84,0xfa,0x00,0x60,0x5c,0x61,0x44, -0xe0,0x84,0xe0,0x84,0x60,0x41,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x60,0x45,0xe0,0x84, -0xc4,0x85,0xc5,0x85,0x00,0x62,0x65,0x44,0x64,0x45,0x11,0x61,0xe0,0x84,0xcd,0x81, -0xfd,0x04,0x01,0x00,0xe0,0x84,0xf2,0x82,0xff,0xff,0x02,0x24,0xc6,0x82,0x02,0x28, -0xd6,0x82,0xe2,0x80,0xcd,0x81,0x02,0x28,0x01,0xbc,0xf4,0x02,0x01,0x2a,0xc6,0x82, -0x60,0x43,0x59,0x60,0x9e,0x62,0xa2,0xdd,0x66,0x60,0x22,0x62,0xa2,0xdd,0x63,0x44, -0xd3,0xa0,0x01,0x65,0x0e,0x04,0x1f,0xf3,0x59,0xf3,0x60,0x40,0x10,0x2a,0x67,0x00, -0xec,0xa0,0x67,0x60,0x6c,0x64,0x63,0x04,0xa0,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff, -0x5e,0x03,0x18,0x60,0xbc,0x65,0x51,0xf3,0xff,0xff,0xe0,0x84,0xc4,0x83,0xa3,0xd3, -0xff,0xff,0xf8,0xa0,0x03,0x65,0x53,0x05,0x18,0x60,0x52,0x64,0xa0,0xd3,0xff,0xff, -0xe2,0xa0,0x18,0x60,0xba,0x63,0x33,0x04,0xa3,0xd3,0xff,0xff,0x00,0xbc,0x60,0x41, -0x2f,0x03,0x02,0x60,0x8f,0x65,0x18,0x60,0x52,0x62,0xa2,0xd3,0xd5,0x80,0xff,0xff, -0x03,0x06,0xe9,0x81,0xe8,0x84,0xfa,0x00,0x60,0x5c,0x61,0x44,0xe0,0x84,0xe0,0x84, -0x60,0x41,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x60,0x45,0xe0,0x84,0xc4,0x85,0xc5,0x85, -0x00,0x62,0x65,0x44,0x64,0x45,0x11,0x61,0xe0,0x84,0xcd,0x81,0xfd,0x04,0x01,0x00, -0xe0,0x84,0xf2,0x82,0xff,0xff,0x02,0x24,0xc6,0x82,0x02,0x28,0xd6,0x82,0xe2,0x80, -0xcd,0x81,0x02,0x28,0x01,0xbc,0xf4,0x02,0x01,0x2a,0xc6,0x82,0x01,0x00,0x69,0x00, -0x60,0x43,0x18,0x60,0xc6,0x62,0xa2,0xdd,0x63,0x44,0xd3,0xa0,0x00,0x63,0x18,0x60, -0x52,0x62,0xa2,0xdd,0x18,0x60,0xba,0x62,0xa2,0xdd,0x5b,0x04,0x18,0x60,0xc6,0x63, -0xa3,0xd1,0x66,0x60,0x22,0x62,0xa2,0xd9,0x64,0x64,0xa3,0xdb,0x02,0x65,0x05,0x64, -0xb8,0xfb,0x66,0x60,0x24,0x63,0x65,0x44,0xbd,0xdb,0x51,0xf3,0xa3,0xdb,0x51,0xf3, -0x50,0xf3,0x60,0x41,0xff,0xa0,0xe8,0x85,0x41,0x03,0xff,0xa1,0x59,0x60,0x6a,0x64, -0xa0,0xd3,0xff,0xff,0xa4,0x80,0x65,0x44,0xf5,0x03,0x50,0xfb,0x61,0x43,0x66,0x60, -0x28,0x62,0xa2,0xdd,0x51,0xfd,0x61,0x45,0x00,0x63,0x17,0x60,0xe6,0x62,0xa2,0xdd, -0x17,0x60,0xe4,0x62,0xa2,0xdd,0x17,0x60,0xec,0x62,0xa2,0xdd,0x18,0x60,0x54,0x62, -0xa2,0xdd,0x17,0x60,0xe8,0x62,0xa2,0xdd,0x67,0x60,0x6c,0x62,0xa2,0xdd,0x64,0x61, -0x17,0x60,0xee,0x63,0x00,0x64,0xc9,0x81,0xbd,0xdb,0xfd,0x02,0x64,0x61,0x18,0x60, -0x56,0x63,0x00,0x64,0xc9,0x81,0xbd,0xdb,0xfd,0x02,0x65,0x41,0xe1,0x85,0x18,0x60, -0xbc,0x63,0xc7,0x83,0xa3,0xd3,0xff,0xff,0xf8,0xa0,0xff,0xff,0xc0,0x05,0x04,0x61, -0x18,0x60,0xbc,0x63,0x00,0x64,0xcd,0x81,0xbd,0xdb,0xfd,0x02,0x5e,0x60,0x32,0x78, -0xff,0xff,0x17,0x60,0xec,0x63,0xa3,0xd3,0xff,0xff,0xe2,0xa0,0x59,0x60,0x9e,0x63, -0xa3,0xd3,0x1d,0x04,0xdd,0xa0,0xff,0xff,0x23,0x05,0x50,0xf3,0x04,0x65,0xf8,0xa0, -0xff,0xff,0x32,0x02,0xb8,0xf3,0xff,0xff,0xfd,0xa0,0x03,0x64,0x2d,0x03,0xb8,0xfb, -0x67,0x60,0x6e,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x25,0x00,0x17,0x60, -0xe8,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x1e,0x02,0x6f,0x00,0x18,0x60, -0xc6,0x63,0xa3,0xd3,0xff,0xff,0xdd,0xa0,0x64,0x64,0xa3,0xdb,0x05,0x65,0xef,0x04, -0x05,0x64,0xb8,0xfb,0x51,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x5f,0x03,0x03,0x60, -0xe8,0x65,0x17,0x60,0xe4,0x64,0xa0,0xd3,0x59,0xf3,0xd4,0x80,0x06,0x65,0x56,0x04, -0xf1,0xa0,0xff,0xff,0xdc,0x05,0x52,0x00,0x66,0x60,0x24,0x63,0x65,0x44,0xbd,0xdb, -0xfa,0xa0,0x51,0xf3,0x15,0x02,0xbd,0xdb,0x60,0x5c,0x08,0x65,0x03,0x61,0x67,0x60, -0x6c,0x62,0x01,0x64,0xa2,0xdb,0x04,0x00,0xd0,0x80,0xe8,0x85,0x3f,0x03,0xff,0xa1, -0x59,0x60,0x6a,0x64,0xa0,0xd3,0xff,0xff,0xa4,0x80,0x65,0x44,0xf5,0x03,0x0e,0x00, -0xbd,0xdb,0x50,0xf3,0x60,0x41,0xf8,0xa0,0xe0,0x85,0x30,0x03,0x01,0xa1,0x59,0x60, -0x6a,0x64,0xa0,0xd3,0xff,0xff,0xa4,0x80,0x65,0x44,0xf5,0x03,0x50,0xfb,0x61,0x43, -0x51,0xfd,0x66,0x60,0x28,0x62,0xa2,0xdd,0x00,0x63,0x17,0x60,0xe6,0x62,0xa2,0xdd, -0x17,0x60,0xe4,0x62,0xa2,0xdd,0x17,0x60,0xec,0x62,0xa2,0xdd,0x18,0x60,0x54,0x62, -0xa2,0xdd,0x64,0x61,0x17,0x60,0xee,0x63,0x00,0x64,0xc9,0x81,0xbd,0xdb,0xfd,0x02, -0x64,0x61,0x18,0x60,0x56,0x63,0x00,0x64,0xc9,0x81,0xbd,0xdb,0xfd,0x02,0x04,0x61, -0x18,0x60,0xbc,0x63,0x00,0x64,0xcd,0x81,0xbd,0xdb,0xfd,0x02,0x00,0x60,0x64,0x65, -0x17,0x60,0xe6,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4,0xd4,0x80,0xa2,0xdb,0x09,0x04, -0x17,0x60,0xe4,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb,0x17,0x60,0xe8,0x62,0x01,0x64, -0xa2,0xdb,0x66,0x60,0x28,0x62,0xa2,0xd3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x04,0x07, -0x5b,0x60,0x58,0x4e,0xc4,0x78,0xff,0xff,0x5c,0x60,0x1f,0x78,0xff,0xff,0x61,0xf1, -0x28,0x60,0xa2,0x62,0xa2,0xd9,0x3c,0x60,0xca,0x62,0x28,0x60,0x9e,0x64,0xa2,0xdb, -0x02,0x64,0x4a,0xdb,0xff,0xff,0x1d,0xff,0x1e,0x60,0xd6,0x62,0x00,0x60,0xfe,0x64, -0xa2,0xdb,0x5e,0x60,0x6b,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x60,0xf3, -0x65,0xf3,0x60,0x45,0x60,0x47,0xb4,0x84,0x60,0x45,0x68,0x60,0xcc,0x62,0x10,0x60, -0x00,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x00,0x60,0x7a,0x66, -0x00,0x64,0x61,0xfb,0x01,0xf2,0xff,0xff,0x00,0xa0,0xff,0xff,0x1e,0x03,0x1e,0x60, -0x92,0x64,0xa0,0xd3,0x03,0xf0,0xff,0xff,0xd0,0x84,0x00,0xfa,0x01,0xf2,0x60,0x45, -0xd4,0x80,0xff,0xff,0x05,0x06,0xd4,0x84,0x01,0xfa,0xfe,0xa0,0xff,0xff,0x0d,0x05, -0x00,0x64,0x01,0xfa,0x02,0xfa,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x80,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x62,0xf1,0x17,0x60,0x06,0x64, -0xa0,0xd3,0xff,0xff,0xd0,0x80,0x60,0x45,0x69,0x03,0x16,0x60,0x42,0x64,0xa0,0xd3, -0xff,0xff,0xff,0xa0,0xfc,0xa0,0x06,0x03,0x62,0x02,0x86,0xf3,0xff,0xff,0x00,0xa0, -0xff,0xff,0x5d,0x03,0x65,0x44,0x60,0x45,0x68,0x60,0xcc,0x62,0x60,0x60,0x00,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x19,0xf2,0xff,0xff,0xdc,0x84, -0x19,0xfa,0x65,0x44,0xff,0x22,0x4b,0x00,0x12,0xfa,0xcc,0x84,0xfc,0xa0,0x60,0x41, -0x01,0x06,0x04,0x64,0xe0,0x84,0x60,0x45,0xe0,0x84,0xe0,0x84,0xc4,0x85,0x18,0x60, -0xf8,0x64,0xc4,0x83,0xbd,0xd3,0xff,0xff,0x14,0xfa,0xbd,0xd3,0xff,0xff,0x15,0xfa, -0xbd,0xd3,0xff,0xff,0x16,0xfa,0xbd,0xd3,0xff,0xff,0x17,0xfa,0xbd,0xd3,0xff,0xff, -0x18,0xfa,0x16,0x60,0x42,0x64,0xa0,0xd3,0xff,0xff,0xfc,0xa0,0x61,0x44,0x05,0x02, -0xfd,0xa0,0x14,0xf2,0x02,0x05,0xfd,0xa4,0x14,0xfa,0xcb,0xf3,0xff,0xff,0xfc,0xa0, -0x62,0xf3,0x08,0x02,0xff,0xff,0xff,0x26,0x05,0x00,0x01,0x64,0x63,0x60,0x58,0x4e, -0x03,0x78,0xff,0xff,0x62,0xf3,0xff,0xff,0x60,0x40,0x00,0x3a,0x2f,0x00,0x15,0xf2, -0x01,0xfa,0x61,0xfb,0x02,0x64,0x02,0xfa,0x08,0x64,0x60,0xfb,0x01,0x64,0x13,0xfa, -0x05,0xfa,0x04,0xfa,0x10,0x60,0x00,0x64,0x66,0xfb,0x20,0x00,0x24,0x00,0x65,0xf3, -0xff,0xff,0x02,0xb0,0xff,0xff,0x04,0x02,0x63,0x60,0x58,0x4e,0x7d,0x78,0xff,0xff, -0xcb,0xf3,0xff,0xff,0xfc,0xa0,0xff,0xff,0x05,0x02,0x00,0x64,0x63,0x60,0x58,0x4e, -0x03,0x78,0xff,0xff,0x80,0x64,0x60,0xfb,0x32,0x64,0x61,0xfb,0x17,0x60,0x06,0x63, -0x00,0x64,0x66,0xfb,0x01,0xfa,0x02,0xfa,0xff,0xff,0xa3,0xdb,0x17,0x60,0x06,0x64, -0xa0,0xd3,0x62,0xfb,0x05,0x00,0x00,0xa0,0xff,0xff,0x02,0x02,0x32,0x64,0x61,0xfb, -0xff,0xff,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60,0x01,0x64,0xa0,0x84,0xa2,0xdb, -0x09,0xf8,0x16,0x60,0x42,0x62,0xa2,0xd3,0xff,0xff,0xfc,0xa0,0x62,0xf3,0x03,0x03, -0x60,0x60,0xa2,0x78,0xff,0xff,0x00,0xa0,0xff,0xff,0x6c,0x03,0x64,0x44,0x80,0x2a, -0x1d,0x00,0x20,0xf2,0xff,0xff,0xdc,0x84,0x20,0xfa,0x01,0x60,0x5e,0x64,0x20,0x40, -0x40,0x2a,0x08,0x00,0x18,0x60,0xf6,0x62,0xa2,0xd3,0xff,0xff,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0xe0,0x84,0x01,0xfa,0x01,0x64,0x02,0xfa,0x65,0xf3,0xff,0xff,0xff,0xff, -0xff,0x26,0x04,0x00,0x63,0x60,0x58,0x4e,0x7d,0x78,0xff,0xff,0x6e,0xf3,0x6f,0xf1, -0xff,0xff,0x01,0xb4,0xb0,0x84,0xff,0xff,0x19,0x03,0x60,0xf3,0xff,0xff,0x08,0xbc, -0x60,0xfb,0x62,0x60,0x58,0x4e,0xdc,0x78,0xff,0xff,0x00,0xfa,0x60,0x45,0x68,0x60, -0xcc,0x62,0x90,0x60,0x21,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb, -0x01,0xf0,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x06,0x01,0xfa,0x09,0xf2,0x06,0xf2, -0x60,0x40,0x08,0x2a,0x28,0x00,0x60,0x40,0xff,0x22,0x02,0x00,0xcc,0x84,0x06,0xfa, -0x00,0xa0,0xff,0xff,0x13,0x02,0x05,0xf2,0x14,0xf0,0x03,0xa4,0xd0,0x80,0xff,0xff, -0x01,0x06,0x64,0x44,0x05,0xfa,0x07,0xf2,0xff,0xff,0x60,0x40,0xff,0x22,0x02,0x00, -0xcc,0x84,0x07,0xfa,0x00,0xa0,0x01,0x64,0x01,0x02,0x05,0xfa,0x86,0xf3,0x01,0xf0, -0x00,0xfa,0xd0,0x80,0xff,0xff,0x01,0x06,0x01,0xfa,0x60,0xf3,0xff,0xff,0x08,0xbc, -0x60,0xfb,0x01,0x00,0x56,0x00,0x09,0xf2,0x60,0xf1,0x60,0x40,0x04,0x2a,0x2c,0x00, -0x64,0x40,0x20,0x2a,0x19,0x00,0x01,0x64,0x05,0xfa,0x04,0xfa,0x62,0x60,0x58,0x4e, -0xdc,0x78,0xff,0xff,0x00,0xfa,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x22,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x01,0xf0,0xff,0xff,0xd0,0x80, -0xff,0xff,0x0d,0x06,0x01,0xfa,0x0b,0x00,0x64,0x40,0x10,0x2a,0x08,0x00,0x14,0x64, -0x00,0xfa,0x61,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x06,0x61,0xfb,0x60,0xf3, -0xff,0xff,0xcf,0xb4,0x08,0xbc,0x60,0xfb,0x09,0xf2,0x60,0xf1,0x60,0x40,0x10,0x2a, -0x0b,0x00,0x64,0x44,0xbf,0xb4,0x08,0xbc,0x60,0xfb,0x14,0x64,0x61,0xf1,0x00,0xfa, -0xd0,0x80,0xff,0xff,0x01,0x06,0x61,0xfb,0x09,0xf2,0x18,0xf0,0x60,0x40,0x20,0x2a, -0x04,0x00,0x01,0x63,0x05,0xfc,0x04,0xfc,0x06,0xf8,0x60,0x40,0x40,0x2a,0x01,0x00, -0x06,0xf8,0x61,0xf3,0x65,0xf1,0x00,0xa0,0x05,0x64,0x03,0x02,0x64,0x40,0x80,0x26, -0x61,0xfb,0x01,0xf2,0x61,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x06,0x61,0xfb, -0x09,0xf0,0x61,0xf3,0x64,0x40,0x02,0x26,0x03,0x00,0x00,0xa0,0xff,0xff,0x7b,0x02, -0x62,0xf3,0xff,0xff,0x00,0xa0,0x60,0xf3,0x76,0x03,0x00,0xa0,0xcb,0xf3,0x5d,0x02, -0xfd,0xa0,0x04,0xf2,0x48,0x02,0x60,0x40,0xff,0x22,0x02,0x00,0xcc,0x84,0x04,0xfa, -0x60,0x40,0x00,0x36,0x0b,0x00,0x71,0xf3,0xff,0xff,0xfb,0xa0,0x3c,0x60,0x28,0x62, -0x05,0x05,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x12,0x03,0x05,0xf2,0x65,0xf1, -0x04,0xfa,0x64,0x40,0xff,0x26,0x04,0x00,0x63,0x60,0x58,0x4e,0x7d,0x78,0xff,0xff, -0x60,0xf3,0x86,0xf1,0x08,0xbc,0x60,0xfb,0x05,0x64,0xc0,0x84,0x00,0xfa,0x44,0x00, -0xa4,0xf3,0xff,0xff,0x60,0x41,0x80,0xf3,0xff,0xff,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x85,0x73,0x44,0xc4,0x84,0x61,0x45,0xd4,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84, -0xe8,0x84,0x60,0x45,0x01,0x60,0xf4,0x64,0xd4,0x80,0x65,0x44,0x05,0x05,0x23,0xf2, -0xff,0xff,0xdc,0x84,0x23,0xfa,0x32,0x64,0xfa,0xa0,0xff,0xff,0x01,0x05,0x06,0x64, -0xfb,0xa4,0x00,0xfa,0x21,0x00,0x61,0xf3,0xff,0xff,0x00,0xa0,0x65,0xf3,0x1c,0x02, -0xfd,0xa0,0xff,0xff,0x04,0x02,0x63,0x60,0x58,0x4e,0xd5,0x78,0xff,0xff,0x32,0x64, -0x00,0xfa,0x01,0x64,0x05,0xfa,0x04,0xfa,0x0f,0x00,0x61,0xf3,0xff,0xff,0x00,0xa0, -0x00,0x64,0x0a,0x02,0x60,0xfb,0x63,0x60,0x58,0x4e,0xd5,0x78,0xff,0xff,0x62,0x60, -0x58,0x4e,0xe8,0x78,0xff,0xff,0x00,0xfa,0x00,0xf2,0x61,0xf1,0xff,0xff,0xd0,0x80, -0xff,0xff,0x01,0x06,0x61,0xfb,0x62,0x60,0xc8,0x78,0xff,0xff,0x62,0xf3,0xff,0xff, -0x00,0xa0,0xff,0xff,0x03,0x02,0x61,0x60,0xab,0x78,0xff,0xff,0x64,0x44,0x80,0x2a, -0x1d,0x00,0x20,0xf2,0xff,0xff,0xdc,0x84,0x20,0xfa,0x01,0x60,0x5e,0x64,0x20,0x40, -0x40,0x2a,0x08,0x00,0x18,0x60,0xf6,0x62,0xa2,0xd3,0xff,0xff,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0xe0,0x84,0x01,0xfa,0x01,0x64,0x02,0xfa,0x65,0xf3,0xff,0xff,0xff,0xff, -0xff,0x26,0x04,0x00,0x63,0x60,0x58,0x4e,0x7d,0x78,0xff,0xff,0x09,0xf2,0xff,0xff, -0xff,0xff,0x04,0x2a,0x62,0x00,0x1c,0xf2,0xff,0xff,0xdc,0x84,0x1c,0xfa,0x00,0x64, -0x00,0xfa,0x01,0x64,0x08,0xfa,0x06,0xf2,0xff,0xff,0xff,0xff,0xff,0x22,0x03,0x00, -0xcc,0x84,0x06,0xfa,0x0b,0x02,0x00,0xa0,0xff,0xff,0x07,0x02,0x05,0xf2,0x14,0xf0, -0x03,0xa4,0xd0,0x80,0xff,0xff,0x01,0x06,0x64,0x44,0x05,0xfa,0x60,0xf3,0xff,0xff, -0x60,0x40,0x20,0x2a,0x22,0x00,0x01,0x60,0x2c,0x64,0x00,0xfa,0x5b,0x60,0x28,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x13,0xf2,0xff,0xff,0x05,0xfa,0x04,0xfa,0x00,0x64,0x63,0x60, -0x58,0x4e,0x03,0x78,0xff,0xff,0x00,0xf2,0x01,0xf0,0xff,0xff,0xd0,0x80,0xff,0xff, -0x18,0x06,0x01,0xfa,0x04,0x64,0x02,0xfa,0x14,0x00,0x60,0x40,0x10,0x2a,0x11,0x00, -0x5b,0x60,0x2c,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82, -0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x32,0x64,0x00,0xfa,0xff,0xff,0x63,0xf3, -0x64,0xfb,0x60,0xf3,0x61,0xf1,0xcf,0xb4,0x60,0xfb,0x00,0xf2,0xff,0xff,0xd0,0x80, -0xff,0xff,0x01,0x06,0x61,0xfb,0x00,0x64,0x0a,0xfa,0x09,0xf2,0xff,0xff,0xff,0xff, -0x10,0x2a,0x12,0x00,0x1d,0xf2,0xff,0xff,0xdc,0x84,0x1d,0xfa,0x60,0xf3,0x32,0x65, -0x60,0x40,0x40,0x2a,0x05,0x65,0xbf,0xb4,0x60,0xfb,0x65,0x44,0x61,0xf1,0x00,0xfa, -0xd0,0x80,0xff,0xff,0x01,0x06,0x61,0xfb,0x09,0xf2,0xff,0xff,0xff,0xff,0x20,0x2a, -0x38,0x00,0x1a,0xf2,0xff,0xff,0xdc,0x84,0x1a,0xfa,0x5d,0xf3,0xa7,0xf1,0x60,0x40, -0xff,0x22,0x14,0x7c,0x64,0x44,0x60,0xf1,0x00,0xfa,0x64,0x40,0x01,0x2a,0x09,0x00, -0x17,0xf2,0x13,0xf0,0x00,0xfa,0xff,0xff,0x05,0xf8,0x04,0xf8,0x18,0xf0,0xff,0xff, -0x06,0xf8,0x60,0xf1,0xff,0xff,0x64,0x40,0x04,0x2a,0x09,0x00,0x17,0xf2,0x64,0x40, -0x01,0x2a,0x05,0x64,0x00,0xfa,0x60,0xf3,0xff,0xff,0xfe,0xb4,0x60,0xfb,0x60,0xf3, -0xff,0xff,0x08,0xbc,0xf9,0xb4,0x60,0xfb,0x00,0xf2,0x01,0xf0,0xff,0xff,0xd0,0x80, -0xff,0xff,0x01,0x06,0x01,0xfa,0x61,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x06, -0x61,0xfb,0x09,0xf2,0xff,0xff,0xff,0xff,0x40,0x22,0x16,0x00,0x1b,0xf2,0xff,0xff, -0xdc,0x84,0x1b,0xfa,0x18,0xf2,0xff,0xff,0x06,0xfa,0x02,0xf2,0xff,0xff,0xfc,0xa0, -0x00,0x64,0x03,0x02,0x01,0xfa,0x02,0xfa,0xff,0xff,0x16,0xf2,0x01,0xf0,0x00,0xfa, -0xd0,0x80,0xff,0xff,0x01,0x06,0x01,0xfa,0x61,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff, -0x05,0x02,0x65,0xf1,0x05,0x64,0x64,0x40,0x80,0x26,0x61,0xfb,0x04,0x00,0x60,0xf3, -0xff,0xff,0x80,0xb4,0x60,0xfb,0x60,0xf3,0x65,0xf3,0x60,0x45,0x60,0x47,0xb4,0x84, -0x01,0xf2,0x61,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x01,0x06,0x61,0xfb,0x09,0xf2, -0x61,0xf1,0x02,0xb0,0x00,0x64,0x06,0x02,0xd0,0x80,0xff,0xff,0x03,0x03,0x62,0x60, -0xc8,0x78,0xff,0xff,0x62,0xf3,0x60,0xf3,0x00,0xa0,0xff,0xff,0x03,0x02,0x62,0x60, -0xc6,0x78,0xff,0xff,0x60,0x40,0xff,0x26,0x6d,0x00,0xcb,0xf3,0xff,0xff,0xfc,0xa0, -0x64,0xf3,0x67,0x02,0x00,0xb8,0xcc,0x84,0x16,0x03,0x64,0xfb,0x60,0x45,0x68,0x60, -0xcc,0x62,0x80,0x60,0x40,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb, -0x67,0x60,0x84,0x64,0xa0,0xd3,0x07,0x02,0x00,0xa0,0xff,0xff,0x04,0x03,0x67,0x60, -0x8a,0x62,0x01,0x64,0xa2,0xdb,0x04,0xf2,0xff,0xff,0x00,0xb8,0xcc,0x84,0x01,0x03, -0x04,0xfa,0x00,0x65,0x64,0xf3,0x63,0xf3,0x00,0xa0,0xff,0xff,0x0d,0x02,0x64,0xfb, -0x60,0x45,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x05,0x64,0xa2,0xdb,0x68,0x60, -0xce,0x62,0x65,0x44,0xa2,0xdb,0x01,0x65,0x04,0xf2,0x05,0xf2,0x00,0xa0,0xff,0xff, -0x02,0x02,0x04,0xfa,0x01,0x65,0x65,0x40,0x00,0x36,0x2d,0x00,0x60,0xf3,0xff,0xff, -0x08,0xbc,0x60,0xfb,0x00,0x64,0x08,0xfa,0x0a,0xf2,0x15,0xf0,0x60,0x40,0x01,0x26, -0x0d,0x00,0x66,0x60,0x2a,0x62,0xa2,0xd3,0x37,0x7c,0xfe,0xa0,0xff,0xff,0x06,0x05, -0x0c,0xf2,0x25,0x7c,0xfe,0xa0,0xff,0xff,0x01,0x05,0x15,0x7c,0x00,0xf8,0x65,0xf3, -0xff,0xff,0xff,0xff,0xff,0x26,0x04,0x00,0x63,0x60,0x58,0x4e,0x7d,0x78,0xff,0xff, -0x18,0x60,0xc8,0x62,0xa2,0xd3,0x10,0x7c,0x0b,0xfa,0x0d,0xf8,0x62,0x60,0xbe,0x78, -0xff,0xff,0x19,0x00,0x2e,0x00,0x80,0xf3,0xff,0xff,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0x73,0x45,0xc4,0x84,0x60,0x53,0x62,0x60,0x58,0x4e,0xe8,0x78,0xff,0xff, -0x00,0xfa,0xe1,0xf1,0x67,0x60,0x7e,0x65,0x05,0x64,0x64,0x40,0x00,0x3a,0xa5,0xdb, -0x62,0x60,0xbe,0x78,0xff,0xff,0x61,0xf3,0xff,0xff,0x00,0xa0,0x32,0x64,0x0a,0x02, -0x61,0xfb,0x65,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x04,0x02,0x63,0x60,0x58,0x4e, -0xd5,0x78,0xff,0xff,0x13,0xf2,0xff,0xff,0x05,0xfa,0x04,0xfa,0x01,0x64,0x0a,0xfa, -0x51,0x00,0x61,0xf3,0xff,0xff,0x00,0xa0,0x00,0x64,0x4c,0x02,0x60,0xfb,0x66,0xf3, -0xff,0xff,0x00,0xa0,0x01,0x64,0x04,0x02,0x63,0x60,0x58,0x4e,0x03,0x78,0xff,0xff, -0x63,0x60,0x58,0x4e,0xd5,0x78,0xff,0xff,0xcb,0xf3,0xff,0xff,0xfc,0xa0,0xff,0xff, -0x26,0x02,0x73,0x44,0x80,0xf3,0xff,0xff,0xe0,0x84,0xe0,0x84,0xe0,0x84,0x60,0x8c, -0xa4,0xf3,0xff,0xff,0x60,0x41,0x73,0x44,0x61,0x45,0xd4,0x80,0xff,0xff,0x03,0x0d, -0x2c,0x45,0xc4,0x84,0xf9,0x00,0x60,0x53,0x08,0xf2,0xff,0xff,0x00,0xa0,0xff,0xff, -0x08,0x02,0x13,0xf2,0xff,0xff,0x05,0xfa,0x04,0xfa,0x24,0xf2,0xff,0xff,0xdc,0x84, -0x24,0xfa,0x62,0x60,0x58,0x4e,0xe8,0x78,0xff,0xff,0x00,0xfa,0x08,0x00,0x32,0x64, -0x00,0xfa,0x13,0xf2,0xff,0xff,0x05,0xfa,0x04,0xfa,0x01,0x64,0x0a,0xfa,0x65,0xf3, -0xff,0xff,0x00,0xa0,0xff,0xff,0x06,0x03,0x00,0xf2,0x14,0x65,0xd4,0x80,0x02,0x06, -0x65,0x44,0x00,0xfa,0x00,0xf2,0x61,0xf1,0xff,0xff,0xd0,0x80,0xff,0xff,0x04,0x06, -0x61,0xfb,0x02,0x00,0x32,0x64,0x61,0xfb,0x1e,0x60,0x92,0x64,0xa0,0xd3,0x03,0xfa, -0xff,0xff,0x61,0xf3,0x60,0x45,0x60,0x45,0x68,0x60,0xcc,0x62,0x50,0x60,0x00,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x5e,0x60,0x53,0x78,0xff,0xff, -0xa4,0xf1,0x73,0x44,0x64,0x45,0x86,0xf1,0xd4,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84, -0xe8,0x84,0xc0,0x84,0x2e,0x58,0xff,0xff,0xa4,0xf3,0xff,0xff,0x60,0x45,0x73,0x44, -0xd4,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0xe8,0x84,0x60,0x45,0x01,0x60,0xf4,0x64, -0xd4,0x80,0x65,0x44,0x05,0x05,0x23,0xf2,0xff,0xff,0xdc,0x84,0x23,0xfa,0x32,0x64, -0xfa,0xa0,0xff,0xff,0x01,0x05,0x06,0x64,0xfb,0xa4,0x2e,0x58,0xff,0xff,0x60,0x45, -0x68,0x60,0xcc,0x62,0x20,0x60,0x00,0x64,0xb4,0x84,0xa2,0xdb,0x65,0x44,0x2e,0x43, -0x11,0xfc,0x10,0x60,0x00,0x65,0x60,0x40,0xff,0x22,0x00,0x65,0x65,0x44,0x66,0xfb, -0x21,0xf2,0xff,0xff,0xdc,0x84,0x21,0xfa,0x7b,0xf5,0xff,0xff,0x81,0xf1,0x2b,0xf8, -0x31,0xf8,0xff,0xff,0x82,0xf1,0x2c,0xf8,0x32,0xf8,0xff,0xff,0x83,0xf1,0x2d,0xf8, -0x33,0xf8,0xff,0xff,0xbd,0xf1,0x2e,0xf8,0xbe,0xf1,0xff,0xff,0x2f,0xf8,0xbf,0xf1, -0x30,0xf8,0xff,0xff,0x01,0x60,0x48,0x64,0xb4,0x84,0x29,0xfa,0x00,0x63,0x22,0xfc, -0x2a,0x60,0x20,0x64,0x0e,0xfa,0x3a,0x60,0x58,0x4e,0x14,0x78,0xff,0xff,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x28,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xc1,0xfe,0x1e,0x60,0xd6,0x62,0x00,0x60,0x01,0x64,0xa2,0xdb, -0x63,0x60,0x52,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xd4,0x62, -0xa2,0xd1,0xff,0x60,0xfe,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb, -0x7b,0xf5,0x22,0xf0,0x00,0x60,0x7a,0x66,0x64,0x44,0x0f,0x22,0x04,0x00,0x22,0xf2, -0xff,0xff,0xdc,0x84,0x22,0xfa,0x5a,0x60,0x3a,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x11,0xf0, -0x68,0x60,0xcc,0x62,0x20,0x60,0x02,0x64,0xa2,0xdb,0xff,0xff,0xf4,0xc6,0x7e,0x00, -0x00,0x10,0x44,0x4e,0x2e,0x58,0xff,0xff,0x1e,0xf2,0xff,0xff,0xdc,0x84,0x1e,0xfa, -0x68,0x60,0xcc,0x62,0x30,0x60,0x00,0x64,0xa2,0xdb,0x2e,0x43,0x11,0xfc,0x1e,0x60, -0xd4,0x62,0xa2,0xd1,0xbf,0x60,0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84, -0x5a,0xdb,0xff,0xff,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xd6,0x62,0x40,0x60, -0x00,0x64,0xa2,0xdb,0x63,0x60,0xa1,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x3c,0x60,0xa2,0x62,0x2a,0x44,0xa2,0xdb,0xca,0x82,0x08,0x64,0xa2,0xdb,0xff,0xff, -0x2d,0xff,0x1e,0x60,0xd6,0x62,0x20,0x60,0x00,0x64,0xa2,0xdb,0x63,0x60,0xb5,0x64, -0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x9f,0x60, -0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0xff,0xff,0xbe,0xfe, -0x1e,0x60,0xa8,0x62,0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe, -0x00,0x60,0x7a,0x66,0x68,0x60,0xcc,0x62,0x30,0x60,0x01,0x64,0xa2,0xdb,0x11,0xf2, -0xff,0xff,0x40,0x4e,0x2e,0x58,0xff,0xff,0x1f,0xf2,0xff,0xff,0xdc,0x84,0x1f,0xfa, -0x68,0x60,0xcc,0x62,0x40,0x60,0x00,0x64,0xa2,0xdb,0x2e,0x43,0x11,0xfc,0x1e,0x60, -0xd4,0x62,0xa2,0xd1,0xbf,0x60,0xff,0x61,0xa1,0x84,0x5a,0xd1,0x4a,0xdb,0xa1,0x84, -0x5a,0xdb,0xff,0xff,0xde,0xfe,0xff,0xff,0x0b,0x04,0x1e,0x60,0xd6,0x62,0x40,0x60, -0x00,0x64,0xa2,0xdb,0x63,0x60,0xf9,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58,0xff,0xff, -0x65,0xf3,0xff,0xff,0xff,0xff,0x80,0x26,0x14,0x00,0x3c,0x60,0xa2,0x62,0x2a,0x44, -0xa2,0xdb,0xca,0x82,0x02,0x64,0xa2,0xdb,0xff,0xff,0x2d,0xff,0x1e,0x60,0xd6,0x62, -0x20,0x60,0x00,0x64,0xa2,0xdb,0x64,0x60,0x13,0x64,0x5a,0xdb,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0xff,0xff,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x9f,0x60,0xff,0x61,0xa1,0x84, -0x5a,0xd1,0x4a,0xdb,0xa1,0x84,0x5a,0xdb,0xff,0xff,0xbe,0xfe,0x1e,0x60,0xa8,0x62, -0xa2,0xd1,0x40,0x60,0x00,0x64,0xb0,0x84,0xa2,0xdb,0xcf,0xfe,0x5b,0x60,0x24,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x00,0x60,0x7a,0x66,0x68,0x60,0xcc,0x62,0x40,0x60,0x01,0x64, -0xa2,0xdb,0x11,0xf2,0xff,0xff,0x40,0x4e,0x2e,0x58,0xff,0xff,0x1e,0x60,0xd4,0x62, -0xa2,0xd1,0x00,0x60,0x02,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2f,0x58, -0xff,0xff,0x3c,0x60,0xb2,0x62,0x28,0x60,0x9e,0x64,0xa2,0xdb,0x03,0x64,0x4a,0xdb, -0xff,0xff,0x1d,0xff,0x1e,0x60,0xd4,0x62,0x00,0x64,0xa2,0xdb,0x5a,0xdb,0x2f,0x58, -0xff,0xff,0x62,0xf3,0x26,0x46,0x60,0x40,0xff,0x22,0x37,0x00,0x60,0xf3,0x0f,0xf2, -0x60,0x43,0x29,0xf0,0x60,0x40,0x10,0x2a,0x15,0x00,0x63,0x44,0x60,0x43,0x68,0x60, -0xcc,0x62,0x00,0x60,0x40,0x64,0xa2,0xdb,0x68,0x60,0xce,0x62,0x63,0x44,0xa2,0xdb, -0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60,0x40,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff, -0xcf,0xfe,0x1b,0x00,0x64,0x40,0x20,0x2b,0x02,0x00,0x40,0xbb,0x01,0x00,0xbf,0xb3, -0x60,0xfd,0x63,0x44,0x60,0x43,0x68,0x60,0xcc,0x62,0x00,0x60,0x10,0x64,0xa2,0xdb, -0x68,0x60,0xce,0x62,0x63,0x44,0xa2,0xdb,0x1e,0x60,0xd4,0x62,0xa2,0xd1,0x00,0x60, -0x10,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x26,0x46,0x2f,0x58,0xff,0xff, -0x22,0x02,0x2e,0xf2,0xff,0xff,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84, -0xe1,0x81,0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81, -0xf0,0x84,0xe1,0x81,0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84, -0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0x65,0x60,0x58,0x4e,0x92,0x78,0xff,0xff, -0x65,0x60,0x8f,0x78,0xff,0xff,0x65,0x60,0x81,0x78,0xff,0xff,0xcb,0xf3,0xff,0xff, -0xfc,0xa0,0xfd,0xa0,0xd5,0x02,0x00,0x64,0x40,0x48,0x26,0x46,0x38,0xf2,0x00,0xf4, -0x10,0x63,0xf4,0xa4,0x60,0x41,0x00,0x65,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac, -0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x40,0x4c, -0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00, -0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x60,0x45,0x2c,0x44,0x04,0xa8,0x05,0xa8,0x06,0x03, -0xc9,0x81,0x2e,0x03,0xd5,0x81,0xc7,0x83,0xce,0x06,0xde,0x00,0x41,0x4c,0x67,0x60, -0x80,0x61,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47, -0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x59,0xdb,0x63,0x44,0x01,0x22,0x05,0x00, -0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f, -0x59,0xdb,0x58,0x60,0x58,0x4e,0xb5,0x78,0xff,0xff,0x65,0x44,0x59,0xdb,0x58,0x60, -0x58,0x4e,0xb5,0x78,0xff,0xff,0x65,0x44,0x59,0xdb,0x2c,0x41,0xf8,0xa1,0xb4,0x00, -0x65,0x41,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47, -0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0x40,0x4c,0x64,0xfb,0x63,0x44,0x01,0x22, -0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3, -0x00,0x7f,0x63,0xfb,0x62,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff,0x49,0x03,0x63,0x44, -0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2,0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2, -0x01,0xa3,0x00,0x7f,0x40,0x4d,0x2c,0x44,0x00,0xb8,0xff,0xff,0x05,0x02,0x2d,0x44, -0x01,0x2a,0x02,0x00,0x10,0x65,0x45,0x48,0x66,0xf3,0xff,0xff,0x00,0xa0,0xff,0xff, -0x2f,0x03,0x2d,0x44,0xfe,0xb5,0x3c,0x60,0xd2,0x64,0xa0,0xd3,0xff,0xff,0x00,0x7f, -0xd4,0x84,0x04,0xa4,0x19,0x04,0x60,0x45,0xd5,0x80,0xfc,0xa5,0x15,0x04,0x3c,0x60, -0xd0,0x64,0xa0,0xd1,0xc7,0x83,0x63,0x44,0x01,0x22,0x05,0x00,0x01,0xac,0xa0,0xd2, -0x01,0xa3,0x60,0x47,0x02,0x00,0xa0,0xd2,0x01,0xa3,0x00,0x7f,0xa0,0x80,0xff,0xff, -0x03,0x03,0x28,0x44,0x20,0xbc,0x40,0x48,0x28,0x44,0xff,0x22,0x09,0x00,0x60,0xf1, -0xff,0xff,0xb0,0x84,0x60,0xfb,0x60,0x45,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb, -0x68,0x60,0xcc,0x62,0x00,0x60,0x04,0x64,0xa2,0xdb,0x1e,0x60,0xd4,0x62,0xa2,0xd1, -0x00,0x60,0x04,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x26,0x46,0x2f,0x58, -0xff,0xff,0x0e,0x48,0x65,0x60,0x58,0x4e,0xfc,0x78,0xff,0xff,0x10,0x03,0x29,0xf2, -0xa3,0xd1,0x60,0x40,0x10,0x2b,0x03,0x00,0x64,0x44,0x02,0xbc,0x02,0x00,0x64,0x44, -0xfd,0xb4,0xa3,0xdb,0x0a,0xa3,0x3c,0x64,0xa3,0xdb,0xf6,0xa3,0x50,0x00,0x2c,0x43, -0xa3,0xd3,0xff,0xff,0x60,0x40,0x01,0x26,0x37,0x00,0x43,0x4c,0x29,0xf0,0x01,0x64, -0x64,0x40,0x10,0x27,0x03,0x64,0xbd,0xdb,0x2e,0xf2,0xff,0xff,0xbd,0xdb,0x2f,0xf2, -0xbd,0xdb,0xff,0xff,0x30,0xf2,0xbd,0xdb,0x01,0x60,0x92,0x64,0xa0,0xd3,0xff,0xff, -0x60,0x40,0x08,0x2a,0x02,0x00,0x08,0x7f,0x0a,0x00,0x04,0x2a,0x02,0x00,0x04,0x7f, -0x06,0x00,0x02,0x2a,0x02,0x00,0x02,0x7f,0x02,0x00,0x01,0x7f,0x01,0x7e,0x60,0x47, -0xbd,0xdb,0x3c,0x64,0xbd,0xdb,0x29,0xf0,0x34,0xf2,0x64,0x40,0x08,0x27,0xcc,0x84, -0xbd,0xdb,0x00,0x64,0xbd,0xdb,0x2c,0x43,0x1a,0x00,0x61,0x44,0xdc,0x84,0xd0,0x80, -0xff,0xff,0xcb,0x06,0x72,0xfb,0xc9,0x00,0x72,0xf1,0x38,0x60,0xe2,0x63,0x00,0x61, -0xa3,0xd3,0xff,0xff,0xff,0xff,0x01,0x2a,0xf0,0x00,0x10,0xa3,0x61,0x44,0xf1,0xa0, -0xdd,0x81,0xf6,0x04,0x00,0x63,0x3d,0x60,0x4a,0x62,0x01,0x64,0xa2,0xdb,0x08,0x4e, -0x00,0xbb,0x2e,0x58,0xff,0xff,0x28,0x60,0xe2,0x65,0x00,0x7f,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0xe0,0x84,0x44,0xd3,0x62,0x43,0x43,0x4c,0x60,0x40,0x01,0x2a,0x10,0x00, -0x02,0xa3,0x2e,0xf2,0x50,0xfe,0xbd,0xd1,0x2f,0xf2,0xd0,0x80,0xbd,0xd1,0x30,0xf2, -0xd0,0x80,0xbd,0xd1,0xff,0xff,0xd0,0x80,0xff,0xff,0x02,0x02,0xf8,0xa3,0x1e,0x00, -0x72,0xf1,0x38,0x60,0xe2,0x63,0x64,0x41,0xff,0x22,0x17,0x00,0xbd,0xd1,0x2e,0xf2, -0x50,0xfe,0x64,0x40,0x01,0x26,0x04,0x00,0xcd,0x81,0x0e,0xa3,0xf7,0x02,0x0d,0x00, -0xbd,0xd1,0x2f,0xf2,0xd0,0x80,0xbd,0xd1,0x30,0xf2,0xd0,0x80,0xbd,0xd1,0xff,0xff, -0xd0,0x80,0xcd,0x81,0xe3,0x01,0x08,0xa3,0xe9,0x02,0x00,0x63,0x00,0xbb,0x2e,0x58, -0xff,0xff,0xff,0x60,0xff,0x64,0x2b,0xfa,0x2c,0xfa,0x2d,0xfa,0xff,0xff,0x47,0xf3, -0xff,0xff,0xe8,0x84,0xe8,0x84,0x01,0x00,0x00,0x64,0x1c,0xfa,0x46,0x4d,0xbd,0xf1, -0x2e,0xf8,0xbe,0xf1,0xff,0xff,0x2f,0xf8,0xbf,0xf1,0x30,0xf8,0xff,0xff,0x81,0xf1, -0x31,0xf8,0x82,0xf1,0xff,0xff,0x32,0xf8,0x83,0xf1,0x33,0xf8,0x3b,0x60,0x28,0x63, -0x80,0xf1,0x00,0x64,0x64,0x5e,0xbd,0xdb,0x64,0x47,0x00,0x7f,0xbd,0xdb,0x43,0xf3, -0x47,0xf1,0x01,0xb4,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xb0,0x84,0x02,0xbc, -0xbd,0xdb,0x00,0x64,0xbd,0xdb,0x00,0x64,0xbd,0xdb,0x59,0x60,0x20,0x62,0xa2,0xd3, -0xda,0x85,0xbd,0xdb,0x60,0x41,0x06,0xa4,0x8f,0xfb,0xa5,0xd1,0xda,0x85,0x64,0x44, -0x00,0x7f,0xcd,0x81,0xbd,0xdb,0x05,0x03,0x64,0x47,0x00,0x7f,0xcd,0x81,0xbd,0xdb, -0xf4,0x02,0x01,0x64,0xbd,0xdb,0x8f,0xf1,0x17,0x60,0xd2,0x62,0xa2,0xd3,0xda,0x85, -0xbd,0xdb,0x43,0x48,0x60,0x41,0x41,0x4c,0xc0,0x84,0x02,0xa4,0x8f,0xfb,0xa5,0xd1, -0xda,0x85,0x64,0x44,0x00,0x7f,0xcd,0x81,0xbd,0xdb,0x05,0x03,0x64,0x47,0x00,0x7f, -0xcd,0x81,0xbd,0xdb,0xf4,0x02,0x03,0x64,0xbd,0xdb,0x01,0x64,0xbd,0xdb,0x7f,0xf3, -0xbd,0xdb,0xff,0xff,0x8f,0xf3,0xff,0xff,0x03,0xa4,0x8f,0xfb,0x06,0x64,0xbd,0xdb, -0x02,0x64,0xbd,0xdb,0x86,0xf1,0x00,0x64,0x64,0x5e,0xbd,0xdb,0x64,0x47,0x00,0x7f, -0xbd,0xdb,0x8f,0xf3,0xff,0xff,0x04,0xa4,0x8f,0xfb,0x07,0x64,0xbd,0xdb,0x06,0x64, -0xbd,0xdb,0x17,0x60,0x82,0x62,0xa2,0xd1,0x00,0x64,0x64,0x5e,0xbd,0xdb,0x64,0x47, -0x00,0x7f,0xbd,0xdb,0x00,0x64,0xbd,0xdb,0x1f,0x60,0x54,0x62,0xa2,0xd3,0xbd,0xdb, -0x1f,0x60,0x56,0x62,0xa2,0xd3,0xbd,0xdb,0x00,0x64,0xbd,0xdb,0x8f,0xf3,0xff,0xff, -0x08,0xa4,0x8f,0xfb,0x00,0x64,0xa3,0xdb,0x17,0x60,0xdc,0x62,0xa2,0xd1,0x28,0x43, -0x2c,0x41,0xa3,0xd3,0xff,0xff,0x60,0x40,0x02,0x3a,0x04,0x00,0x64,0x40,0x01,0x2a, -0x14,0x00,0x11,0x00,0x04,0x3a,0x04,0x00,0x64,0x40,0x02,0x2a,0x0e,0x00,0x0b,0x00, -0x0b,0x3a,0x04,0x00,0x64,0x40,0x04,0x2a,0x08,0x00,0x05,0x00,0x16,0x3a,0x05,0x00, -0x64,0x40,0x08,0x2a,0x02,0x00,0x80,0xbc,0xa3,0xdb,0xcd,0x81,0xdb,0x83,0xe1,0x02, -0x8f,0xf3,0xff,0xff,0x60,0x41,0x08,0xa4,0x38,0xfa,0x00,0xf4,0x3b,0x60,0x28,0x63, -0x01,0xf2,0xff,0xff,0x7c,0x7e,0x01,0xfa,0x0c,0x65,0xbd,0xd3,0xbd,0xd1,0x60,0x47, -0xb0,0x87,0xa5,0xda,0xda,0x85,0xcd,0x81,0xcd,0x81,0x01,0x03,0xf6,0x02,0x2d,0x46, -0x2e,0x58,0xff,0xff,0x00,0xf4,0x07,0xf0,0x73,0xf3,0x64,0x40,0x02,0x2a,0x49,0x00, -0x02,0xbc,0x73,0xfb,0x60,0x45,0x26,0x46,0x2e,0xf2,0xff,0xff,0x60,0x47,0xbd,0xf3, -0x60,0x5c,0x60,0x47,0x2f,0xf2,0xd0,0x80,0x60,0x47,0xbe,0xf3,0x60,0x5c,0x60,0x47, -0x10,0x07,0x0b,0x04,0x30,0xf2,0xd0,0x80,0x60,0x47,0x60,0x5c,0xbf,0xf3,0x09,0x07, -0x04,0x04,0x60,0x47,0xd0,0x80,0xff,0xff,0x04,0x07,0xfe,0x64,0xa4,0x84,0x73,0xfb, -0xff,0xff,0x31,0xf2,0x32,0xf0,0x33,0xf0,0xb0,0x84,0xb0,0x84,0xff,0xff,0x21,0x03, -0x3b,0x60,0x28,0x63,0x31,0xf0,0xbd,0xd9,0x32,0xf0,0xff,0xff,0xbd,0xd9,0x33,0xf0, -0xbd,0xd9,0xff,0xff,0x00,0xf4,0x02,0xf0,0xbd,0xd9,0xff,0xff,0x03,0xf0,0xbd,0xd9, -0x04,0xf0,0xff,0xff,0xbd,0xd9,0x05,0xf0,0xbd,0xd9,0xff,0xff,0x06,0xf0,0xbd,0xd9, -0x07,0xf0,0xff,0xff,0xbd,0xd9,0x00,0x64,0x08,0xf0,0xa3,0xdb,0x64,0x47,0x60,0x45, -0x00,0x3b,0x62,0x00,0xbd,0xdb,0xdc,0x84,0xe8,0x81,0x10,0x64,0x58,0xd0,0xcd,0x81, -0xbd,0xd9,0xfc,0x02,0xd8,0x83,0x04,0x64,0x40,0x4d,0x09,0x61,0x65,0x40,0x01,0x2a, -0xbd,0xd0,0xff,0xff,0x64,0x44,0x00,0x7f,0x2d,0xda,0x5a,0x8d,0x64,0x47,0x00,0x7f, -0x2d,0xda,0xcd,0x81,0x5a,0x8d,0xf4,0x02,0x3b,0x60,0x5c,0x63,0x04,0x61,0x65,0x40, -0x01,0x26,0x02,0xa1,0xa1,0xd2,0xff,0xff,0x01,0xa8,0x59,0xd2,0x4b,0x02,0xfc,0xa0, -0xff,0xff,0x48,0x07,0xbd,0xdb,0x59,0xd0,0xcc,0x84,0xbd,0xd9,0xfc,0x02,0x00,0x64, -0xbd,0xdb,0x3b,0x60,0x6a,0x63,0x59,0xd2,0x59,0xd0,0x03,0xa8,0x7f,0xf3,0x3a,0x02, -0x59,0xd0,0xff,0xff,0xd0,0x80,0xbd,0xd9,0x35,0x02,0x59,0xd2,0x59,0xd0,0x06,0xa8, -0x59,0xd0,0x30,0x02,0x59,0xd2,0xff,0xff,0x60,0x47,0xb0,0x84,0xbd,0xdb,0x3b,0x60, -0x5e,0x63,0x00,0x61,0xa3,0xd3,0xff,0xff,0x60,0x40,0xff,0x22,0x16,0x00,0x80,0x2a, -0x11,0x00,0x7f,0xb4,0xa3,0xdb,0x60,0x40,0x02,0x3a,0x02,0x00,0x01,0xb9,0x0a,0x00, -0x04,0x3a,0x02,0x00,0x02,0xb9,0x06,0x00,0x0b,0x3a,0x02,0x00,0x04,0xb9,0x02,0x00, -0x16,0x36,0x08,0xb9,0x02,0xa3,0xe6,0x00,0x0d,0x00,0x3b,0x60,0x68,0x63,0x61,0x44, -0xa3,0xdb,0x3b,0x60,0x28,0x63,0x39,0x60,0xf0,0x64,0x23,0x61,0xbd,0xd1,0xcd,0x81, -0x58,0xd9,0xfc,0x02,0x26,0x46,0x2f,0x58,0xff,0xff,0xcb,0xf3,0x0f,0xf0,0xfd,0xa0, -0xff,0xff,0x07,0x02,0x64,0x40,0x60,0x26,0x04,0x00,0x68,0x60,0x58,0x4e,0xba,0x78, -0xff,0xff,0x2f,0x58,0xff,0xff,0xd5,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x4d,0x05, -0x16,0x60,0x42,0x62,0xa2,0xd3,0x6e,0xf1,0xfc,0xa0,0xff,0xff,0x46,0x02,0x64,0x40, -0x01,0x2a,0x43,0x00,0x68,0x60,0x58,0x4e,0x86,0x78,0xff,0xff,0x26,0x46,0x3d,0x02, -0x2e,0xf0,0x2b,0xf8,0x2f,0xf0,0xff,0xff,0x2c,0xf8,0x30,0xf0,0x2d,0xf8,0x66,0x60, -0x58,0x4e,0x45,0x78,0xff,0xff,0x26,0x46,0x00,0xf0,0x04,0x64,0x03,0xfa,0x04,0xf8, -0x00,0x64,0x0b,0xfa,0x0c,0xfa,0x0f,0xfa,0xff,0xff,0x85,0xf3,0x38,0xf0,0x50,0xbc, -0x29,0xfa,0x17,0xf8,0x0c,0x64,0x15,0xfa,0x20,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f, -0x13,0xfa,0x1c,0x64,0x21,0xfa,0x08,0x64,0x28,0xfa,0x00,0x63,0x22,0xfc,0x16,0xfc, -0x07,0xfc,0x01,0x64,0x19,0xfc,0x1c,0xfc,0x14,0xfa,0xff,0x67,0x0e,0xfa,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0e,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xc1,0xfe,0x00,0x66,0x46,0x46,0x2f,0x58,0xff,0xff,0xcb,0xf3, -0x0f,0xf0,0xfd,0xa0,0x20,0x64,0x47,0x02,0x64,0x40,0x60,0x26,0x10,0x64,0x60,0xf1, -0xff,0xff,0xb0,0x84,0x60,0xfb,0x60,0x45,0x68,0x60,0xcc,0x62,0x90,0x60,0x50,0x64, -0xa2,0xdb,0x68,0x60,0xce,0x62,0x65,0x44,0xa2,0xdb,0x1e,0x60,0xd4,0x62,0xa2,0xd1, -0x00,0x60,0x04,0x64,0xb0,0x84,0xa2,0xdb,0xff,0xff,0xcf,0xfe,0x2e,0xf2,0xff,0xff, -0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0xe1,0x81,0x5a,0xd2,0xf0,0x85, -0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0xe1,0x81,0x5a,0xd2, -0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0xe1,0x81, -0xf0,0x84,0x65,0x60,0x58,0x4e,0x92,0x78,0xff,0xff,0x29,0xf2,0xff,0xff,0x60,0x40, -0x10,0x2b,0x09,0x00,0x69,0x60,0x58,0x4e,0xdf,0x78,0xff,0xff,0x04,0x03,0x69,0x60, -0x58,0x4e,0xf9,0x78,0xff,0xff,0x2f,0x58,0xff,0xff,0x00,0xf4,0x04,0x63,0x06,0x00, -0x00,0xf4,0x07,0xf0,0x10,0x63,0x64,0x40,0x02,0x2a,0x27,0x00,0xbd,0xd2,0xff,0xff, -0x60,0x47,0x00,0x3a,0x22,0x00,0x60,0x41,0x00,0x36,0x1d,0x00,0x59,0x60,0x20,0x62, -0xa2,0xd3,0x61,0x45,0xd4,0x80,0xff,0xff,0x18,0x02,0xda,0x82,0x61,0x40,0xfe,0x22, -0x08,0x00,0x62,0x45,0xbd,0xd2,0xa5,0xd1,0xda,0x82,0xd0,0x80,0xc9,0x81,0xf6,0x03, -0x0c,0x00,0x61,0x40,0x00,0x36,0x07,0x00,0x62,0x45,0xa3,0xd2,0xa5,0xd1,0xff,0xff, -0x90,0x80,0xff,0x26,0x02,0x00,0x00,0x64,0x01,0x00,0x01,0x64,0x01,0xb4,0x2e,0x58, -0xff,0xff,0x2e,0xf0,0x2b,0xf8,0x2f,0xf0,0xff,0xff,0x2c,0xf8,0x30,0xf0,0x2d,0xf8, -0xff,0xff,0xbd,0xf1,0x2e,0xf8,0xff,0xff,0xbe,0xf1,0x2f,0xf8,0xbf,0xf1,0xff,0xff, -0x30,0xf8,0x81,0xf1,0x31,0xf8,0xff,0xff,0x82,0xf1,0x32,0xf8,0x83,0xf1,0xff,0xff, -0x33,0xf8,0x00,0xf0,0x04,0x64,0x03,0xfa,0x04,0xf8,0x00,0x64,0x0b,0xfa,0x0c,0xfa, -0x0f,0xfa,0xff,0xff,0x85,0xf3,0xff,0xff,0xb0,0xbc,0x29,0xfa,0x0c,0x64,0x15,0xfa, -0x20,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0x13,0xfa,0x1c,0x64,0x21,0xfa,0x08,0x64, -0x28,0xfa,0x00,0x63,0x22,0xfc,0x16,0xfc,0x07,0xfc,0x01,0x64,0x19,0xfc,0x1c,0xfc, -0x14,0xfa,0xff,0x67,0x0e,0xfa,0x38,0xf0,0x06,0x64,0x38,0xfa,0x17,0xfa,0x44,0x48, -0x00,0xf4,0x01,0xf2,0xff,0xff,0x7c,0x7e,0x01,0xfa,0x02,0xf2,0x00,0x63,0x00,0xa0, -0x04,0xfc,0x07,0x02,0x03,0xf2,0x00,0x63,0xff,0xa0,0xff,0xff,0x3b,0x03,0x0e,0x63, -0x39,0x00,0xff,0xa0,0x0d,0x63,0x36,0x02,0x43,0xf3,0xff,0xff,0x60,0x40,0x01,0x2a, -0x31,0x00,0x03,0xf2,0x0e,0x63,0xff,0xa0,0xff,0xff,0x1c,0x02,0x0a,0x63,0x80,0x60, -0x10,0x64,0xbd,0xda,0x00,0x60,0x3a,0x61,0x01,0x60,0x02,0x65,0x55,0x60,0xaa,0x64, -0xcd,0x81,0xbd,0xda,0xc4,0x84,0xfc,0x02,0x00,0xf4,0x04,0x63,0x06,0x61,0xcd,0x81, -0xbd,0xda,0xc4,0x84,0xfc,0x02,0x26,0x46,0x88,0x64,0x38,0xfa,0x17,0xfa,0x00,0xf4, -0x00,0x63,0x10,0x00,0xfd,0xa0,0xff,0xff,0x0d,0x02,0x0f,0x63,0x55,0x60,0xaa,0x65, -0x05,0xf2,0xff,0xff,0xd4,0x80,0x88,0x64,0x05,0x02,0x28,0x45,0xd4,0x80,0xff,0xff, -0x01,0x02,0x00,0x63,0x03,0xf2,0x04,0xfc,0xdc,0x84,0x03,0xfa,0x26,0x46,0x3c,0x60, -0x82,0x62,0x3c,0x60,0x2e,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0e,0x64,0x5a,0xdb, -0xff,0xff,0x2b,0xff,0xc1,0xfe,0x00,0x66,0x46,0x46,0x2e,0x58,0xff,0xff,0x1e,0x60, -0x92,0x62,0xa2,0xd1,0x59,0x60,0x76,0x64,0xa0,0xd3,0xfa,0x65,0xd0,0x80,0xff,0xff, -0x37,0x0d,0xc4,0x84,0xa2,0xdb,0x59,0x60,0x74,0x64,0xa0,0xd1,0x39,0x60,0xe2,0x64, -0x64,0x43,0xd0,0x80,0x28,0x60,0xe2,0x64,0x01,0x07,0x60,0x43,0x10,0x61,0xa3,0xd3, -0xff,0xff,0xff,0xff,0x01,0x2a,0x1e,0x00,0x0a,0x65,0x46,0xd3,0xff,0xff,0xcc,0x84, -0xa2,0xdb,0x03,0x02,0x00,0x64,0xa3,0xdb,0x15,0x00,0xfe,0xa2,0xa2,0xd3,0xff,0xff, -0x60,0x47,0x60,0x40,0x08,0x2a,0x02,0x00,0x08,0x7f,0x0a,0x00,0x04,0x2a,0x02,0x00, -0x04,0x7f,0x06,0x00,0x02,0x2a,0x02,0x00,0x02,0x7f,0x02,0x00,0x01,0x7f,0x01,0x7e, -0x60,0x47,0xa2,0xdb,0xcd,0x81,0x10,0xa3,0xda,0x02,0x59,0x60,0x74,0x64,0xa0,0xdd, -0x2e,0x58,0xff,0xff,0x3a,0x60,0xb0,0x63,0x6b,0xf3,0xff,0xff,0x00,0xbc,0x60,0x41, -0x10,0x03,0x2b,0xf2,0x50,0xfe,0xbd,0xd1,0x2c,0xf2,0xd0,0x80,0xbd,0xd1,0x2d,0xf2, -0xd0,0x80,0xbd,0xd1,0xff,0xff,0xd0,0x80,0xff,0xff,0x04,0x03,0xfa,0xa1,0xff,0xff, -0xf0,0x02,0x01,0xbc,0x2e,0x58,0xff,0xff,0x3a,0x60,0x38,0x63,0x6a,0xf3,0xe6,0x00, -0x3a,0x60,0xb0,0x65,0x6b,0xf3,0xff,0xff,0xc4,0x83,0x88,0xa0,0x06,0xa4,0x09,0x05, -0x6b,0xfb,0xff,0xff,0x2b,0xf2,0xbd,0xdb,0x2c,0xf2,0xff,0xff,0xbd,0xdb,0x2d,0xf2, -0xbd,0xdb,0x2e,0x58,0xff,0xff,0x3a,0x60,0x38,0x65,0x6a,0xf3,0xff,0xff,0xc4,0x83, -0x88,0xa0,0x06,0xa4,0x09,0x05,0x6a,0xfb,0xff,0xff,0x2b,0xf2,0xbd,0xdb,0x2c,0xf2, -0xff,0xff,0xbd,0xdb,0x2d,0xf2,0xbd,0xdb,0x2e,0x58,0xff,0xff,0x3a,0x60,0xb0,0x63, -0x6b,0xf3,0xff,0xff,0x00,0xbc,0x60,0x41,0x10,0x03,0x2e,0xf2,0x50,0xfe,0xbd,0xd1, -0x2f,0xf2,0xd0,0x80,0xbd,0xd1,0x30,0xf2,0xd0,0x80,0xbd,0xd1,0xff,0xff,0xd0,0x80, -0xff,0xff,0x04,0x03,0xfa,0xa1,0xff,0xff,0xf0,0x02,0x01,0xbc,0x2e,0x58,0xff,0xff, -0x3a,0x60,0xb0,0x65,0x6b,0xf3,0xff,0xff,0xc4,0x83,0x88,0xa0,0x06,0xa4,0x09,0x05, -0x6b,0xfb,0xff,0xff,0x2e,0xf2,0xbd,0xdb,0x2f,0xf2,0xff,0xff,0xbd,0xdb,0x30,0xf2, -0xbd,0xdb,0x2e,0x58,0xff,0xff,0x3c,0x60,0x64,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa8, -0x60,0x46,0x03,0x02,0x3d,0x60,0x2f,0x78,0xff,0xff,0x26,0x45,0xd4,0x80,0x0f,0xf0, -0xf9,0x03,0x64,0x44,0x70,0xb0,0x70,0x2a,0x03,0x00,0x6f,0x60,0x7a,0x78,0xff,0xff, -0x64,0x40,0x04,0x2a,0x13,0x00,0x67,0x60,0x60,0x62,0x00,0x64,0xa2,0xdb,0x29,0xf2, -0xff,0xff,0xff,0xff,0x40,0x2b,0x0f,0x00,0x64,0x40,0x80,0x2b,0x07,0x00,0x1b,0xf2, -0x22,0xf0,0x60,0x47,0xc0,0xb4,0xb0,0x84,0x22,0xfa,0x05,0x00,0x00,0x64,0x40,0x46, -0x3d,0x60,0x2f,0x78,0xff,0xff,0x32,0x40,0x01,0x2a,0x07,0x00,0x70,0x60,0xb6,0x78, -0xff,0xff,0x03,0x03,0x6f,0x60,0x7a,0x78,0xff,0xff,0x46,0x46,0x0f,0xf0,0xff,0xff, -0x64,0x44,0x80,0x26,0x0e,0x00,0x32,0x40,0x01,0x2a,0x08,0x00,0x22,0xf0,0x07,0x60, -0x01,0x64,0xb0,0x84,0x22,0xfa,0x6f,0x60,0x93,0x78,0xff,0xff,0x6f,0x60,0x7a,0x78, -0xff,0xff,0x08,0x26,0x2a,0x00,0x5b,0x60,0x22,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x29,0xf2, -0xff,0xff,0xff,0xff,0x03,0x27,0x06,0x00,0x67,0x60,0x78,0x62,0xa2,0xd3,0xff,0xff, -0x01,0xa4,0xa2,0xdb,0x32,0x44,0x01,0x2a,0x05,0x00,0x22,0xf0,0x07,0x60,0x02,0x64, -0xb0,0x84,0x04,0x00,0x02,0x2a,0x06,0x00,0x00,0x60,0x02,0x64,0x22,0xfa,0x6f,0x60, -0x93,0x78,0xff,0xff,0x6f,0x60,0x7a,0x78,0xff,0xff,0x32,0x40,0x01,0x2a,0x08,0x00, -0x22,0xf0,0x07,0x60,0x00,0x64,0xb0,0x84,0x22,0xfa,0x6f,0x60,0x93,0x78,0xff,0xff, -0x29,0xf2,0x0f,0xf0,0x60,0x40,0xa4,0x36,0x08,0x00,0x0c,0xb4,0x04,0x36,0x02,0x00, -0x0c,0x3a,0x06,0x00,0x6f,0x60,0x7a,0x78,0xff,0xff,0x6f,0x60,0x75,0x78,0xff,0xff, -0x64,0x40,0x60,0x26,0x03,0x00,0x6b,0x60,0x84,0x78,0xff,0xff,0x95,0xf3,0x29,0xf2, -0x00,0xbc,0xd3,0xf1,0x20,0x03,0x64,0x40,0x00,0x3a,0x4c,0x00,0x60,0x40,0x40,0x36, -0x49,0x00,0x80,0x3a,0x15,0x00,0x5c,0x63,0x61,0x60,0xbc,0x61,0xbd,0xd2,0xa1,0xd1, -0x02,0xa1,0xbd,0xd2,0xd0,0x80,0xa1,0xd1,0x02,0xa1,0x0a,0x02,0xd0,0x80,0xbd,0xd2, -0xa1,0xd1,0x06,0x02,0xd0,0x80,0xff,0xff,0x03,0x02,0x6d,0x60,0xd3,0x78,0xff,0xff, -0x6f,0x60,0x7a,0x78,0xff,0xff,0x5c,0x63,0x60,0x40,0x02,0x2b,0x62,0x63,0xbd,0xd2, -0x81,0xf1,0xbd,0xd2,0xd0,0x80,0x82,0xf1,0x07,0x02,0xd0,0x80,0xbd,0xd2,0x83,0xf1, -0x03,0x02,0xd0,0x80,0xff,0xff,0x1e,0x03,0xd5,0xf3,0xff,0xff,0xfd,0xa0,0x29,0xf2, -0x04,0x04,0x60,0x40,0x80,0x36,0x16,0x00,0x12,0x00,0x20,0x40,0x40,0x26,0xf9,0x00, -0x16,0x60,0x42,0x62,0xa2,0xd3,0x29,0xf2,0xfc,0xa0,0x2b,0xf0,0x08,0x02,0x60,0x40, -0x80,0x36,0x02,0x00,0x40,0x3a,0x03,0x00,0x64,0x40,0x01,0x26,0x03,0x00,0x6f,0x60, -0x7a,0x78,0xff,0xff,0x29,0xf2,0xff,0xff,0x0c,0xb4,0x08,0x3a,0x3a,0x00,0x70,0x60, -0x15,0x78,0xff,0xff,0x17,0x60,0x74,0x64,0xa0,0xd3,0xcb,0xf3,0x00,0xa0,0xfe,0xa0, -0xee,0x02,0xed,0x03,0x5a,0x60,0x88,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1f,0xf2,0xff,0xff, -0x60,0x45,0x5a,0x60,0xce,0x64,0xa0,0xd3,0xff,0xff,0xc4,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47, -0x00,0x7f,0xe0,0x84,0xe0,0x84,0x60,0x45,0x5a,0x60,0x8c,0x64,0xc4,0x84,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x0f,0xf2,0xff,0xff,0x60,0x40,0x40,0x26,0x42,0x00,0x32,0x44,0x02,0x26, -0x3f,0x00,0x58,0x60,0x5a,0x64,0xa0,0xd3,0xff,0xff,0x00,0xa0,0x60,0x41,0x13,0x03, -0x58,0x60,0x5e,0x63,0x2b,0xf2,0x50,0xfe,0xbd,0xd1,0x2c,0xf2,0xd0,0x80,0xbd,0xd1, -0x2d,0xf2,0xd0,0x80,0xbd,0xd1,0xff,0xff,0xd0,0x80,0xfa,0xa1,0x04,0x01,0xf2,0x02, -0x6f,0x60,0x7a,0x78,0xff,0xff,0xcb,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x20,0x02, -0x2e,0xf2,0xff,0xff,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0xe1,0x81, -0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84, -0xe1,0x81,0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81, -0xf0,0x84,0xf4,0xd6,0x7e,0x00,0x00,0x10,0xe1,0x81,0xf0,0x84,0x65,0x60,0x58,0x4e, -0x92,0x78,0xff,0xff,0x00,0x03,0x6f,0x60,0x64,0x78,0xff,0xff,0x32,0x40,0x02,0x26, -0x2e,0x00,0x29,0xf0,0x43,0xf3,0x64,0x40,0x08,0x2a,0x29,0x00,0x64,0x40,0x40,0x27, -0x0a,0x00,0x02,0x2a,0x08,0x00,0x38,0xf2,0xff,0xff,0x00,0xa8,0xff,0xff,0x03,0x03, -0x6f,0x60,0x7a,0x78,0xff,0xff,0x29,0xf0,0x03,0x67,0xa0,0x84,0xff,0xff,0x00,0x37, -0x62,0x63,0x02,0x37,0x5c,0x63,0x01,0x37,0x56,0x63,0x03,0x37,0x10,0x00,0xbd,0xd2, -0x81,0xf1,0xbd,0xd2,0xd0,0x80,0x82,0xf1,0x07,0x02,0xd0,0x80,0xbd,0xd2,0x83,0xf1, -0x03,0x02,0xd0,0x80,0xff,0xff,0x03,0x03,0x6f,0x60,0x7a,0x78,0xff,0xff,0x1e,0x60, -0x9e,0x62,0xa2,0xd5,0x1e,0x60,0x92,0x62,0xa2,0xd3,0xff,0xff,0x40,0x48,0x09,0xf2, -0x46,0x4b,0x00,0xbe,0x12,0xf2,0x19,0x03,0x60,0x45,0x28,0x44,0xd4,0x81,0x27,0x60, -0x10,0x65,0xd5,0x80,0x46,0x45,0xf3,0x04,0x09,0xf2,0x2b,0x46,0x09,0xfa,0x5b,0x60, -0x18,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb,0xa2,0xff,0x1a,0x60,0x58,0x4f, -0x9e,0x78,0xff,0xff,0xa3,0xff,0x2b,0x46,0xe2,0x00,0x26,0x46,0x34,0xf2,0xff,0xff, -0x0f,0xb4,0x29,0xf0,0x03,0x02,0x64,0x40,0x04,0x2b,0x67,0x00,0x60,0x40,0x0f,0x26, -0x7d,0x00,0x5a,0x60,0x74,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47, -0x00,0x7f,0xe0,0x84,0xe0,0x84,0x60,0x45,0x5a,0x60,0x78,0x64,0xc4,0x84,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x1f,0xf2,0xff,0xff,0x60,0x45,0x5a,0x60,0xce,0x64,0xa0,0xd3,0xff,0xff, -0xc4,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x1e,0x60,0x92,0x62,0xa2,0xd1,0xff,0xff,0x12,0xf8,0x3c,0x60,0x82,0x62,0x00,0x64, -0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x00,0x64, -0x09,0xfa,0x05,0xf2,0x06,0xf2,0x60,0x43,0x05,0xfa,0x60,0x46,0x01,0xf0,0x7f,0x60, -0xff,0x64,0xa0,0x84,0x01,0xfa,0x00,0x64,0x00,0xf0,0x00,0xfa,0xc0,0x80,0x44,0x45, -0x08,0x03,0x25,0x46,0x05,0xfc,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff, -0xa3,0xff,0x26,0x46,0x70,0x60,0x58,0x4e,0x99,0x78,0xff,0xff,0x09,0x02,0x2b,0x46, -0x26,0x44,0x09,0xfa,0x6f,0x60,0x8e,0x78,0xff,0xff,0x6d,0x60,0xb4,0x78,0xff,0xff, -0x09,0x45,0x09,0xf0,0x26,0x46,0x09,0xf8,0x2b,0x46,0x26,0x44,0x09,0xfa,0xa2,0xff, -0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0x5b,0x60,0x12,0x62,0xa2,0xd3, -0xff,0xff,0x01,0xa4,0xa2,0xdb,0x6f,0x60,0x8e,0x78,0xff,0xff,0x70,0x60,0x58,0x4e, -0x99,0x78,0xff,0xff,0x39,0x02,0x5a,0x60,0x74,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x26,0xf2, -0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84,0xe0,0x84,0x60,0x45,0x5a,0x60,0x78,0x64, -0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1f,0xf2,0xff,0xff,0x60,0x45,0x5a,0x60,0xce,0x64, -0xa0,0xd3,0xff,0xff,0xc4,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x5b,0x60,0x16,0x62,0xa2,0xd3,0xff,0xff,0x01,0xa4,0xa2,0xdb, -0x26,0x46,0x6f,0x60,0x7a,0x78,0xff,0xff,0x34,0xf2,0x26,0x46,0x34,0xf2,0x01,0xa5, -0xd4,0x80,0x29,0x46,0x6a,0x03,0x01,0xa4,0xd4,0x80,0x26,0x46,0x23,0x02,0x5a,0x60, -0xe6,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84, -0xe0,0x84,0x60,0x45,0x5a,0x60,0xea,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x6f,0x60, -0x7a,0x78,0xff,0xff,0x29,0x46,0x05,0xf2,0x09,0xf0,0x2b,0x46,0x09,0xf8,0x26,0x46, -0x05,0xf4,0x29,0x43,0x00,0xfc,0x26,0x46,0x05,0xfa,0x5a,0x60,0x74,0x64,0xa0,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84,0xe0,0x84,0x60,0x45, -0x5a,0x60,0x78,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1f,0xf2,0xff,0xff,0x60,0x45, -0x5a,0x60,0xce,0x64,0xa0,0xd3,0xff,0xff,0xc4,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82, -0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x5b,0x60,0x14,0x62,0xa2,0xd3,0xff,0xff, -0x01,0xa4,0xa2,0xdb,0x6f,0x60,0x7a,0x78,0xff,0xff,0x34,0xfa,0x5a,0x60,0x74,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84,0xe0,0x84, -0x60,0x45,0x5a,0x60,0x78,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1f,0xf2,0xff,0xff, -0x60,0x45,0x5a,0x60,0xce,0x64,0xa0,0xd3,0xff,0xff,0xc4,0x84,0xa2,0xdb,0x05,0x04, -0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x3c,0x60,0x82,0x62,0x00,0x64, -0xa2,0xdb,0x26,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0x26,0x46, -0x7f,0x60,0xff,0x65,0x00,0xf0,0x38,0xf2,0xff,0xff,0x06,0xf4,0x01,0xf2,0x60,0x41, -0xa4,0x84,0x01,0xfa,0x00,0xf2,0x00,0x63,0x00,0xfc,0x66,0x45,0x26,0x46,0x00,0xfa, -0x29,0x46,0x65,0x44,0x05,0xfa,0x64,0x45,0x06,0xf0,0x06,0xfa,0x64,0x46,0x65,0x44, -0x00,0xfa,0x29,0x46,0x38,0xf0,0x61,0x44,0xc0,0x84,0x38,0xfa,0x26,0x46,0x29,0xf0, -0x00,0xf2,0x06,0x45,0x00,0xa8,0x66,0x44,0x01,0x02,0x05,0xfa,0x64,0x40,0x04,0x2b, -0x0e,0x00,0x1e,0x60,0x92,0x62,0xa2,0xd3,0x29,0x46,0x12,0xfa,0xa2,0xff,0x1a,0x60, -0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0x6f,0x60,0x8e,0x78,0xff,0xff,0x29,0x46, -0x38,0xf2,0x09,0xf0,0x60,0x47,0x3f,0xfa,0x2b,0x46,0x09,0xf8,0x26,0x46,0xff,0x60, -0xf0,0x65,0x34,0xf2,0x29,0xf0,0xa4,0x84,0x29,0x46,0x34,0xfa,0xf7,0x60,0xff,0x64, -0x0b,0xfa,0xa0,0x9c,0x29,0xf8,0x00,0x64,0x09,0xfa,0x06,0xf4,0x80,0x67,0x01,0xf2, -0x60,0x45,0xb4,0x83,0x01,0xfc,0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff, -0xa3,0xff,0x09,0x46,0x29,0x46,0x95,0xf3,0xff,0xff,0x60,0x40,0x01,0x26,0x03,0x00, -0x6f,0x60,0x51,0x78,0xff,0xff,0x6f,0x60,0x64,0x78,0xff,0xff,0x95,0xf3,0xff,0xff, -0x60,0x40,0x01,0x26,0x03,0x00,0x6e,0x60,0x7e,0x78,0xff,0xff,0x29,0xf2,0xff,0xff, -0xff,0xff,0x50,0x3a,0xf0,0x00,0x5c,0x63,0x61,0x60,0xbc,0x61,0xbd,0xd2,0xa1,0xd1, -0x02,0xa1,0xbd,0xd2,0xd0,0x80,0xa1,0xd1,0x02,0xa1,0xe5,0x02,0xd0,0x80,0xbd,0xd2, -0xa1,0xd1,0xe1,0x02,0xd0,0x80,0xff,0xff,0xde,0x02,0x26,0x46,0x28,0x60,0xda,0x63, -0x00,0xf4,0x02,0xf2,0xbd,0xdb,0xff,0xff,0x03,0xf2,0xbd,0xdb,0x04,0xf2,0xff,0xff, -0xbd,0xdb,0x05,0xf2,0xa3,0xdb,0xfa,0xa3,0x26,0x46,0x00,0x60,0x00,0x65,0xa3,0xd3, -0x23,0xf0,0x00,0x61,0xd0,0x84,0xf1,0x81,0xd4,0x84,0xf1,0x81,0xbd,0xdb,0xa3,0xd3, -0x03,0xb1,0x03,0xa9,0x24,0xf0,0x42,0xfe,0x01,0x03,0xcc,0x84,0xf1,0x81,0xd0,0x84, -0xf1,0x81,0xbd,0xdb,0xa3,0xd3,0x03,0xb1,0x03,0xa9,0x27,0xf0,0x42,0xfe,0x01,0x03, -0xcc,0x84,0xf1,0x81,0xd0,0x84,0xf1,0x81,0xbd,0xdb,0xa3,0xd3,0x03,0xb1,0x03,0xa9, -0x28,0xf0,0x01,0x03,0xcc,0x84,0xd0,0x84,0xa3,0xdb,0x01,0x64,0x23,0xfb,0xff,0xff, -0x1a,0xff,0x67,0x60,0x6a,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0xff,0xff,0x68,0x03, -0x26,0x46,0x00,0xf4,0x02,0xf2,0x5a,0xd2,0x40,0x47,0x40,0x48,0x5a,0xd2,0x5a,0xd2, -0x40,0x49,0x60,0x41,0x5a,0xd0,0x80,0xf9,0x40,0x63,0xad,0x80,0xf0,0xa3,0x09,0x02, -0x3c,0x03,0x29,0x41,0x28,0x44,0x40,0x49,0x27,0x44,0x40,0x48,0x00,0x64,0x40,0x47, -0xf4,0x00,0xd1,0x80,0x01,0x02,0x31,0x04,0x10,0xa3,0x80,0x60,0x00,0x65,0xa5,0x80, -0xcf,0x83,0x08,0x02,0x27,0x44,0x60,0x87,0x28,0x44,0x70,0x88,0x29,0x44,0x70,0x89, -0xf1,0x81,0xf5,0x00,0xe7,0xa3,0x64,0x44,0x00,0xa0,0x00,0x62,0x02,0x02,0x00,0x61, -0x1c,0x00,0xe0,0x84,0xde,0x82,0xfd,0x04,0x42,0xfe,0xf8,0x84,0x62,0x45,0xc7,0x83, -0x60,0x45,0x02,0xfe,0xd5,0x84,0x02,0x05,0x01,0x05,0x61,0x44,0xcf,0x83,0x60,0x41, -0x08,0x03,0x27,0x44,0x60,0x87,0x28,0x44,0x70,0x88,0x29,0x44,0x70,0x89,0xf1,0x81, -0xf1,0x00,0xce,0x82,0xe9,0x81,0xfd,0x02,0xf1,0x81,0x02,0xf2,0xff,0xff,0x60,0x47, -0xe8,0x84,0xe8,0x84,0x5a,0xd2,0x3f,0xb5,0xe0,0x84,0xe0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0xe0,0x84,0xb4,0x84,0x61,0x45,0xd4,0x84,0xc0,0x84,0xe0,0x84,0xe0,0x84, -0xe0,0x84,0xe0,0x93,0x67,0x60,0x6a,0x62,0x00,0x64,0xa2,0xdb,0x26,0x46,0x6d,0x00, -0xcb,0xf3,0xff,0xff,0xfd,0xa0,0xff,0xff,0x68,0x02,0x3d,0x60,0x1c,0x64,0xa0,0xd3, -0xff,0xff,0x01,0xbc,0xa2,0xdb,0x29,0xf2,0xff,0xff,0x60,0x40,0x10,0x2b,0x09,0x00, -0x69,0x60,0x58,0x4e,0xdf,0x78,0xff,0xff,0x04,0x03,0x69,0x60,0x58,0x4e,0xf9,0x78, -0xff,0xff,0x2e,0xf2,0xff,0xff,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84, -0xe1,0x81,0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84,0xe1,0x81, -0xf0,0x84,0xe1,0x81,0x5a,0xd2,0xf0,0x85,0x94,0x84,0x60,0x41,0xe1,0x81,0xf0,0x84, -0xe1,0x81,0xf0,0x84,0xe1,0x81,0xf0,0x84,0x65,0x60,0x58,0x4e,0x92,0x78,0xff,0xff, -0x34,0x03,0x29,0xf2,0x34,0xf0,0x60,0x40,0x08,0x3a,0x61,0x00,0x08,0x2b,0x2a,0x00, -0x0c,0xa3,0xa3,0xd3,0xff,0xff,0xd0,0x80,0xff,0xff,0x25,0x02,0x5a,0x60,0xe6,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x26,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84,0xe0,0x84, -0x60,0x45,0x5a,0x60,0xea,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x6f,0x60,0x7a,0x78, -0xff,0xff,0x69,0x00,0x0c,0xa3,0xa3,0xd9,0x32,0x00,0x67,0x60,0x46,0x65,0x29,0xf2, -0x34,0xf0,0x60,0x40,0xa4,0x36,0x72,0x00,0x08,0x2b,0x28,0x00,0xa5,0xd3,0xff,0xff, -0xd0,0x80,0xff,0xff,0x23,0x02,0x5a,0x60,0xe6,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x26,0xf2, -0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84,0xe0,0x84,0x60,0x45,0x5a,0x60,0xea,0x64, -0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x6f,0x60,0x7a,0x78,0xff,0xff,0xa5,0xd9,0x29,0xf2, -0xff,0xff,0xff,0xff,0x0c,0x22,0x42,0x00,0x5a,0x60,0x74,0x64,0xa0,0xd3,0xff,0xff, -0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb, -0x26,0xf2,0xff,0xff,0x60,0x47,0x00,0x7f,0xe0,0x84,0xe0,0x84,0x60,0x45,0x5a,0x60, -0x78,0x64,0xc4,0x84,0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82, -0xa2,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x1f,0xf2,0xff,0xff,0x60,0x45,0x5a,0x60, -0xce,0x64,0xa0,0xd3,0xff,0xff,0xc4,0x84,0xa2,0xdb,0x05,0x04,0xda,0x82,0xa2,0xd3, -0xff,0xff,0xdc,0x84,0xa2,0xdb,0x46,0x48,0x00,0xf4,0x80,0x60,0x87,0x65,0x66,0x44, -0xac,0x80,0x05,0xf2,0xff,0xff,0xd4,0x80,0x08,0x03,0x07,0x02,0x6f,0x60,0xc4,0x78, -0xff,0xff,0x03,0x02,0x6a,0x60,0x0c,0x78,0xff,0xff,0x28,0x46,0x38,0xf2,0x49,0xf1, -0xff,0xff,0xd0,0x80,0xff,0xff,0x10,0x07,0x78,0x43,0x04,0xa3,0x56,0xfd,0x0c,0x60, -0x46,0x64,0xa0,0xd7,0xff,0xff,0xff,0xff,0x6a,0x60,0x0c,0x78,0xff,0xff,0x95,0xf3, -0xff,0xff,0x60,0x40,0x01,0x26,0x19,0x00,0x0f,0x4e,0x46,0x45,0x3c,0x60,0x82,0x62, -0x00,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff, -0xa2,0xff,0x1a,0x60,0x58,0x4f,0x9e,0x78,0xff,0xff,0xa3,0xff,0xd1,0xfe,0x0e,0x4f, -0x00,0x64,0x40,0x46,0x6a,0x60,0x0c,0x78,0xff,0xff,0x3c,0x60,0x82,0x62,0x3c,0x60, -0x6a,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff, -0xd2,0xfe,0x00,0x64,0x40,0x46,0x6a,0x60,0x0c,0x78,0xff,0xff,0x2f,0x58,0xff,0xff, -0x29,0xf2,0xff,0xff,0x60,0x47,0x56,0x63,0x01,0xb0,0x01,0x26,0x62,0x63,0xbd,0xd0, -0x39,0xf8,0xbd,0xd0,0xff,0xff,0x3a,0xf8,0xbd,0xd0,0x3b,0xf8,0x02,0xb0,0x5c,0x63, -0x04,0x03,0x62,0x63,0x03,0xb0,0x02,0x3a,0x6a,0x63,0xbd,0xd0,0x3c,0xf8,0xbd,0xd0, -0xff,0xff,0x3d,0xf8,0xbd,0xd0,0x3e,0xf8,0x2f,0x58,0xff,0xff,0x06,0x67,0x06,0xf2, -0x60,0x45,0xd4,0x80,0xff,0xff,0x48,0x02,0x17,0x60,0x7a,0x63,0xa3,0xd3,0x08,0xfe, -0xff,0xff,0x04,0x26,0x41,0x00,0x07,0x67,0x06,0xfa,0x28,0x46,0x00,0xf0,0x04,0x64, -0x03,0xfa,0x04,0xf8,0x00,0x64,0x0b,0xfa,0x0c,0xfa,0xff,0xff,0x0f,0xfa,0x2e,0xf2, -0x2b,0xfa,0xff,0xff,0x2f,0xf2,0x2c,0xfa,0x30,0xf2,0xff,0xff,0x2d,0xfa,0xbd,0xf1, -0x2e,0xf8,0xff,0xff,0xbe,0xf1,0x2f,0xf8,0xbf,0xf1,0xff,0xff,0x30,0xf8,0x85,0xf3, -0xff,0xff,0x08,0xbc,0x43,0xf1,0xff,0xff,0x64,0x40,0x01,0x2a,0x03,0x00,0x60,0x47, -0x40,0xbc,0x60,0x47,0x29,0xfa,0x00,0x63,0x28,0xfc,0x22,0xfc,0x3a,0x60,0x58,0x4e, -0x14,0x78,0xff,0xff,0xff,0x7f,0x00,0x7e,0x0e,0xfa,0x3c,0x60,0x82,0x62,0x3c,0x60, -0x28,0x64,0xa2,0xdb,0x66,0x44,0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff, -0xc1,0xfe,0x00,0x64,0x40,0x46,0x48,0xfe,0x6f,0x60,0x5f,0x78,0xff,0xff,0x2b,0xf0, -0x67,0x44,0xd0,0x80,0x38,0xf2,0x7b,0x02,0xdc,0xa0,0x00,0xf4,0x78,0x04,0x06,0x60, -0x08,0x65,0x05,0xf2,0x09,0xf0,0xd4,0x80,0x01,0x60,0x00,0x64,0x70,0x02,0xd0,0x80, -0x67,0x60,0x06,0x63,0x6c,0x02,0x67,0x60,0x0a,0x64,0xa0,0xd3,0xff,0xff,0xdc,0x84, -0xa2,0xdb,0x12,0xf0,0xbd,0xd3,0x13,0xf0,0xd0,0x80,0xa3,0xd3,0x60,0x02,0xd0,0x80, -0x00,0xa0,0x5d,0x02,0x5c,0x03,0xbd,0xf3,0x0f,0xfa,0xbe,0xf3,0xff,0xff,0x10,0xfa, -0xbf,0xf3,0x11,0xfa,0x02,0x60,0x00,0x64,0x09,0xfa,0x14,0x63,0x1e,0x61,0x26,0x65, -0xa3,0xd2,0xa1,0xd0,0xa1,0xda,0x64,0x44,0xbd,0xda,0xd5,0x80,0xd9,0x81,0xf8,0x02, -0x26,0x46,0x85,0xf3,0x43,0xf1,0x08,0xbc,0x60,0x47,0x64,0x40,0x01,0x26,0x40,0xbc, -0x60,0x47,0x29,0xfa,0xff,0x7f,0x00,0x7e,0x0e,0xfa,0x28,0x64,0x38,0xfa,0x00,0x64, -0x22,0xfa,0x28,0xfa,0xff,0xff,0x81,0xf3,0x2b,0xfa,0x82,0xf3,0xff,0xff,0x2c,0xfa, -0x83,0xf3,0x2d,0xfa,0xff,0xff,0xbd,0xf3,0x2e,0xfa,0xbe,0xf3,0xff,0xff,0x2f,0xfa, -0xbf,0xf3,0x30,0xfa,0xff,0xff,0x00,0xf4,0x0f,0xf2,0x10,0xf0,0x60,0x45,0x11,0xf2, -0x26,0x46,0x33,0xfa,0x64,0x44,0x32,0xfa,0x65,0x44,0x31,0xfa,0x3a,0x60,0x58,0x4e, -0x14,0x78,0xff,0xff,0x3c,0x60,0x82,0x62,0x3c,0x60,0x28,0x64,0xa2,0xdb,0x66,0x44, -0x5a,0xdb,0x0a,0x64,0x5a,0xdb,0xff,0xff,0x2b,0xff,0xc1,0xfe,0x67,0x60,0x0c,0x64, -0xa0,0xd3,0xff,0xff,0xdc,0x84,0xa2,0xdb,0x6f,0x60,0x8e,0x78,0xff,0xff,0x26,0x46, -0x6b,0x60,0x03,0x78,0xff,0xff,0x1e,0x60,0x9e,0x64,0xa0,0xd5,0x66,0x45,0x09,0xf2, -0x46,0x4b,0x00,0xbe,0x46,0x49,0x12,0x03,0x30,0xf0,0x65,0x46,0x30,0xf2,0x2f,0xf0, -0xd0,0x80,0x29,0x46,0xf4,0x02,0x2f,0xf2,0x2e,0xf2,0xd0,0x80,0x65,0x46,0x03,0x02, -0x2e,0xf0,0xff,0xff,0xd0,0x80,0x29,0x46,0xea,0x02,0x08,0xfe,0x2e,0x58,0xff,0xff, -0x00,0x64,0x00,0xa0,0x68,0x60,0xd4,0x62,0xa2,0xd3,0x29,0xf0,0x60,0x40,0x00,0x36, -0x34,0x00,0x01,0x3a,0x07,0x00,0x64,0x44,0x00,0x7f,0x80,0x65,0xd4,0x80,0xff,0xff, -0x2f,0x03,0x2b,0x00,0x64,0x44,0x0c,0xb4,0xf8,0xa0,0xff,0xff,0x44,0x03,0x64,0x44, -0x80,0x36,0x26,0x00,0xb4,0x36,0x27,0x00,0xc4,0x36,0x28,0x00,0xd4,0x36,0x29,0x00, -0x40,0x36,0x2a,0x00,0xe4,0x36,0x2b,0x00,0x00,0x36,0x2c,0x00,0x10,0x36,0x2d,0x00, -0x20,0x36,0x28,0x00,0x30,0x36,0x29,0x00,0x50,0x36,0x27,0x00,0xa0,0x36,0x28,0x00, -0xa4,0x36,0x20,0x00,0xb0,0x36,0x24,0x00,0xc0,0x36,0x22,0x00,0x68,0x60,0xd6,0x62, -0x68,0x60,0xd8,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb,0x6a,0x60,0x42,0x78,0xff,0xff, -0x72,0x60,0xb8,0x78,0xff,0xff,0x71,0x60,0x5a,0x78,0xff,0xff,0x71,0x60,0x98,0x78, -0xff,0xff,0x71,0x60,0x8b,0x78,0xff,0xff,0x71,0x60,0xa5,0x78,0xff,0xff,0x71,0x60, -0xfd,0x78,0xff,0xff,0x71,0x60,0x14,0x78,0xff,0xff,0x71,0x60,0x37,0x78,0xff,0xff, -0x72,0x60,0x1b,0x78,0xff,0xff,0x72,0x60,0x52,0x78,0xff,0xff,0x68,0x60,0xd6,0x62, -0x68,0x60,0xd8,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb,0xff,0xff,0x2b,0xf2,0x81,0xf1, -0xff,0xff,0xd0,0x80,0x2c,0xf2,0x82,0xf1,0x07,0x02,0xd0,0x80,0x2d,0xf2,0x83,0xf1, -0x03,0x02,0xd0,0x80,0xff,0xff,0x06,0x03,0x56,0x65,0x73,0x60,0x58,0x4f,0xc2,0x78, -0xff,0xff,0x04,0x02,0x68,0x60,0xd6,0x62,0x01,0x64,0xa2,0xdb,0x70,0x60,0xf3,0x78, -0xff,0xff,0x68,0x60,0xd6,0x62,0x68,0x60,0xd8,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb, -0xff,0xff,0x2e,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80,0x2f,0xf2,0x82,0xf1,0x07,0x02, -0xd0,0x80,0x30,0xf2,0x83,0xf1,0x03,0x02,0xd0,0x80,0xff,0xff,0x06,0x03,0x5c,0x65, -0x73,0x60,0x58,0x4f,0xc2,0x78,0xff,0xff,0x04,0x02,0x68,0x60,0xd6,0x62,0x01,0x64, -0xa2,0xdb,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60,0xd6,0x62,0x68,0x60,0xd8,0x63, -0x00,0x64,0xa2,0xdb,0xa3,0xdb,0xff,0xff,0x2b,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80, -0x2c,0xf2,0x82,0xf1,0x15,0x02,0xd0,0x80,0x2d,0xf2,0x83,0xf1,0x11,0x02,0xd0,0x80, -0xff,0xff,0x14,0x03,0x2e,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80,0x2f,0xf2,0x82,0xf1, -0x07,0x02,0xd0,0x80,0x30,0xf2,0x83,0xf1,0x03,0x02,0xd0,0x80,0xff,0xff,0x06,0x03, -0x56,0x65,0x73,0x60,0x58,0x4f,0xc2,0x78,0xff,0xff,0x04,0x02,0x68,0x60,0xd8,0x62, -0x01,0x64,0xa2,0xdb,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60,0xd8,0x65,0x68,0x60, -0xd6,0x63,0x00,0x64,0x01,0x61,0xa3,0xd1,0xa5,0xdb,0xd1,0x80,0xa3,0xdb,0x70,0x60, -0xf3,0x78,0xff,0xff,0x68,0x60,0xd8,0x65,0x68,0x60,0xd6,0x63,0x00,0x64,0x01,0x61, -0xa5,0xd1,0xa3,0xdb,0xd1,0x80,0xa5,0xdb,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60, -0xd6,0x62,0x68,0x60,0xd8,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb,0x46,0x4a,0x2b,0xf2, -0x81,0xf1,0xff,0xff,0xd0,0x80,0x2c,0xf2,0x82,0xf1,0x0c,0x02,0xd0,0x80,0x2d,0xf2, -0x83,0xf1,0x08,0x02,0xd0,0x80,0xff,0xff,0x05,0x02,0x68,0x60,0xd6,0x62,0x01,0x64, -0xa2,0xdb,0x0c,0x00,0x2b,0xf0,0xff,0x60,0xff,0x64,0xd0,0x80,0x2c,0xf0,0x33,0x02, -0xd0,0x80,0x2d,0xf0,0x30,0x02,0xd0,0x80,0xff,0xff,0x2d,0x02,0x38,0xf2,0xff,0xff, -0xfe,0xa0,0xff,0xff,0x28,0x04,0x00,0xf4,0x02,0xf0,0x16,0x60,0x44,0x62,0xa2,0xd1, -0x64,0x47,0xd0,0x80,0xff,0xff,0x1f,0x02,0x60,0x41,0xe9,0x81,0x06,0x63,0x0c,0x03, -0x16,0x60,0x46,0x64,0x60,0x45,0xbd,0xd0,0xa5,0xd3,0xff,0xff,0xd0,0x80,0x65,0x44, -0x12,0x02,0xcd,0x81,0x02,0xa4,0xf6,0x02,0x02,0xf0,0xff,0xff,0x64,0x40,0x01,0x27, -0x02,0x00,0x48,0xfe,0x08,0x00,0xa3,0xd0,0xa0,0xd1,0x64,0x44,0x00,0x7f,0x60,0x45, -0x64,0x44,0x00,0x7f,0xd4,0x80,0x2a,0x46,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60, -0xd6,0x62,0x68,0x60,0xd8,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb,0xff,0xff,0x2e,0xf2, -0x81,0xf1,0xff,0xff,0xd0,0x80,0x2f,0xf2,0x82,0xf1,0x07,0x02,0xd0,0x80,0x30,0xf2, -0x83,0xf1,0x03,0x02,0xd0,0x80,0xff,0xff,0x05,0x03,0x5c,0x65,0x73,0x60,0x58,0x4f, -0xc2,0x78,0xff,0xff,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60,0xd6,0x62,0x68,0x60, -0xd8,0x63,0x00,0x64,0xa2,0xdb,0xa3,0xdb,0xff,0xff,0x2b,0xf2,0x81,0xf1,0xff,0xff, -0xd0,0x80,0x2c,0xf2,0x82,0xf1,0x07,0x02,0xd0,0x80,0x2d,0xf2,0x83,0xf1,0x03,0x02, -0xd0,0x80,0xff,0xff,0x1a,0x03,0x56,0x65,0x73,0x60,0x58,0x4f,0xc2,0x78,0xff,0xff, -0x14,0x03,0x2e,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80,0x2f,0xf2,0x82,0xf1,0x07,0x02, -0xd0,0x80,0x30,0xf2,0x83,0xf1,0x03,0x02,0xd0,0x80,0xff,0xff,0x06,0x03,0x5c,0x65, -0x73,0x60,0x58,0x4f,0xc2,0x78,0xff,0xff,0x04,0x00,0x68,0x60,0xd6,0x62,0x01,0x64, -0xa2,0xdb,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60,0xd6,0x62,0x68,0x60,0xd8,0x63, -0x00,0x64,0xa2,0xdb,0xa3,0xdb,0x29,0xf2,0xff,0xff,0xff,0xff,0x01,0x2b,0x3a,0x00, -0x2b,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80,0x2c,0xf2,0x82,0xf1,0x07,0x02,0xd0,0x80, -0x2d,0xf2,0x83,0xf1,0x03,0x02,0xd0,0x80,0xff,0xff,0x40,0x03,0x68,0x60,0xdc,0x62, -0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff,0x42,0x02,0x68,0x60,0xde,0x62,0xa2,0xd3, -0xff,0xff,0x00,0xa0,0x40,0x47,0x1e,0x03,0x56,0x65,0x68,0x60,0xe0,0x61,0x65,0x43, -0x50,0xfe,0xbd,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80,0xbd,0xd2,0xa1,0xd1,0x02,0xa1, -0xd0,0x80,0xa3,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80,0xff,0xff,0x1f,0x01,0x27,0x44, -0xcc,0x84,0x40,0x47,0xec,0x02,0x29,0xf2,0xff,0xff,0xff,0xff,0x01,0x27,0x02,0x00, -0x08,0xfe,0x1d,0x00,0x2e,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80,0x2f,0xf2,0x82,0xf1, -0x07,0x02,0xd0,0x80,0x30,0xf2,0x83,0xf1,0x03,0x02,0xd0,0x80,0xff,0xff,0x06,0x03, -0x5c,0x65,0x73,0x60,0x58,0x4f,0xc2,0x78,0xff,0xff,0x09,0x02,0x2b,0xf2,0xff,0xff, -0xff,0xff,0x01,0x26,0x04,0x00,0x68,0x60,0xd6,0x62,0x01,0x64,0xa2,0xdb,0x70,0x60, -0xf3,0x78,0xff,0xff,0x68,0x60,0xd6,0x62,0x68,0x60,0xd8,0x63,0x00,0x64,0xa2,0xdb, -0xa3,0xdb,0x38,0xf2,0x46,0x4a,0x60,0x41,0x68,0x60,0xd4,0x62,0xa2,0xd3,0xff,0xff, -0xff,0xff,0x02,0x36,0x07,0x00,0x68,0x60,0xd2,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff, -0x04,0x36,0x07,0x00,0x61,0x44,0xf2,0xa0,0xff,0xff,0x06,0x05,0x73,0x60,0xbe,0x78, -0xff,0xff,0x73,0x60,0x15,0x78,0xff,0xff,0x2e,0xf2,0x81,0xf1,0xff,0xff,0xd0,0x80, -0x2f,0xf2,0x82,0xf1,0x07,0x02,0xd0,0x80,0x30,0xf2,0x83,0xf1,0x03,0x02,0xd0,0x80, -0xff,0xff,0xef,0x03,0x68,0x60,0xd4,0x62,0xa2,0xd3,0xff,0xff,0xfe,0xa0,0xff,0xff, -0xe5,0x02,0x68,0x60,0xdc,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff,0xde,0x02, -0x68,0x60,0xde,0x62,0xa2,0xd3,0xff,0xff,0x00,0xa0,0x40,0x47,0x22,0x03,0x5c,0x65, -0x68,0x60,0xe0,0x61,0x65,0x43,0x50,0xfe,0xbd,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80, -0xbd,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80,0xa3,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80, -0xff,0xff,0xc4,0x01,0x27,0x44,0xcc,0x84,0x40,0x47,0xec,0x02,0x0a,0x00,0x68,0x60, -0xd4,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff,0x02,0x3a,0x03,0x00,0x73,0x60,0xbe,0x78, -0xff,0xff,0x38,0xf2,0x00,0xf4,0x08,0xf0,0xf2,0xa0,0xff,0xff,0x03,0x05,0x73,0x60, -0xbe,0x78,0xff,0xff,0x68,0x60,0xd2,0x62,0xa2,0xd3,0xff,0xff,0xff,0xff,0x04,0x36, -0x1b,0x00,0x16,0x60,0x44,0x62,0x64,0x47,0x00,0xa0,0xff,0xff,0x3c,0x06,0xe0,0xa0, -0xff,0xff,0x39,0x07,0xa2,0xdb,0x12,0x63,0x60,0x41,0x16,0x60,0x46,0x64,0xbd,0xd0, -0xa0,0xd9,0xcd,0x81,0x02,0xa4,0xfb,0x02,0x08,0xf0,0xff,0xff,0x64,0x40,0x01,0x2b, -0x2a,0x00,0xa3,0xd0,0xa0,0xd9,0x27,0x00,0x16,0x60,0x44,0x62,0x64,0x47,0xa2,0xd1, -0xff,0xff,0xd0,0x80,0xff,0xff,0x6c,0x02,0x60,0x41,0xe9,0x81,0x12,0x63,0x0c,0x03, -0x16,0x60,0x46,0x64,0x60,0x45,0xbd,0xd0,0xa5,0xd3,0xff,0xff,0xd0,0x80,0x65,0x44, -0x5f,0x02,0xcd,0x81,0x02,0xa4,0xf6,0x02,0x08,0xf0,0xff,0xff,0x64,0x40,0x01,0x2b, -0x0a,0x00,0xa3,0xd0,0xa0,0xd1,0x64,0x44,0x00,0x7f,0x60,0x45,0x64,0x44,0x00,0x7f, -0xd4,0x80,0xff,0xff,0x4d,0x02,0x08,0xf2,0x12,0x65,0x00,0x7e,0x60,0x47,0xc4,0x81, -0x61,0x45,0x01,0x26,0x04,0x00,0xa1,0xd2,0xf4,0xe6,0x7e,0x00,0xda,0x01,0xff,0xff, -0x60,0x47,0x02,0x00,0x01,0xa1,0xa1,0xd2,0xff,0xff,0x00,0x7f,0x02,0xa4,0xc4,0x81, -0x02,0xa1,0x01,0x26,0x02,0x00,0xa1,0xd2,0x04,0x00,0xff,0xa1,0xa1,0xd2,0xff,0xff, -0x60,0x47,0x7f,0xf1,0x00,0x7f,0xd0,0x80,0xff,0xff,0x2d,0x02,0x68,0x60,0xd4,0x62, -0xa2,0xd3,0xff,0xff,0xfe,0xa0,0xff,0xff,0x19,0x02,0x68,0x60,0xde,0x62,0xa2,0xd3, -0xff,0xff,0xf6,0xa0,0x60,0x41,0x12,0x05,0x01,0xa4,0xa2,0xdb,0xe1,0x81,0xe1,0x85, -0xc5,0x85,0x68,0x60,0xe0,0x64,0xc4,0x81,0x2a,0x46,0x5c,0x63,0xbd,0xd2,0xa1,0xdb, -0xbd,0xd2,0x02,0xa1,0xa1,0xdb,0xa3,0xd2,0x02,0xa1,0xa1,0xdb,0x68,0x60,0xd4,0x62, -0x02,0x64,0xa2,0xdb,0x2a,0x46,0xff,0xff,0x2e,0xf0,0x81,0xf9,0x2f,0xf0,0xff,0xff, -0x82,0xf9,0x30,0xf0,0x83,0xf9,0x2a,0x46,0x70,0x60,0xf3,0x78,0xff,0xff,0x68,0x60, -0xdc,0x62,0xa2,0xd3,0xff,0xff,0xff,0xa0,0xff,0xff,0x1d,0x02,0x68,0x60,0xde,0x62, -0xa2,0xd3,0xff,0xff,0xff,0xa0,0x40,0x47,0x16,0x04,0x68,0x60,0xe0,0x61,0x65,0x43, -0x50,0xfe,0xbd,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80,0xbd,0xd2,0xa1,0xd1,0x02,0xa1, -0xd0,0x80,0xa3,0xd2,0xa1,0xd1,0x02,0xa1,0xd0,0x80,0xff,0xff,0x06,0x01,0x27,0x44, -0xcc,0x84,0x40,0x47,0xec,0x02,0x08,0xfe,0x01,0x00,0x48,0xfe,0x2f,0x58,0xff,0xff, -0x99,0xff,0x08,0x60,0x2a,0x62,0x05,0x60,0xff,0x64,0xa2,0xdb,0x05,0x60,0xff,0xe5, -0xff,0xff,0xff,0xff,0x98,0xff,0xe0,0x60,0x00,0x63,0xfe,0x60,0x00,0x66,0x0c,0x60, -0x7b,0x64,0xa3,0xd0,0xcc,0x84,0xbd,0xd8,0xfc,0x02,0x99,0xff,0x08,0x60,0x2a,0x62, -0x04,0x60,0xff,0x64,0xa2,0xdb,0x04,0x60,0xff,0xe5,0xff,0xff,0xff,0xff,0x98,0xff, -0x0c,0x60,0x87,0x78,0xff,0xff,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00, -0x00,0x00,0x01,0x00,0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x01,0x00, -0x01,0x00,0x01,0x00,0x21,0x00,0x02,0x00,0x02,0x00,0x01,0x00,0x00,0x00,0x04,0x00, -0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x10,0x20,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x02,0x00,0x02,0x00,0x00,0x00, -0x53,0x65,0x63,0x6f,0x6e,0x64,0x61,0x72,0x79,0x20,0x46,0x27,0x73,0x00,0x0f,0x01, -0x00,0x18,0x7e,0x00,0xce,0xd0,0x0c,0x01,0x38,0x81,0x7f,0x00,0x02,0x00,0x0e,0x01, -0xfa,0x8d,0x7f,0x00,0x02,0x00,0x10,0x01,0x00,0x80,0x7f,0x00,0xda,0x14,0x0a,0x01, -0xc2,0x8d,0x7f,0x00,0x02,0x00,0x0b,0x01,0x0c,0x8e,0x7f,0x00,0x24,0x00,0x08,0x01, -0xe8,0x8d,0x7f,0x00,0x12,0x00,0x09,0x01,0xe6,0x8d,0x7f,0x00,0x02,0x00,0x04,0x01, -0x0a,0x81,0x7f,0x00,0x02,0x00,0x05,0x01,0x46,0x8d,0x7f,0x00,0x02,0x00,0x05,0x01, -0x40,0x81,0x7f,0x00,0x02,0x00,0x02,0x00,0x00,0x80,0x7f,0x00,0xfa,0x0f,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x0f,0x00,0x00,0x00,0x00,0x00,0x70,0x09, -0x34,0x09,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x1b,0x00,0x1b,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xe0,0x27, -0xe0,0x27,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x05,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0x07,0x01,0x00,0x64,0x00,0x64,0x00, -0xe8,0x03,0x10,0x27,0x14,0x00,0x88,0x13,0x88,0x13,0x2f,0x00,0x14,0x00,0x04,0x00, -0x0f,0x00,0x02,0x00,0x02,0x00,0x14,0x00,0x0a,0x00,0x0f,0x00,0x0f,0x00,0x05,0x00, -0x0a,0x00,0x64,0x00,0x88,0x13,0x0d,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x01,0x00, -0x05,0x00,0x08,0x00,0x23,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x2b,0x09, -0x03,0x00,0x00,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x1f,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0x10,0x60,0xa3,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x41,0xff,0x10,0x60,0xa4,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc4,0xe2,0x10,0x60,0xab,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x10,0x60,0x85,0x78,0x43,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x44,0xff,0x08,0xe1,0x10,0x60, -0xc6,0x78,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x44,0xe2,0x10,0x60,0xc8,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x46,0xff,0x10,0x60,0xc9,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x10,0x60,0xca,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x12,0x60,0xd8,0x78,0x4c,0x4e, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x12,0x60,0x9f,0x78,0x4c,0xe2, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x60,0xcf,0x78,0x43,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x60,0xab,0x78,0xa1,0xf3, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x12,0x60,0xbc,0x78,0x46,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x11,0x60,0x8e,0x78,0x47,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x42,0xff,0x19,0x60,0x56,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x43,0xff,0x19,0x60,0x56,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x44,0xff,0x19,0x60,0x56,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x45,0xff,0x1a,0x60,0xd4,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x07,0xf7,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x83,0x7c,0x08,0x60,0x12,0x64,0x80,0x29, -0xa0,0xd9,0x47,0xff,0x19,0x60,0x0c,0x78,0xff,0xff,0x40,0xff,0x24,0x58,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x41,0xff,0x21,0x58,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xc4,0xe2,0x22,0x58,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x60,0x08,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x22,0x60,0x76,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x45,0xff,0x21,0x58,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x1b,0x60,0x08,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x20,0x60,0x0b,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xf8,0x60,0x8c,0x78,0x40,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xf6,0x60,0xa0,0x78,0x41,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xf8,0x60,0xf5,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0x25,0x60,0x2d,0x78,0x43,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xf8,0x60,0xf5,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0x24,0x60,0xb2,0x78,0x45,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0x25,0x60,0x75,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0xf8,0x60,0xf5,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0xff,0xff,0x3d,0x60,0x25,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3f,0x60,0x47,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x00,0x79,0x3d,0x60,0x2e,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x24,0xe2,0x3d,0x60,0x2e,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x3d,0x60,0xa1,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x44,0xe2,0x3d,0x60,0x2e,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x84,0xe2,0x3d,0x60,0x2e,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x47,0xff,0x3d,0x60,0x2e,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x30,0x60,0x37,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x31,0x60,0x19,0x78,0xff,0xff, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x28,0xe2,0x30,0x60,0x7f,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x44,0xff,0x30,0x60,0x7f,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x45,0xff,0x30,0x60,0x7f,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x46,0xff,0x30,0x60,0x7f,0x78, -0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0x87,0x7c,0x08,0x60,0x12,0x64,0x80,0x29, -0xa0,0xd9,0x47,0xff,0x30,0x60,0x7f,0x78,0x93,0x6f,0xa6,0x6f,0xcc,0x3f,0xb3,0x50, -0xe4,0x67,0xbf,0x64,0x4e,0x2d,0x53,0x56,0x38,0x68,0xd0,0x58,0xa4,0x6f,0xa4,0x6f, -0xa4,0x6f,0xa4,0x6f,0xa4,0x6f,0xa4,0x6f,0xa4,0x6f,0xa4,0x6f,0xa4,0x6f,0xa4,0x6f, -0xa4,0x6f,0xa4,0x6f,0x8e,0x11,0x00,0x0a,0x10,0x01,0x68,0xa4,0xb0,0x01,0x84,0x01, -0x30,0x33,0x31,0x33,0x44,0x44,0x30,0x33,0x31,0x33,0x30,0x33,0x31,0x33,0x32,0x33, -0x32,0x33,0x90,0x00,0x78,0x04,0xae,0xe4,0xcc,0x3d,0xb5,0x3d,0xb0,0x33,0x46,0x34, -0x03,0xfc,0xe7,0x34,0xe1,0x36,0xc6,0x17,0x02,0x00,0x04,0xfc,0xe7,0x34,0x13,0x35, -0xe4,0x16,0x22,0x00,0x07,0xfc,0xe7,0x34,0x13,0x35,0x92,0x00,0x02,0x00,0x0e,0xfc, -0xe7,0x34,0xfd,0x36,0x10,0x17,0x22,0x00,0x00,0xfc,0xe7,0x34,0x13,0x35,0xc0,0x16, -0x02,0x00,0x01,0xfc,0xe7,0x34,0x04,0x35,0xb6,0x16,0x06,0x00,0x02,0xfc,0xe7,0x34, -0x04,0x35,0xc2,0x16,0x22,0x00,0x05,0xfc,0xe7,0x34,0x13,0x35,0xbe,0x16,0x02,0x00, -0x09,0xfc,0xe7,0x34,0x7e,0x37,0x06,0x17,0x02,0x00,0x0a,0xfc,0xe7,0x34,0x13,0x35, -0x08,0x17,0x02,0x00,0x0b,0xfc,0xe7,0x34,0x13,0x35,0x0a,0x17,0x02,0x00,0x0c,0xfc, -0xe7,0x34,0x13,0x35,0x0c,0x17,0x02,0x00,0x0f,0xfc,0xe7,0x34,0x13,0x35,0x5e,0x17, -0x02,0x00,0x19,0xfd,0xe7,0x34,0x13,0x35,0x70,0x17,0x02,0x00,0xb0,0xfc,0xe7,0x34, -0x13,0x35,0xbe,0x01,0x02,0x00,0x1a,0xfd,0xe7,0x34,0x13,0x35,0x3a,0x17,0x02,0x00, -0x8e,0xfc,0xe7,0x34,0x13,0x35,0x44,0x17,0x02,0x00,0xa8,0xfc,0xe7,0x34,0x13,0x35, -0x46,0x17,0x02,0x00,0xb3,0xfc,0xe7,0x34,0x13,0x35,0xdc,0x17,0x02,0x00,0xb4,0xfc, -0xe7,0x34,0x30,0x37,0x92,0x01,0x02,0x00,0xa9,0xfc,0xe7,0x34,0xcf,0x34,0xd4,0x66, -0x02,0x00,0xad,0xfc,0xe7,0x34,0x13,0x35,0x6a,0x00,0x02,0x00,0xaa,0xfc,0xe7,0x34, -0x13,0x35,0xc2,0x01,0x02,0x00,0xab,0xfc,0xe7,0x34,0x13,0x35,0x76,0x67,0x02,0x00, -0xac,0xfc,0xe7,0x34,0x13,0x35,0xf6,0x18,0x02,0x00,0xaf,0xfc,0xcf,0x34,0x39,0x39, -0x00,0x00,0x02,0x00,0x0d,0xfc,0xe7,0x34,0x13,0x35,0x0e,0x17,0x02,0x00,0x19,0xfc, -0xe7,0x34,0x13,0x35,0xa6,0x01,0x02,0x00,0x20,0xfc,0xe7,0x34,0x13,0x35,0xb4,0x61, -0x06,0x00,0x21,0xfc,0xe7,0x34,0x00,0x35,0xbc,0x61,0x06,0x00,0x24,0xfc,0x13,0x35, -0xaf,0x37,0x00,0x00,0x0e,0x00,0x25,0xfc,0x13,0x35,0xb3,0x37,0x00,0x00,0x0e,0x00, -0x26,0xfc,0x13,0x35,0xb7,0x37,0x00,0x00,0x0e,0x00,0x27,0xfc,0x13,0x35,0xbb,0x37, -0x00,0x00,0x0e,0x00,0x23,0xfc,0xe7,0x34,0x13,0x35,0x84,0x00,0x02,0x00,0x28,0xfc, -0xd7,0x37,0xe3,0x37,0x00,0x00,0x06,0x00,0x2a,0xfc,0xe7,0x34,0x13,0x35,0xfa,0x00, -0x02,0x00,0x2b,0xfc,0xe7,0x34,0xe3,0x34,0x78,0x01,0x02,0x00,0x2c,0xfc,0xe7,0x34, -0x11,0x38,0xd8,0x66,0x02,0x00,0x2d,0xfc,0xe7,0x34,0x02,0x38,0xaa,0x01,0x02,0x00, -0x2e,0xfc,0xe7,0x34,0x13,0x35,0xa8,0x66,0x02,0x00,0x3a,0xfc,0xe7,0x34,0x13,0x35, -0x06,0x67,0x04,0x00,0x80,0xfc,0x29,0x35,0x3c,0x35,0x5e,0x58,0xc0,0x00,0x81,0xfc, -0xe7,0x34,0x13,0x35,0x8c,0x01,0x02,0x00,0x82,0xfc,0xe7,0x34,0x13,0x35,0x8e,0x01, -0x02,0x00,0x83,0xfc,0xe7,0x34,0x13,0x35,0x90,0x01,0x02,0x00,0x84,0xfc,0xe7,0x34, -0x30,0x37,0x92,0x01,0x02,0x00,0x85,0xfc,0xe7,0x34,0x1c,0x37,0x1e,0x59,0x02,0x00, -0x87,0xfc,0xe7,0x34,0x13,0x35,0x7c,0x17,0x02,0x00,0x88,0xfc,0xe7,0x34,0x13,0x35, -0x7a,0x17,0x02,0x00,0x89,0xfc,0xe7,0x34,0x13,0x35,0x34,0x17,0x02,0x00,0x8a,0xfc, -0xe7,0x34,0x13,0x35,0xdc,0x17,0x02,0x00,0x8b,0xfc,0xe7,0x34,0x13,0x35,0x00,0x01, -0x02,0x00,0x8c,0xfc,0xe7,0x34,0x2d,0x38,0x7e,0x17,0x02,0x00,0xa5,0xfc,0xe7,0x34, -0x8a,0x37,0x74,0x17,0x02,0x00,0xa6,0xfc,0xcf,0x34,0x72,0x37,0x00,0x00,0x02,0x00, -0x18,0xfc,0xe7,0x34,0x13,0x35,0xbc,0x16,0x02,0x00,0xae,0xfc,0xe7,0x34,0x13,0x35, -0xbc,0x01,0x02,0x00,0x2f,0xfc,0xe7,0x34,0x13,0x35,0xac,0x01,0x02,0x00,0x30,0xfc, -0xcf,0x34,0x4b,0x38,0x00,0x00,0x14,0x00,0x31,0xfc,0xcf,0x34,0xae,0x38,0x00,0x00, -0x06,0x00,0x10,0xfd,0xe7,0x34,0xe3,0x34,0x4a,0x01,0x02,0x00,0x11,0xfd,0x81,0x36, -0xe3,0x34,0x4c,0xe8,0x0c,0x00,0x12,0xfd,0x81,0x36,0xe3,0x34,0x5a,0xe8,0x02,0x00, -0x13,0xfd,0x41,0x36,0xe3,0x34,0x00,0x04,0xe0,0x01,0x14,0xfd,0xe7,0x34,0xe3,0x34, -0x38,0x17,0x02,0x00,0x15,0xfd,0xe7,0x34,0xe3,0x34,0x82,0x17,0x24,0x00,0x16,0xfd, -0xe7,0x34,0xe3,0x34,0x60,0x17,0x10,0x00,0x17,0xfd,0xe7,0x34,0xe3,0x34,0x5c,0x17, -0x02,0x00,0x18,0xfd,0xe7,0x34,0xe3,0x34,0x76,0x17,0x04,0x00,0x1b,0xfd,0xe7,0x34, -0xe3,0x34,0x72,0x17,0x02,0x00,0x1c,0xfd,0xe7,0x34,0xe3,0x34,0x3e,0x00,0x02,0x00, -0x24,0xfd,0xe7,0x34,0xe3,0x34,0xaa,0x17,0x0c,0x00,0x25,0xfd,0xe7,0x34,0xe3,0x34, -0xb8,0x17,0x0c,0x00,0x26,0xfd,0x81,0x36,0xe3,0x34,0x74,0xe8,0x20,0x00,0x27,0xfd, -0x81,0x36,0xe3,0x34,0x94,0xe8,0x38,0x00,0x45,0xfd,0xe7,0x34,0xe3,0x34,0x00,0x01, -0x02,0x00,0x47,0xfd,0xe7,0x34,0xe3,0x34,0x4e,0x01,0x02,0x00,0x48,0xfd,0xa2,0x36, -0xe3,0x34,0x6c,0x01,0x02,0x00,0x49,0xfd,0xa2,0x36,0xe3,0x34,0x6e,0x01,0x02,0x00, -0x4a,0xfd,0xe7,0x34,0xe3,0x34,0xe0,0x17,0x02,0x00,0x4b,0xfd,0xe7,0x34,0xe3,0x34, -0xe2,0x17,0x02,0x00,0x4d,0xfd,0x81,0x36,0xe3,0x34,0x5c,0xe8,0x04,0x00,0x50,0xfd, -0xe7,0x34,0xe3,0x34,0xb2,0x59,0x12,0x00,0x4f,0xfd,0x81,0x36,0xe3,0x34,0x58,0xe8, -0x02,0x00,0xc0,0xfd,0x81,0x36,0xe3,0x34,0x60,0xe8,0x02,0x00,0xc1,0xfd,0xe7,0x34, -0xe3,0x34,0xfe,0x00,0x02,0x00,0xc2,0xfd,0xb0,0x36,0xe3,0x34,0x00,0x00,0x02,0x00, -0xc3,0xfd,0x81,0x36,0xe3,0x34,0x62,0xe8,0x02,0x00,0xc6,0xfd,0xe7,0x34,0xe3,0x34, -0xd2,0x17,0x0a,0x00,0x20,0xfd,0x68,0x36,0xe3,0x34,0x3a,0xe8,0x08,0x00,0x21,0xfd, -0x68,0x36,0xe3,0x34,0x42,0xe8,0x0a,0x00,0x22,0xfd,0x68,0x36,0xe3,0x34,0x1c,0xe8, -0x0a,0x00,0x23,0xfd,0x68,0x36,0xe3,0x34,0x30,0xe8,0x0a,0x00,0x40,0xfd,0xe7,0x34, -0xe3,0x34,0x96,0x01,0x02,0x00,0x41,0xfd,0xe7,0x34,0xe3,0x34,0x20,0x59,0x22,0x00, -0x42,0xfd,0xe7,0x34,0x0e,0x35,0x02,0x01,0x06,0x00,0x43,0xfd,0xcb,0x36,0xe3,0x34, -0x00,0x00,0x06,0x00,0x44,0xfd,0xc0,0x36,0xe3,0x34,0xa0,0x00,0x02,0x00,0x46,0xfd, -0xe7,0x34,0xe3,0x34,0x84,0x01,0x0c,0x00,0x4c,0xfd,0xe7,0x34,0xe3,0x34,0xca,0x18, -0x02,0x00,0x8d,0xfc,0xe7,0x34,0xe3,0x34,0x8e,0x00,0x02,0x00,0x8f,0xfc,0xe7,0x34, -0xe3,0x34,0x80,0x17,0x02,0x00,0xa7,0xfc,0xe7,0x34,0xe3,0x34,0xc6,0x66,0x04,0x00, -0xfe,0xff,0x81,0x36,0xe3,0x34,0x64,0xe8,0x02,0x00,0xff,0xff,0x81,0x36,0xe3,0x34, -0x66,0xe8,0x0e,0x00,0x00,0xf1,0x2a,0x00,0xc3,0x35,0x01,0xf1,0x80,0x08,0x92,0x35, -0x02,0xf1,0x80,0x08,0xca,0x35,0x03,0xf1,0x96,0x00,0x03,0x39,0x04,0xf1,0x90,0x1a, -0x05,0x36,0xd8,0x1a,0x91,0x19,0x96,0x19,0x5e,0x1a,0xb3,0x1a,0x0e,0x1a,0x6d,0x19, -0x16,0x1a,0x1e,0x1a,0xdb,0x19,0x59,0x19,0xca,0x1a,0xca,0x1a,0x30,0x24,0x5c,0x24, -0x59,0x24,0x7a,0x23,0x5c,0x24,0x5c,0x24,0x00,0x00,0x62,0x24,0x62,0x24,0x62,0x24, -0x00,0x00,0x00,0x00,0xec,0x24,0x05,0x25,0x7b,0x23,0x00,0x00,0x77,0x24,0x00,0x00, -0x00,0x00,0x9b,0x16,0x00,0x02,0x48,0x04,0x48,0x06,0x80,0x08,0x03,0x0a,0x04,0x0c, -0x04,0x0e,0x00,0x10,0xe4,0x12,0xbb,0x14,0x1b,0x16,0x00,0x18,0x00,0x1a,0x00,0x1c, -0x5c,0x1e,0xc1,0x20,0x20,0x22,0x74,0x24,0x07,0x26,0x0a,0x28,0x16,0x2a,0x00,0x2c, -0x00,0x2e,0x1c,0x30,0x20,0x32,0x98,0x34,0x08,0x36,0x7a,0x38,0x0a,0x3a,0x24,0x3c, -0xb2,0x3e,0x00,0x40,0x00,0x42,0x00,0x44,0x0c,0x46,0x26,0x48,0x5b,0x4a,0x7f,0x4c, -0x29,0x4e,0x0f,0x50,0x20,0x52,0x20,0x54,0x10,0x56,0x10,0x58,0x10,0x5a,0x10,0x5c, -0x1e,0x5e,0x1a,0x60,0x18,0x62,0x00,0x2c,0x0c,0x2e,0x01,0x2c,0x10,0x2e,0x02,0x2c, -0x14,0x2e,0x03,0x2c,0x18,0x2e,0x04,0x2c,0x1c,0x2e,0x05,0x2c,0x20,0x2e,0x06,0x2c, -0x24,0x2e,0x07,0x2c,0x28,0x2e,0x08,0x2c,0x2e,0x2e,0x09,0x2c,0x34,0x2e,0x0a,0x2c, -0x38,0x2e,0x0b,0x2c,0x3c,0x2e,0x0c,0x2c,0x3f,0x2e,0x0d,0x2c,0x43,0x2e,0x0e,0x2c, -0x46,0x2e,0x0f,0x2c,0x48,0x2e,0x10,0x2c,0x4b,0x2e,0x11,0x2c,0x50,0x2e,0x12,0x2c, -0x55,0x2e,0x13,0x2c,0x5a,0x2e,0x14,0x2c,0x63,0x2e,0x15,0x2c,0x6d,0x2e,0x16,0x2c, -0x76,0x2e,0x17,0x2c,0x7f,0x2e,0x18,0x2c,0x7f,0x2e,0x19,0x2c,0x7f,0x2e,0x1a,0x2c, -0x7f,0x2e,0x1b,0x2c,0x7f,0x2e,0x1c,0x2c,0x7f,0x2e,0x1d,0x2c,0x7f,0x2e,0x1e,0x2c, -0x7f,0x2e,0x1f,0x2c,0x7f,0x2e,0x00,0x02,0x01,0x04,0x38,0x06,0x80,0x08,0x03,0x0a, -0x04,0x0c,0x04,0x0e,0x00,0x10,0xa2,0x12,0xc8,0x14,0x1b,0x16,0x00,0x18,0x00,0x1a, -0x00,0x1c,0x5c,0x1e,0xc1,0x20,0x1e,0x22,0x54,0x24,0x07,0x26,0x6a,0x28,0x12,0x2a, -0x00,0x2c,0x00,0x2e,0x1c,0x30,0x20,0x32,0x82,0x34,0x08,0x36,0x7a,0x38,0xca,0x3a, -0x24,0x3c,0xb6,0x3e,0x00,0x40,0x00,0x42,0x00,0x44,0x7f,0x46,0x8b,0x48,0x0f,0x4a, -0x06,0x4c,0x0a,0x4e,0x0f,0x50,0x20,0x52,0x20,0x54,0x10,0x56,0x10,0x58,0x20,0x5a, -0xee,0x5c,0x1a,0x5e,0x26,0x60,0x5b,0x62,0x00,0x04,0x00,0x2c,0x0c,0x2e,0x01,0x2c, -0x10,0x2e,0x02,0x2c,0x14,0x2e,0x03,0x2c,0x18,0x2e,0x04,0x2c,0x1c,0x2e,0x05,0x2c, -0x20,0x2e,0x06,0x2c,0x24,0x2e,0x07,0x2c,0x28,0x2e,0x08,0x2c,0x2e,0x2e,0x09,0x2c, -0x34,0x2e,0x0a,0x2c,0x38,0x2e,0x0b,0x2c,0x3c,0x2e,0x0c,0x2c,0x3f,0x2e,0x0d,0x2c, -0x43,0x2e,0x0e,0x2c,0x46,0x2e,0x0f,0x2c,0x48,0x2e,0x10,0x2c,0x4b,0x2e,0x11,0x2c, -0x50,0x2e,0x12,0x2c,0x55,0x2e,0x13,0x2c,0x5a,0x2e,0x14,0x2c,0x63,0x2e,0x15,0x2c, -0x6d,0x2e,0x16,0x2c,0x76,0x2e,0x17,0x2c,0x7f,0x2e,0x18,0x2c,0x7f,0x2e,0x19,0x2c, -0x7f,0x2e,0x1a,0x2c,0x7f,0x2e,0x1b,0x2c,0x7f,0x2e,0x1c,0x2c,0x7f,0x2e,0x1d,0x2c, -0x7f,0x2e,0x1e,0x2c,0x7f,0x2e,0x1f,0x2c,0x7f,0x2e,0x00,0x00,0x04,0x00,0x65,0x00, -0x00,0x00,0x00,0x00,0x67,0x00,0x00,0x00,0x00,0x00,0xb0,0x00,0x00,0x00,0x5c,0x00, -0x32,0x00,0x00,0x00,0x04,0x00,0x65,0x00,0x00,0x00,0x00,0x00,0xb0,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x7e,0x00,0x5a,0x00,0x00,0x00,0x7e,0x00,0x6e,0x00, -0x00,0x00,0x80,0x00,0x02,0x00,0x00,0x00,0x80,0x00,0x16,0x00,0x00,0x00,0x80,0x00, -0x2a,0x00,0x00,0x00,0x80,0x00,0x3e,0x00,0x00,0x00,0x80,0x00,0x52,0x00,0x00,0x00, -0x80,0x00,0x66,0x00,0x00,0x00,0x80,0x00,0x7a,0x00,0x00,0x00,0x82,0x00,0x0e,0x00, -0x00,0x00,0x82,0x00,0x22,0x00,0x00,0x00,0x82,0x00,0x36,0x00,0x00,0x00,0x82,0x00, -0x4a,0x00,0x00,0x00,0x82,0x00,0x7a,0x00,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b, -0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x1b,0x3b,0x10,0x3b,0x10,0x3b,0x30,0x3b, -0x10,0x3b,0x10,0x3b,0x63,0x3b,0x71,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b, -0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b, -0x10,0x3b,0x10,0x3b,0x10,0x3b,0x10,0x3b,0xd5,0x3b,0x24,0x3c,0x49,0x3c,0x42,0x3c, -0x2e,0x3c,0x38,0x3c,0x10,0x3b,0x10,0x3b,0x10,0x3b,0x4b,0x3c,0x61,0x3c,0x68,0x3c, -0x12,0x00,0x02,0x00,0x72,0x0e,0x04,0x00,0x8b,0x0e,0x06,0x00,0x39,0x0f,0x08,0x00, -0x50,0x0f,0x0a,0x00,0x73,0x0f,0x0c,0x00,0x2e,0x10,0x12,0x00,0x3f,0x18,0x1a,0x00, -0x75,0x25,0x00,0x09,0x16,0x0c,0x02,0x09,0x22,0x33,0x04,0x09,0x2f,0x34,0x06,0x09, -0x72,0x34,0x14,0x09,0x34,0x31,0x16,0x09,0x50,0x31,0x42,0x09,0xb0,0x34,0x22,0x09, -0x82,0x34,0x64,0x09,0x7a,0x34,0x70,0x09,0x02,0x3b,0x03,0x00,0x00,0x00,0x53,0x70, -0x65,0x63,0x74,0x72,0x75,0x6d,0x32,0x34,0x2f,0x48,0x44,0x52,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x14,0x00, -0x6e,0x6f,0x6e,0x2d,0x73,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x20,0x53,0x53, -0x49,0x44,0x20,0x21,0x21,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x00,0x00,0x01,0x00,0x01,0x00,0x64,0x00,0x64,0x00,0x00,0x00,0x50,0x72,0x69,0x73, -0x6d,0x20,0x20,0x49,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x01,0x00,0x05,0x00,0x03,0x00,0x00,0x00,0x53,0x70,0x65,0x63, -0x74,0x72,0x75,0x6d,0x32,0x34,0x2f,0x48,0x44,0x52,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x14,0x00,0x6e,0x6f, -0x6e,0x2d,0x73,0x70,0x65,0x63,0x69,0x66,0x69,0x65,0x64,0x20,0x53,0x53,0x49,0x44, -0x20,0x21,0x21,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00, -0x01,0x00,0x01,0x00,0x64,0x00,0x64,0x00,0x00,0x00,0x50,0x72,0x69,0x73,0x6d,0x20, -0x20,0x49,0x00,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x00,0x00,0x80,0x01,0x2c,0x00, -0x01,0x00,0xb6,0x00,0xc0,0x00,0xd4,0x00,0xee,0x00,0xfe,0x00,0x00,0x00,0x00,0x00, -0x12,0x00,0x0f,0x00,0x0c,0x00,0x07,0x00,0x00,0x00,0x00,0x00,0x02,0x00,0x01,0x00, -0x03,0x00,0x03,0x00,0x7f,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x08,0x00,0x00,0x00,0x00,0x00,0x2a,0x1b, -0x20,0x1d,0x00,0x00,0x00,0x00,0x00,0x00,0x12,0x00,0x20,0x20,0x53,0x74,0x61,0x6e, -0x64,0x61,0x72,0x64,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x46,0x33,0x2e,0x31,0x30,0x2d,0x30,0x34,0x00,0x00,0x00,0x00,0x00,0x00, -0x30,0x31,0x2f,0x31,0x37,0x2f,0x32,0x30,0x30,0x32,0x00,0x00,0x00,0x00,0x01,0x00, -0x04,0x00,0x82,0x84,0x8b,0x96,0x00,0x00,0x00,0x00,0x04,0x00,0x02,0x04,0x0b,0x16, -0x00,0x00,0x00,0x00,0x0f,0x00,0x00,0x00,0x00,0x02,0x00,0x02,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00, -0x00,0x00,0x00,0x00,0x60,0x1f,0xe0,0x27,0x3f,0x3f,0x49,0x6e,0x74,0x27,0x6c,0x2d, -0x73,0x65,0x61,0x72,0x63,0x68,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20, -0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x20,0x7d,0x00, -0x04,0x00,0xfa,0x00,0xc8,0x00,0xf4,0x01,0x05,0x00,0x07,0x00,0xfa,0x00,0xc8,0x00, -0x2c,0x01,0x05,0x00,0x0a,0x00,0xfa,0x00,0x32,0x00,0x64,0x00,0x05,0x00,0x0a,0x00, -0xfa,0x00,0x32,0x00,0x32,0x00,0x05,0x00,0x0a,0x00,0xfa,0x00,0x19,0x00,0x19,0x00, -0x05,0x00,0x35,0x44,0x5d,0x65,0xf7,0x98,0xd9,0x6e,0x42,0xf7,0xb8,0x74,0xdc,0x15, -0xfc,0xf8,0x82,0x05,0x79,0xf3,0x09,0x59,0x97,0x30,0xee,0x53,0x7b,0x83,0x15,0x46, -0xbd,0x2c,0xd1,0x91,0x43,0x08,0x1e,0x7f,0xc9,0x60,0x53,0x68,0xf4,0xd2,0x88,0x06, -0x22,0x14,0x39,0x09,0xf5,0x9f,0x05,0x27,0x74,0xfe,0xec,0x75,0x1f,0x42,0xf2,0x0c, -0xae,0xb0,0x1b,0xfd,0xb5,0x76,0x03,0x39,0xfa,0x8f,0x7f,0x00,0xe0,0x04,0x35,0x2a, -0x7f,0x42,0x2f,0x45,0xd9,0xd4,0x49,0xe6,0xf8,0xd9,0x86,0xee,0x78,0x42,0xca,0x54, -0x39,0x10,0x17,0x89,0x15,0xfc,0xcd,0x61,0x9c,0x76,0xdc,0xbe,0x02,0x0a,0x46,0xb6, -0xea,0xad,0x47,0xaa,0x89,0x11,0x97,0xf1,0x0b,0xec,0x22,0x6d,0xf3,0x33,0xd3,0xef, -0x02,0x6f,0x58,0xb8,0x73,0x50,0x2a,0x8b,0xe8,0x3a,0x53,0xa8,0xe9,0x09,0xbf,0xbc, -0x57,0x47,0x83,0xdb,0x5e,0xb1,0x62,0x82,0x5c,0xb2,0x71,0x5f,0x23,0x67,0xfd,0xcb, -0xe0,0xd1,0x0d,0xe8,0xab,0x44,0x33,0x0f,0x4c,0x76,0x92,0x32,0x65,0xb1,0x7e,0xca, -0xed,0x21,0x5e,0x45,0xba,0x92,0xa4,0x67,0x67,0x9e,0x23,0x33,0x8e,0x6a,0xa1,0xe9, -0x94,0x3a,0x39,0xef,0x34,0xb3,0x65,0x96,0x3b,0x6e,0x46,0xbd,0xd0,0xc3,0x22,0x87, -0x54,0xad,0xbc,0x89,0xd6,0x3a,0x3a,0x99,0xe0,0x89,0x0e,0xcf,0xfe,0xa3,0x0a,0x1a, -0x68,0x6f,0xcb,0xd7,0xa6,0x25,0xd1,0x25,0x4d,0xc0,0x86,0xd8,0x9b,0xf7,0xe2,0xd5, -0xf7,0xa3,0x0c,0x33,0xe3,0x83,0x87,0xff,0x4c,0x9d,0xd6,0xd6,0x89,0x9a,0x0c,0x38, -0xa0,0xe8,0xef,0x52,0x1b,0x0e,0xbb,0x52,0xbc,0x9f,0xde,0xbf,0x1a,0xc8,0xf0,0xd0, -0xd9,0x54,0xc2,0x6c,0x53,0xa8,0x1b,0xc4,0x17,0x42,0x1d,0x51,0x2e,0xc8,0x8e,0xe7, -0x63,0x5c,0x00,0xd6,0xc5,0x0d,0xcd,0xeb,0xab,0x59,0x13,0xf3,0x02,0x82,0x0c,0x2c, -0x36,0x3c,0xe7,0x21,0xb8,0xf9,0x57,0x67,0xdd,0xae,0x1d,0x6e,0x39,0x06,0xe2,0xd2, -0x16,0x1f,0x8e,0x2c,0xec,0x5f,0x71,0xf1,0x01,0x8b,0x6b,0x52,0x72,0x04,0x49,0xa8, -0x8b,0xa7,0x27,0xe3,0x3c,0xfa,0x55,0x45,0x94,0x54,0xcc,0x68,0xc9,0xf9,0x35,0xa8, -0xa5,0x8c,0xa2,0x5c,0xb8,0x7f,0x24,0xe5,0x6e,0x15,0xe4,0xdd,0x97,0xf2,0xe8,0x84, -0xf9,0xcf,0x92,0x98,0x70,0x25,0x24,0xf3,0x6a,0x39,0x15,0x11,0xa0,0x40,0xa2,0x99, -0x58,0x7a,0xa2,0x9b,0x2a,0xb2,0x74,0xa4,0x7d,0x2d,0x7e,0x5e,0x0e,0xf5,0x59,0x37, -0xf6,0x50,0x9f,0x06,0xf3,0x0d,0x03,0x87,0xcc,0x18,0xb5,0xca,0x44,0xf1,0x57,0x55, -0xe2,0x5f,0x8c,0x82,0x6c,0x1e,0xb2,0x83,0x40,0x0f,0xef,0x6d,0x61,0x34,0x9d,0x8f, -0x68,0x59,0xcb,0x22,0x9b,0x29,0x55,0x1a,0x87,0x3f,0x64,0x22,0x4a,0xbd,0x6c,0x7c, -0x0e,0xc3,0x89,0x5d,0x2a,0x86,0xa2,0xb6,0xf5,0xa3,0xd8,0x36,0x90,0x08,0x95,0xee, -0xca,0xb4,0x95,0xcc,0xa1,0x8b,0x98,0xc7,0x48,0xfd,0xa7,0xce,0xd6,0xc5,0x3b,0x7a, -0x2e,0x3a,0x0e,0xf8,0x11,0x63,0xef,0xb5,0xd1,0x10,0xed,0x67,0xb7,0x25,0x26,0x23, -0x2d,0xdb,0x8b,0xf8,0x50,0x8d,0xd1,0x2c,0x32,0x14,0xe5,0x92,0xd8,0x88,0x31,0x82, -0x7c,0xa1,0x6e,0x59,0xf1,0x54,0xb7,0x6f,0xfa,0x00,0xe4,0x59,0xe8,0x59,0xec,0x59, -0xf0,0x59,0xf4,0x59,0x00,0x5a,0x04,0x5a,0x08,0x5a,0x14,0x5a,0x18,0x5a,0x3e,0x5a, -0x42,0x5a,0x46,0x5a,0x4a,0x5a,0x4e,0x5a,0x5a,0xda,0x3e,0x67,0x3e,0x67,0x3e,0x67, -0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x5c,0xda,0x5e,0x5a, -0x3e,0xe7,0x3e,0xe7,0x62,0x5a,0x66,0x5a,0x3e,0x67,0x70,0x5a,0x74,0x5a,0x78,0x5a, -0x7c,0x5a,0x88,0x5a,0x8c,0x5a,0x90,0x5a,0x9c,0x5a,0xa0,0x5a,0xca,0x5a,0xce,0x5a, -0xd2,0x5a,0xd6,0x5a,0xda,0x5a,0xe6,0x5a,0x3e,0x67,0x3e,0xe7,0xfa,0x5a,0xfe,0xda, -0x00,0xdb,0x02,0xdb,0x04,0xdb,0x06,0x5b,0x3e,0xe7,0x0a,0x5b,0x0e,0xdb,0x10,0xdb, -0x12,0xdb,0x14,0xdb,0x16,0xdb,0x18,0xdb,0x3e,0xe7,0x3e,0xe7,0x1a,0xdb,0x1c,0xdb, -0x1e,0xdb,0x20,0xdb,0x24,0x5b,0x28,0x5b,0x2c,0x5b,0x30,0x5b,0x34,0xdb,0x36,0xdb, -0x8e,0x59,0x92,0x59,0x9c,0xd9,0x9e,0xd9,0x3e,0xe7,0x88,0xd9,0x8a,0xd9,0x8c,0xd9, -0xa6,0xd9,0xa8,0xd9,0xaa,0xd9,0xb4,0xd9,0xb6,0xd9,0xbe,0xd9,0xa0,0xd9,0xa2,0xd9, -0xa4,0xd9,0xc0,0xd9,0xc2,0xd9,0xc4,0xd9,0xc6,0xd9,0xc8,0xd9,0xca,0xd9,0xd0,0xd9, -0xd2,0xd9,0xd4,0xd9,0xd6,0xd9,0xd8,0xd9,0xda,0xd9,0xdc,0xd9,0xde,0xd9,0xe0,0xd9, -0xe2,0xd9,0x6c,0xd9,0x6e,0xd9,0x46,0xd9,0x4a,0xd9,0x4c,0xd9,0x4e,0xd9,0x50,0xd9, -0x3e,0xe7,0x38,0x97,0x3e,0xe7,0x08,0x81,0x50,0x9e,0x5a,0xd9,0x5c,0xd9,0x3e,0xe7, -0x5e,0xd9,0x70,0xd9,0x72,0xd9,0x3e,0xe7,0x78,0xd9,0x7a,0xd9,0x7c,0xd9,0x7e,0xd9, -0x80,0xd9,0x82,0xd9,0x84,0xd9,0x86,0xd9,0x3a,0x5a,0x1c,0xda,0x1e,0xda,0x20,0xda, -0x22,0xda,0x24,0xda,0x26,0x5a,0x2a,0x5a,0x2e,0x5a,0x32,0x5a,0x36,0x5a,0xc6,0x5a, -0xa8,0xda,0xaa,0xda,0xac,0xda,0xae,0xda,0xb0,0xda,0xb2,0x5a,0xb6,0x5a,0xba,0x5a, -0xbe,0x5a,0xc2,0x5a,0xea,0x5a,0xee,0x5a,0xac,0xd9,0xae,0xd9,0xcc,0xd9,0xce,0xd9, -0x3e,0x67,0x42,0xd9,0x44,0xd9,0x38,0xdf,0x3e,0xe7,0x48,0xd9,0xa0,0x80,0x3e,0xe7, -0x3e,0xe7,0x60,0xd9,0x6a,0xda,0x3e,0xe7,0xb0,0xd9,0x3a,0xdf,0x64,0xd9,0x22,0xdb, -0x62,0xd9,0x66,0xd9,0x6c,0x5a,0x90,0x81,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67, -0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67, -0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67, -0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0x3e,0x67,0xbe,0xe6, -0xbc,0xe6,0xb8,0xd9,0xba,0xd9,0xce,0x98,0x5c,0xe4,0x60,0xe4,0x54,0xd9,0x56,0xd9, -0xf8,0x59,0xfc,0x59,0x0c,0x5a,0x10,0x5a,0x52,0x5a,0x56,0x5a,0x80,0x5a,0x84,0x5a, -0x94,0x5a,0x98,0x5a,0xde,0x5a,0xe2,0x5a,0xf2,0x5a,0xf6,0x5a,0x92,0x1e,0x68,0x59, -0x6a,0x59,0xc2,0xe1,0xc6,0xe1,0xfa,0x81,0x2c,0xbc,0x32,0xbc,0x38,0xbc,0x44,0xbc, -0x4a,0xbc,0x68,0xbc,0x6e,0xbc,0xcc,0x98,0xb0,0x80,0xb2,0x80,0xb4,0x80,0x11,0x00, -0x00,0x00,0x00,0x00,0xb6,0x16,0x06,0x00,0x01,0x00,0xb4,0x61,0x06,0x00,0x01,0x00, -0xbc,0x61,0x06,0x00,0x01,0x00,0x60,0x17,0x10,0x00,0x01,0x00,0x82,0x17,0x24,0x00, -0x01,0x00,0xaa,0x17,0x0e,0x00,0x01,0x00,0xc4,0x16,0x20,0x00,0x01,0x00,0x50,0x5b, -0xe8,0x03,0x14,0x00,0x3c,0x5f,0x78,0x00,0x14,0x00,0x62,0x64,0xc0,0x01,0x10,0x00, -0xd8,0x61,0x80,0x02,0x10,0x00,0x2a,0x67,0x38,0x00,0x07,0x00,0xa6,0x59,0x99,0x01, -0x01,0x00,0xaa,0x17,0x0e,0x00,0x01,0x00,0xb8,0x17,0x0e,0x00,0x01,0x00,0x02,0x01, -0x06,0x00,0x01,0x00,0x16,0x67,0x00,0x00,0x00,0x00,0x34,0x12,0xaa,0x55,0xe8,0x59, -0x02,0x00,0xec,0x59,0x02,0x00,0xf0,0x59,0x02,0x00,0xf4,0x59,0x02,0x00,0x00,0x5a, -0x02,0x00,0x04,0x5a,0x02,0x00,0x08,0x5a,0x02,0x00,0x42,0x5a,0x02,0x00,0x5a,0x5a, -0x01,0x00,0x70,0x5a,0x02,0x00,0x74,0x5a,0x02,0x00,0x78,0x5a,0x02,0x00,0x7c,0x5a, -0x02,0x00,0x88,0x5a,0x02,0x00,0x8c,0x5a,0x02,0x00,0x90,0x5a,0x02,0x00,0x9c,0x5a, -0x02,0x00,0xce,0x5a,0x02,0x00,0x9c,0x59,0x01,0x00,0x9e,0x59,0x01,0x00,0x3e,0x67, -0x01,0x00,0x8a,0x59,0x01,0x00,0xa6,0x59,0x01,0x00,0xb4,0x59,0x01,0x00,0xb6,0x59, -0x01,0x00,0xc0,0x59,0x01,0x00,0xc2,0x59,0x01,0x00,0xc4,0x59,0x01,0x00,0xc6,0x59, -0x01,0x00,0xc8,0x59,0x01,0x00,0xca,0x59,0x01,0x00,0x6c,0x59,0x01,0x00,0x46,0x59, -0x01,0x00,0x3e,0x67,0x01,0x00,0x38,0x17,0x01,0x00,0xfe,0x00,0x01,0x00,0xa0,0x00, -0x01,0x00,0xf8,0x59,0x02,0x00,0xfc,0x59,0x02,0x00,0x0c,0x5a,0x02,0x00,0x10,0x5a, -0x02,0x00,0x80,0x5a,0x02,0x00,0x84,0x5a,0x02,0x00,0x94,0x5a,0x02,0x00,0x98,0x5a, -0x02,0x00,0xcc,0x18,0x01,0x00,0xb0,0x00,0x01,0x00,0x00,0x00,0x00,0x00,0xff,0xff, -0xff,0xff,0x66,0xe8,0x7e,0x00,0x0e,0x00,0x00,0x00,0x01,0x01,0x00,0x00,0x40,0x8d, -0x7f,0x00,0x06,0x00,0x00,0x00,0x08,0x01,0x00,0x00,0xe8,0x8d,0x7f,0x00,0x12,0x00, -0x00,0x00,0x09,0x01,0x00,0x00,0xe6,0x8d,0x7f,0x00,0x02,0x00,0x00,0x00,0x0a,0x01, -0x00,0x00,0xc2,0x8d,0x7f,0x00,0x02,0x00,0x00,0x00,0x0b,0x01,0x00,0x00,0x0c,0x8e, -0x7f,0x00,0x24,0x00,0x00,0x00,0x03,0x01,0x00,0x00,0x4c,0xe8,0x7e,0x00,0x0c,0x00, -0x00,0x00,0x04,0x01,0x00,0x00,0x0a,0x81,0x7f,0x00,0x02,0x00,0x00,0x00,0x05,0x01, -0x00,0x00,0x46,0x8d,0x7f,0x00,0x02,0x00,0x00,0x00,0x05,0x01,0x00,0x00,0x40,0x81, -0x7f,0x00,0x02,0x00,0x00,0x00,0x05,0x01,0x00,0x00,0x50,0x8e,0x7f,0x00,0x02,0x00, -0x00,0x00,0x06,0x01,0x00,0x00,0x58,0xe8,0x7e,0x00,0x02,0x00,0x00,0x00,0x07,0x01, -0x00,0x00,0x5a,0xe8,0x7e,0x00,0x02,0x00,0x00,0x00,0x06,0x00,0x00,0x00,0x26,0xe8, -0x7e,0x00,0x0a,0x00,0x00,0x00,0x09,0x00,0x00,0x00,0xbe,0x8d,0x7f,0x00,0x02,0x00, -0x00,0x00,0x0a,0x00,0x00,0x00,0xc0,0x8d,0x7f,0x00,0x02,0x00,0x00,0x00,0x0c,0x01, -0x00,0x00,0x38,0x81,0x7f,0x00,0x02,0x00,0x00,0x00,0x0d,0x01,0x00,0x00,0xc4,0x8d, -0x7f,0x00,0x02,0x00,0x00,0x00,0x0e,0x01,0x00,0x00,0xfa,0x8d,0x7f,0x00,0x02,0x00, -0x00,0x00,0x11,0x01,0x00,0x00,0xfc,0x8d,0x7f,0x00,0x02,0x00,0x00,0x00,0x00,0x18, -0x7e,0x00,0xce,0xd0,0x00,0x00,0x01,0x00,0x00,0x00,0x05,0x00,0x01,0x00,0x21,0x00, -0x02,0x00,0x02,0x00,0x01,0x00,0x06,0x00,0x02,0x00,0x00,0x00,0x04,0x00,0x02,0x00, -0x01,0x00,0x01,0x00,0x06,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00,0x01,0x00, -0x01,0x00,0x06,0x00,0x02,0x00,0x01,0x00,0x02,0x00,0x01,0x00,0x01,0x00,0x01,0x00, -0x5a,0xd7 -}; - -#endif /* _FIRMWARE_WI_SPECTRUM24T_CF_H_ */ diff --git a/sys/dev/wpi/if_wpi.c b/sys/dev/wpi/if_wpi.c index 7df317b..f801493 100644 --- a/sys/dev/wpi/if_wpi.c +++ b/sys/dev/wpi/if_wpi.c @@ -152,6 +152,11 @@ static const struct wpi_ident wpi_ident_table[] = { { 0, 0, 0, NULL } }; +static struct ieee80211vap *wpi_vap_create(struct ieee80211com *, + const char name[IFNAMSIZ], int unit, int opmode, + int flags, const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]); +static void wpi_vap_delete(struct ieee80211vap *); static int wpi_dma_contig_alloc(struct wpi_softc *, struct wpi_dma_info *, void **, bus_size_t, bus_size_t, int); static void wpi_dma_contig_free(struct wpi_dma_info *); @@ -166,8 +171,7 @@ static int wpi_alloc_tx_ring(struct wpi_softc *, struct wpi_tx_ring *, static void wpi_reset_tx_ring(struct wpi_softc *, struct wpi_tx_ring *); static void wpi_free_tx_ring(struct wpi_softc *, struct wpi_tx_ring *); static struct ieee80211_node *wpi_node_alloc(struct ieee80211_node_table *); -static int wpi_media_change(struct ifnet *); -static int wpi_newstate(struct ieee80211com *, enum ieee80211_state, int); +static int wpi_newstate(struct ieee80211vap *, enum ieee80211_state, int); static void wpi_mem_lock(struct wpi_softc *); static void wpi_mem_unlock(struct wpi_softc *); static uint32_t wpi_mem_read(struct wpi_softc *, uint16_t); @@ -193,11 +197,14 @@ static void wpi_watchdog(void *); static int wpi_tx_data(struct wpi_softc *, struct mbuf *, struct ieee80211_node *, int); static void wpi_start(struct ifnet *); +static void wpi_start_locked(struct ifnet *); +static int wpi_raw_xmit(struct ieee80211_node *, struct mbuf *, + const struct ieee80211_bpf_params *); static void wpi_scan_start(struct ieee80211com *); static void wpi_scan_end(struct ieee80211com *); static void wpi_set_channel(struct ieee80211com *); -static void wpi_scan_curchan(struct ieee80211com *, unsigned long); -static void wpi_scan_mindwell(struct ieee80211com *); +static void wpi_scan_curchan(struct ieee80211_scan_state *, unsigned long); +static void wpi_scan_mindwell(struct ieee80211_scan_state *); static int wpi_ioctl(struct ifnet *, u_long, caddr_t); static void wpi_read_eeprom(struct wpi_softc *); static void wpi_read_eeprom_channels(struct wpi_softc *, int); @@ -210,8 +217,8 @@ static void wpi_enable_tsf(struct wpi_softc *, struct ieee80211_node *); #if 0 static int wpi_setup_beacon(struct wpi_softc *, struct ieee80211_node *); #endif -static int wpi_auth(struct wpi_softc *); -static int wpi_run(struct wpi_softc *); +static int wpi_auth(struct wpi_softc *, struct ieee80211vap *); +static int wpi_run(struct wpi_softc *, struct ieee80211vap *); static int wpi_scan(struct wpi_softc *); static int wpi_config(struct wpi_softc *); static void wpi_stop_master(struct wpi_softc *); @@ -222,7 +229,6 @@ static void wpi_init(void *); static void wpi_init_locked(struct wpi_softc *, int); static void wpi_stop(struct wpi_softc *); static void wpi_stop_locked(struct wpi_softc *); -static void wpi_iter_func(void *, struct ieee80211_node *); static void wpi_newassoc(struct ieee80211_node *, int); static int wpi_set_txpower(struct wpi_softc *, struct ieee80211_channel *, @@ -301,7 +307,7 @@ wpi_probe(device_t dev) static int wpi_load_firmware(struct wpi_softc *sc) { - const struct firmware *fp ; + const struct firmware *fp; struct wpi_dma_info *dma = &sc->fw_dma; const struct wpi_firmware_hdr *hdr; const uint8_t *itext, *idata, *rtext, *rdata, *btext; @@ -476,7 +482,7 @@ wpi_attach(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); struct ifnet *ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic; int ac, error, supportsa = 1; uint32_t tmp; const struct wpi_ident *ident; @@ -499,7 +505,6 @@ wpi_attach(device_t dev) } } -#if __FreeBSD_version >= 700000 /* * Create the taskqueues used by the driver. Primarily * sc_tq handles most the task @@ -508,9 +513,6 @@ wpi_attach(device_t dev) taskqueue_thread_enqueue, &sc->sc_tq); taskqueue_start_threads(&sc->sc_tq, 1, PI_NET, "%s taskq", device_get_nameunit(dev)); -#else -#error "Sorry, this driver is not yet ready for FreeBSD < 7.0" -#endif /* Create the tasks that can be queued */ TASK_INIT(&sc->sc_opstask, 0, wpi_ops, sc); @@ -607,17 +609,17 @@ wpi_attach(device_t dev) goto fail; } - ifp = sc->sc_ifp = if_alloc(IFT_ETHER); + ifp = sc->sc_ifp = if_alloc(IFT_IEEE80211); if (ifp == NULL) { device_printf(dev, "can not if_alloc()\n"); error = ENOMEM; goto fail; } + ic = ifp->if_l2com; ic->ic_ifp = ifp; - ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ - ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ - ic->ic_state = IEEE80211_S_INIT; + ic->ic_phytype = IEEE80211_T_OFDM; /* not only, but not used */ + ic->ic_opmode = IEEE80211_M_STA; /* default to BSS mode */ /* set device capabilities */ ic->ic_caps = @@ -663,11 +665,12 @@ wpi_attach(device_t dev) IFQ_SET_MAXLEN(&ifp->if_snd, IFQ_MAXLEN); ifp->if_snd.ifq_drv_maxlen = IFQ_MAXLEN; IFQ_SET_READY(&ifp->if_snd); - ieee80211_ifattach(ic); + ieee80211_ifattach(ic); /* override default methods */ ic->ic_node_alloc = wpi_node_alloc; ic->ic_newassoc = wpi_newassoc; + ic->ic_raw_xmit = wpi_raw_xmit; ic->ic_wme.wme_update = wpi_wme_update; ic->ic_scan_start = wpi_scan_start; ic->ic_scan_end = wpi_scan_end; @@ -675,21 +678,11 @@ wpi_attach(device_t dev) ic->ic_scan_curchan = wpi_scan_curchan; ic->ic_scan_mindwell = wpi_scan_mindwell; - /* override state transition machine */ - sc->sc_newstate = ic->ic_newstate; - ic->ic_newstate = wpi_newstate; - ieee80211_media_init(ic, wpi_media_change, ieee80211_media_status); + ic->ic_vap_create = wpi_vap_create; + ic->ic_vap_delete = wpi_vap_delete; - ieee80211_amrr_init(&sc->amrr, ic, - IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, - IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD); - - /* whilst ieee80211_ifattach will listen for ieee80211 frames, - * we also want to listen for the lower level radio frames - */ - bpfattach2(ifp, DLT_IEEE802_11_RADIO, - sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap), - &sc->sc_drvbpf); + bpfattach(ifp, DLT_IEEE802_11_RADIO, + sizeof (struct ieee80211_frame) + sizeof (sc->sc_txtap)); sc->sc_rxtap_len = sizeof sc->sc_rxtap; sc->sc_rxtap.wr_ihdr.it_len = htole16(sc->sc_rxtap_len); @@ -714,7 +707,6 @@ wpi_attach(device_t dev) #ifdef XXX_DEBUG ieee80211_announce_channels(ic); #endif - return 0; fail: wpi_detach(dev); @@ -725,8 +717,8 @@ static int wpi_detach(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int ac; if (ifp != NULL) { @@ -774,6 +766,48 @@ wpi_detach(device_t dev) return 0; } +static struct ieee80211vap * +wpi_vap_create(struct ieee80211com *ic, + const char name[IFNAMSIZ], int unit, int opmode, int flags, + const uint8_t bssid[IEEE80211_ADDR_LEN], + const uint8_t mac[IEEE80211_ADDR_LEN]) +{ + struct wpi_vap *wvp; + struct ieee80211vap *vap; + + if (!TAILQ_EMPTY(&ic->ic_vaps)) /* only one at a time */ + return NULL; + wvp = (struct wpi_vap *) malloc(sizeof(struct wpi_vap), + M_80211_VAP, M_NOWAIT | M_ZERO); + if (wvp == NULL) + return NULL; + vap = &wvp->vap; + ieee80211_vap_setup(ic, vap, name, unit, opmode, flags, bssid, mac); + /* override with driver methods */ + wvp->newstate = vap->iv_newstate; + vap->iv_newstate = wpi_newstate; + + ieee80211_amrr_init(&wvp->amrr, vap, + IEEE80211_AMRR_MIN_SUCCESS_THRESHOLD, + IEEE80211_AMRR_MAX_SUCCESS_THRESHOLD, + 500 /*ms*/); + + /* complete setup */ + ieee80211_vap_attach(vap, ieee80211_media_change, ieee80211_media_status); + ic->ic_opmode = opmode; + return vap; +} + +static void +wpi_vap_delete(struct ieee80211vap *vap) +{ + struct wpi_vap *wvp = WPI_VAP(vap); + + ieee80211_amrr_cleanup(&wvp->amrr); + ieee80211_vap_detach(vap); + free(wvp, M_80211_VAP); +} + static void wpi_dma_map_addr(void *arg, bus_dma_segment_t *segs, int nsegs, int error) { @@ -1195,7 +1229,7 @@ static int wpi_resume(device_t dev) { struct wpi_softc *sc = device_get_softc(dev); - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; pci_write_config(dev, 0x41, 0, 1); @@ -1213,72 +1247,43 @@ wpi_node_alloc(struct ieee80211_node_table *ic) { struct wpi_node *wn; - wn = malloc(sizeof (struct wpi_node), M_80211_NODE, M_NOWAIT |M_ZERO); + wn = malloc(sizeof (struct wpi_node), M_80211_NODE, M_NOWAIT | M_ZERO); return &wn->ni; } -static int -wpi_media_change(struct ifnet *ifp) -{ - int error; - - error = ieee80211_media_change(ifp); - if (error != ENETRESET) - return error; - - if ((ifp->if_flags & IFF_UP) && (ifp->if_drv_flags & IFF_DRV_RUNNING)) - wpi_init(ifp->if_softc); - - return 0; -} - /** * Called by net80211 when ever there is a change to 80211 state machine */ static int -wpi_newstate(struct ieee80211com *ic, enum ieee80211_state nstate, int arg) +wpi_newstate(struct ieee80211vap *vap, enum ieee80211_state nstate, int arg) { + struct wpi_vap *wvp = WPI_VAP(vap); + struct ieee80211com *ic = vap->iv_ic; struct ifnet *ifp = ic->ic_ifp; struct wpi_softc *sc = ifp->if_softc; + int error; - DPRINTF(("%s: %s -> %s\n", __func__, - ieee80211_state_name[ic->ic_state], - ieee80211_state_name[nstate])); - - switch (nstate) { - case IEEE80211_S_SCAN: - /* - * Scanning is handled in net80211 via the scan_start, - * scan_end, scan_curchan functions. Hence all we do when - * changing to the SCAN state is update the leds - */ - - /* make the link LED blink while we're scanning */ - wpi_set_led(sc, WPI_LED_LINK, 20, 2); - break; + DPRINTF(("%s: %s -> %s flags 0x%x\n", __func__, + ieee80211_state_name[vap->iv_state], + ieee80211_state_name[nstate], sc->flags)); - case IEEE80211_S_AUTH: + if (nstate == IEEE80211_S_AUTH) { /* Delay the auth transition until we can update the firmware */ - return wpi_queue_cmd(sc, WPI_AUTH, arg, WPI_QUEUE_NORMAL); - - case IEEE80211_S_RUN: - if (ic->ic_opmode == IEEE80211_M_MONITOR) { - /* link LED blinks while monitoring */ - wpi_set_led(sc, WPI_LED_LINK, 5, 5); - break; - } - if (ic->ic_state != IEEE80211_S_RUN) - /* set the association id first */ - return wpi_queue_cmd(sc, WPI_RUN, arg, - WPI_QUEUE_NORMAL); - break; - - default: - break; + error = wpi_queue_cmd(sc, WPI_AUTH, arg, WPI_QUEUE_NORMAL); + return (error != 0 ? error : EINPROGRESS); } - - return sc->sc_newstate(ic, nstate, arg); + if (nstate == IEEE80211_S_RUN && vap->iv_state != IEEE80211_S_RUN) { + /* set the association id first */ + error = wpi_queue_cmd(sc, WPI_RUN, arg, WPI_QUEUE_NORMAL); + return (error != 0 ? error : EINPROGRESS); + } + if (nstate == IEEE80211_S_RUN) { + /* RUN -> RUN transition; just restart the timers */ + wpi_calib_timeout(sc); + /* XXX split out rate control timer */ + } + return wvp->newstate(vap, nstate, arg); } /* @@ -1431,8 +1436,8 @@ static void wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc, struct wpi_rx_data *data) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_rx_ring *ring = &sc->rxq; struct wpi_rx_stat *stat; struct wpi_rx_head *head; @@ -1490,7 +1495,7 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc, /* update Rx descriptor */ ring->desc[ring->cur] = htole32(paddr); - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct wpi_rx_radiotap_header *tap = &sc->sc_rxtap; tap->wr_flags = 0; @@ -1523,27 +1528,25 @@ wpi_rx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc, if (le16toh(head->flags) & 0x4) tap->wr_flags |= IEEE80211_RADIOTAP_F_SHORTPRE; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_rxtap_len, m); + bpf_mtap2(ifp->if_bpf, tap, sc->sc_rxtap_len, m); } WPI_UNLOCK(sc); - /* XXX frame length > sizeof(struct ieee80211_frame_min)? */ - /* grab a reference to the source node */ ni = ieee80211_find_rxnode(ic, mtod(m, struct ieee80211_frame_min *)); + if (ni != NULL) { + (void) ieee80211_input(ni, m, stat->rssi, 0, 0); + ieee80211_free_node(ni); + } else + (void) ieee80211_input_all(ic, m, stat->rssi, 0, 0); - /* send the frame to the 802.11 layer */ - ieee80211_input(ic, m, ni, stat->rssi, 0, 0); - - /* release node reference */ - ieee80211_free_node(ni); WPI_LOCK(sc); } static void wpi_tx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc) { - struct ifnet *ifp = sc->sc_ic.ic_ifp; + struct ifnet *ifp = sc->sc_ifp; struct wpi_tx_ring *ring = &sc->txq[desc->qid & 0x3]; struct wpi_tx_data *txdata = &ring->data[desc->idx]; struct wpi_tx_stat *stat = (struct wpi_tx_stat *)(desc + 1); @@ -1584,7 +1587,7 @@ wpi_tx_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc) sc->sc_tx_timer = 0; ifp->if_drv_flags &= ~IFF_DRV_OACTIVE; - wpi_start(ifp); + wpi_start_locked(ifp); } static void @@ -1617,8 +1620,8 @@ wpi_cmd_intr(struct wpi_softc *sc, struct wpi_rx_desc *desc) static void wpi_notif_intr(struct wpi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_rx_desc *desc; struct wpi_rx_data *data; uint32_t hw; @@ -1698,28 +1701,30 @@ wpi_notif_intr(struct wpi_softc *sc) { struct wpi_stop_scan *scan = (struct wpi_stop_scan *)(desc + 1); + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); DPRINTFN(WPI_DEBUG_SCANNING, ("scan finished nchan=%d status=%d chan=%d\n", scan->nchan, scan->status, scan->chan)); sc->sc_scan_timer = 0; - ieee80211_scan_next(ic); + ieee80211_scan_next(vap); break; } case WPI_MISSED_BEACON: { - struct wpi_missed_beacon *beacon = + struct wpi_missed_beacon *beacon = (struct wpi_missed_beacon *)(desc + 1); - - if (le32toh(beacon->consecutive) >= - ic->ic_bmissthreshold) { - DPRINTF(("Beacon miss: %u >= %u\n", - le32toh(beacon->consecutive), - ic->ic_bmissthreshold)); - ieee80211_beacon_miss(ic); - } - break; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + + if (le32toh(beacon->consecutive) >= + vap->iv_bmissthreshold) { + DPRINTF(("Beacon miss: %u >= %u\n", + le32toh(beacon->consecutive), + vap->iv_bmissthreshold)); + ieee80211_beacon_miss(ic); + } + break; } } @@ -1811,7 +1816,9 @@ static int wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, int ac) { - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211vap *vap = ni->ni_vap; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct chanAccParams *cap = &ic->ic_wme.wme_chanParams; struct wpi_tx_ring *ring = &sc->txq[ac]; struct wpi_tx_desc *desc; @@ -1819,6 +1826,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, struct wpi_tx_cmd *cmd; struct wpi_cmd_data *tx; struct ieee80211_frame *wh; + const struct ieee80211_txparam *tp; struct ieee80211_key *k; struct mbuf *mnew; int i, error, nsegs, rate, hdrlen, ismcast; @@ -1833,7 +1841,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, ismcast = IEEE80211_IS_MULTICAST(wh->i_addr1); if (wh->i_fc[1] & IEEE80211_FC1_WEP) { - k = ieee80211_crypto_encap(ic, ni, m0); + k = ieee80211_crypto_encap(ni, m0); if (k == NULL) { m_freem(m0); return ENOBUFS; @@ -1850,7 +1858,7 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, tx = (struct wpi_cmd_data *)cmd->data; tx->flags = htole32(WPI_TX_AUTO_SEQ); - tx->timeout= htole16(0); + tx->timeout = htole16(0); tx->ofdm_mask = 0xff; tx->cck_mask = 0x0f; tx->lifetime = htole32(WPI_LIFETIME_INFINITE); @@ -1861,40 +1869,42 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, if ((ni->ni_flags & IEEE80211_NODE_QOS) == 0 || !cap->cap_wmeParams[ac].wmep_noackPolicy) tx->flags |= htole32(WPI_TX_NEED_ACK); - if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > ic->ic_rtsthreshold) { + if (m0->m_pkthdr.len + IEEE80211_CRC_LEN > vap->iv_rtsthreshold) { tx->flags |= htole32(WPI_TX_NEED_RTS|WPI_TX_FULL_TXOP); tx->rts_ntries = 7; } } - /* pick a rate */ - if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MASK) { + tp = &vap->iv_txparms[ieee80211_chan2mode(ni->ni_chan)]; + if ((wh->i_fc[0] & IEEE80211_FC0_TYPE_MASK) == IEEE80211_FC0_TYPE_MGT) { uint8_t subtype = wh->i_fc[0] & IEEE80211_FC0_SUBTYPE_MASK; /* tell h/w to set timestamp in probe responses */ if (subtype == IEEE80211_FC0_SUBTYPE_PROBE_RESP) tx->flags |= htole32(WPI_TX_INSERT_TSTAMP); - if (subtype == IEEE80211_FC0_SUBTYPE_ASSOC_REQ || subtype == IEEE80211_FC0_SUBTYPE_REASSOC_REQ) tx->timeout = htole16(3); else tx->timeout = htole16(2); - - rate = ni->ni_rates.rs_rates[0] & IEEE80211_RATE_VAL; + rate = tp->mgmtrate; } else if (ismcast) { - rate = ic->ic_mcast_rate; - } else if (ic->ic_fixed_rate != IEEE80211_FIXED_RATE_NONE) { - rate = ic->ic_fixed_rate; + rate = tp->mcastrate; + } else if (tp->ucastrate != IEEE80211_FIXED_RATE_NONE) { + rate = tp->ucastrate; } else { - rate = ni->ni_rates.rs_rates[ni->ni_txrate]; - rate &= IEEE80211_RATE_VAL; + (void) ieee80211_amrr_choose(ni, &WPI_NODE(ni)->amn); + rate = ni->ni_txrate; } tx->rate = wpi_plcp_signal(rate); /* be very persistant at sending frames out */ - tx->data_ntries = 15; /* XXX Way too high */ +#if 0 + tx->data_ntries = tp->maxretry; +#else + tx->data_ntries = 15; /* XXX way too high */ +#endif - if (bpf_peers_present(sc->sc_drvbpf)) { + if (bpf_peers_present(ifp->if_bpf)) { struct wpi_tx_radiotap_header *tap = &sc->sc_txtap; tap->wt_flags = 0; tap->wt_chan_freq = htole16(ni->ni_chan->ic_freq); @@ -1903,7 +1913,8 @@ wpi_tx_data(struct wpi_softc *sc, struct mbuf *m0, struct ieee80211_node *ni, tap->wt_hwqueue = ac; if (wh->i_fc[1] & IEEE80211_FC1_WEP) tap->wt_flags |= IEEE80211_RADIOTAP_F_WEP; - bpf_mtap2(sc->sc_drvbpf, tap, sc->sc_txtap_len, m0); + + bpf_mtap2(ifp->if_bpf, tap, sc->sc_txtap_len, m0); } /* save and trim IEEE802.11 header */ @@ -1976,139 +1987,126 @@ static void wpi_start(struct ifnet *ifp) { struct wpi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; + + WPI_LOCK(sc); + wpi_start_locked(ifp); + WPI_UNLOCK(sc); +} + +static void +wpi_start_locked(struct ifnet *ifp) +{ + struct wpi_softc *sc = ifp->if_softc; struct ieee80211_node *ni; - struct ether_header *eh; - struct mbuf *m0; - int ac, waslocked; + struct mbuf *m; + int ac; + + WPI_LOCK_ASSERT(sc); if ((ifp->if_drv_flags & IFF_DRV_RUNNING) == 0) return; - waslocked = WPI_LOCK_OWNED(sc); - if (!waslocked) - WPI_LOCK(sc); - for (;;) { - IF_DEQUEUE(&ic->ic_mgtq, m0); - if (m0 != NULL) { - ni = (struct ieee80211_node *)m0->m_pkthdr.rcvif; - m0->m_pkthdr.rcvif = NULL; - - /* management frames go into ring 0 */ - if (sc->txq[0].queued > sc->txq[0].count - 8) { - ifp->if_oerrors++; - continue; - } - - if (wpi_tx_data(sc, m0, ni, 0) != 0) { - ifp->if_oerrors++; - break; - } - } else { - if (ic->ic_state != IEEE80211_S_RUN) - break; - - IFQ_DRV_DEQUEUE(&ifp->if_snd, m0); - if (m0 == NULL) - break; - - /* - * Cancel any background scan. - */ - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_cancel_scan(ic); - - if (m0->m_len < sizeof (*eh) && - (m0 = m_pullup(m0, sizeof (*eh))) != NULL) { - ifp->if_oerrors++; - continue; - } - eh = mtod(m0, struct ether_header *); - ni = ieee80211_find_txnode(ic, eh->ether_dhost); - if (ni == NULL) { - m_freem(m0); - ifp->if_oerrors++; - continue; - } - - /* classify mbuf so we can find which tx ring to use */ - if (ieee80211_classify(ic, m0, ni) != 0) { - m_freem(m0); - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - - ac = M_WME_GETAC(m0); - if (sc->txq[ac].queued > sc->txq[ac].count - 8) { - /* there is no place left in this ring */ - IFQ_DRV_PREPEND(&ifp->if_snd, m0); - ifp->if_drv_flags |= IFF_DRV_OACTIVE; - break; - } - - BPF_MTAP(ifp, m0); - - m0 = ieee80211_encap(ic, m0, ni); - if (m0 == NULL) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - continue; - } - - if (bpf_peers_present(ic->ic_rawbpf)) - bpf_mtap(ic->ic_rawbpf, m0); - - if (wpi_tx_data(sc, m0, ni, ac) != 0) { - ieee80211_free_node(ni); - ifp->if_oerrors++; - break; - } + IFQ_POLL(&ifp->if_snd, m); + if (m == NULL) + break; + /* no QoS encapsulation for EAPOL frames */ + ac = M_WME_GETAC(m); + if (sc->txq[ac].queued > sc->txq[ac].count - 8) { + /* there is no place left in this ring */ + IFQ_DRV_PREPEND(&ifp->if_snd, m); + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + break; + } + IFQ_DRV_DEQUEUE(&ifp->if_snd, m); + ni = (struct ieee80211_node *) m->m_pkthdr.rcvif; + m = ieee80211_encap(ni, m); + if (m == NULL) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + continue; + } + if (wpi_tx_data(sc, m, ni, ac) != 0) { + ieee80211_free_node(ni); + ifp->if_oerrors++; + break; } - sc->sc_tx_timer = 5; - ic->ic_lastdata = ticks; } +} - if (!waslocked) +static int +wpi_raw_xmit(struct ieee80211_node *ni, struct mbuf *m, + const struct ieee80211_bpf_params *params) +{ + struct ieee80211com *ic = ni->ni_ic; + struct ifnet *ifp = ic->ic_ifp; + struct wpi_softc *sc = ifp->if_softc; + + /* prevent management frames from being sent if we're not ready */ + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { + m_freem(m); + ieee80211_free_node(ni); + return ENETDOWN; + } + WPI_LOCK(sc); + + /* management frames go into ring 0 */ + if (sc->txq[0].queued > sc->txq[0].count - 8) { + ifp->if_drv_flags |= IFF_DRV_OACTIVE; + m_freem(m); WPI_UNLOCK(sc); + ieee80211_free_node(ni); + return ENOBUFS; /* XXX */ + } + + ifp->if_opackets++; + if (wpi_tx_data(sc, m, ni, 0) != 0) + goto bad; + sc->sc_tx_timer = 5; + callout_reset(&sc->watchdog_to, hz, wpi_watchdog, sc); + + WPI_UNLOCK(sc); + return 0; +bad: + ifp->if_oerrors++; + WPI_UNLOCK(sc); + ieee80211_free_node(ni); + return EIO; /* XXX */ } static int wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) { struct wpi_softc *sc = ifp->if_softc; - struct ieee80211com *ic = &sc->sc_ic; - int error = 0; + struct ieee80211com *ic = ifp->if_l2com; + struct ifreq *ifr = (struct ifreq *) data; + int error = 0, startall = 0; WPI_LOCK(sc); - switch (cmd) { case SIOCSIFFLAGS: if ((ifp->if_flags & IFF_UP)) { - if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) + if (!(ifp->if_drv_flags & IFF_DRV_RUNNING)) { wpi_init_locked(sc, 0); + startall = 1; + } } else if ((ifp->if_drv_flags & IFF_DRV_RUNNING) || (sc->flags & WPI_FLAG_HW_RADIO_OFF)) wpi_stop_locked(sc); break; + case SIOCGIFMEDIA: + case SIOCSIFMEDIA: + error = ifmedia_ioctl(ifp, ifr, &ic->ic_media, cmd); + break; default: - WPI_UNLOCK(sc); - error = ieee80211_ioctl(ic, cmd, data); - WPI_LOCK(sc); - } - - if (error == ENETRESET) { - if ((ifp->if_flags & IFF_UP) && - (ifp->if_drv_flags & IFF_DRV_RUNNING) && - ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - wpi_init_locked(sc, 0); - error = 0; + error = ether_ioctl(ifp, cmd, data); + break; } - WPI_UNLOCK(sc); + if (startall) + ieee80211_start_all(ic); return error; } @@ -2118,7 +2116,8 @@ wpi_ioctl(struct ifnet *ifp, u_long cmd, caddr_t data) static void wpi_read_eeprom(struct wpi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int i; /* read the hardware capabilities, revision and SKU type */ @@ -2222,7 +2221,6 @@ wpi_wme_update(struct ieee80211com *ic) "txop=%d\n", ac, wme.ac[ac].aifsn, wme.ac[ac].cwmin, wme.ac[ac].cwmax, wme.ac[ac].txop)); } - return wpi_cmd(sc, WPI_CMD_SET_WME, &wme, sizeof wme, 1); #undef WPI_USEC #undef WPI_EXP2 @@ -2234,7 +2232,8 @@ wpi_wme_update(struct ieee80211com *ic) static int wpi_mrr_setup(struct wpi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_mrr_setup mrr; int i, error; @@ -2326,7 +2325,8 @@ wpi_enable_tsf(struct wpi_softc *sc, struct ieee80211_node *ni) static int wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_tx_ring *ring = &sc->cmdq; struct wpi_tx_desc *desc; struct wpi_tx_data *data; @@ -2395,10 +2395,10 @@ wpi_setup_beacon(struct wpi_softc *sc, struct ieee80211_node *ni) #endif static int -wpi_auth(struct wpi_softc *sc) +wpi_auth(struct wpi_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_node *ni = vap->iv_bss; struct wpi_node_info node; int error; @@ -2412,16 +2412,14 @@ wpi_auth(struct wpi_softc *sc) sc->config.flags |= htole32(WPI_CONFIG_AUTO | WPI_CONFIG_24GHZ); } - switch (ic->ic_curmode) { - case IEEE80211_MODE_11A: + if (IEEE80211_IS_CHAN_A(ni->ni_chan)) { sc->config.cck_mask = 0; sc->config.ofdm_mask = 0x15; - break; - case IEEE80211_MODE_11B: + } else if (IEEE80211_IS_CHAN_B(ni->ni_chan)) { sc->config.cck_mask = 0x03; sc->config.ofdm_mask = 0; - break; - default: /* assume 802.11b/g */ + } else { + /* XXX assume 802.11b/g */ sc->config.cck_mask = 0x0f; sc->config.ofdm_mask = 0x15; } @@ -2457,13 +2455,18 @@ wpi_auth(struct wpi_softc *sc) } static int -wpi_run(struct wpi_softc *sc) +wpi_run(struct wpi_softc *sc, struct ieee80211vap *vap) { - struct ieee80211com *ic = &sc->sc_ic; - struct ieee80211_node *ni = ic->ic_bss; + struct ieee80211com *ic = vap->iv_ic; + struct ieee80211_node *ni = vap->iv_bss; int error; - ni = ic->ic_bss; + if (vap->iv_opmode == IEEE80211_M_MONITOR) { + /* link LED blinks while monitoring */ + wpi_set_led(sc, WPI_LED_LINK, 5, 5); + return 0; + } + wpi_enable_tsf(sc, ni); /* update adapter's configuration */ @@ -2488,22 +2491,22 @@ wpi_run(struct wpi_softc *sc) return error; } - error = wpi_set_txpower(sc, ic->ic_bsschan, 1); + error = wpi_set_txpower(sc, ni->ni_chan, 1); if (error != 0) { device_printf(sc->sc_dev, "could set txpower\n"); return error; } - if (ic->ic_opmode == IEEE80211_M_STA) { + if (vap->iv_opmode == IEEE80211_M_STA) { /* fake a join to init the tx rate */ - wpi_newassoc(ic->ic_bss, 1); + wpi_newassoc(ni, 1); } /* link LED always on while associated */ wpi_set_led(sc, WPI_LED_LINK, 0, 1); /* start automatic rate control timer */ - callout_reset(&sc->calib_to, hz/2, wpi_calib_timeout, sc); + callout_reset(&sc->calib_to, 60*hz, wpi_calib_timeout, sc); return (error); } @@ -2519,7 +2522,8 @@ wpi_run(struct wpi_softc *sc) static int wpi_scan(struct wpi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct ieee80211_scan_state *ss = ic->ic_scan; struct wpi_tx_ring *ring = &sc->cmdq; struct wpi_tx_desc *desc; @@ -2534,7 +2538,6 @@ wpi_scan(struct wpi_softc *sc) uint8_t *frm; int nrates, pktlen, error, i, nssid; bus_addr_t physaddr; - struct ifnet *ifp = ic->ic_ifp; desc = &ring->desc[ring->cur]; data = &ring->data[ring->cur]; @@ -2578,22 +2581,19 @@ wpi_scan(struct wpi_softc *sc) hdr->tx.lifetime = htole32(WPI_LIFETIME_INFINITE); hdr->tx.flags = htole32(WPI_TX_AUTO_SEQ); - /*XXX Need to cater for multiple essids */ - memset(&hdr->scan_essids, 0, sizeof(hdr->scan_essids)); + memset(hdr->scan_essids, 0, sizeof(hdr->scan_essids)); nssid = MIN(ss->ss_nssid, WPI_SCAN_MAX_ESSIDS); - for (i = 0; i < nssid; i++ ){ + for (i = 0; i < nssid; i++) { hdr->scan_essids[i].id = IEEE80211_ELEMID_SSID; hdr->scan_essids[i].esslen = MIN(ss->ss_ssid[i].len, 32); memcpy(hdr->scan_essids[i].essid, ss->ss_ssid[i].ssid, hdr->scan_essids[i].esslen); -#ifdef WPI_DEBUG if (wpi_debug & WPI_DEBUG_SCANNING) { printf("Scanning Essid: "); - ieee80211_print_essid(ic->ic_des_ssid[i].ssid, - ic->ic_des_ssid[i].len); + ieee80211_print_essid(hdr->scan_essids[i].essid, + hdr->scan_essids[i].esslen); printf("\n"); } -#endif } /* @@ -2651,17 +2651,17 @@ wpi_scan(struct wpi_softc *sc) chan->flags = 0; if (!(c->ic_flags & IEEE80211_CHAN_PASSIVE)) { chan->flags |= WPI_CHAN_ACTIVE; - if (ic->ic_des_ssid[0].len != 0) + if (nssid != 0) chan->flags |= WPI_CHAN_DIRECT; } chan->gain_dsp = 0x6e; /* Default level */ if (IEEE80211_IS_CHAN_5GHZ(c)) { chan->active = htole16(10); - chan->passive = htole16(sc->maxdwell); + chan->passive = htole16(ss->ss_maxdwell); chan->gain_radio = 0x3b; } else { chan->active = htole16(20); - chan->passive = htole16(sc->maxdwell); + chan->passive = htole16(ss->ss_maxdwell); chan->gain_radio = 0x28; } @@ -2746,8 +2746,8 @@ wpi_scan(struct wpi_softc *sc) static int wpi_config(struct wpi_softc *sc) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_power power; struct wpi_bluetooth bluetooth; struct wpi_node_info node; @@ -2968,7 +2968,8 @@ static void wpi_rfkill_resume(struct wpi_softc *sc) { struct ifnet *ifp = sc->sc_ifp; - struct ieee80211com *ic = &sc->sc_ic; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); int ntries; /* enable firmware again */ @@ -3000,46 +3001,26 @@ wpi_rfkill_resume(struct wpi_softc *sc) ifp->if_drv_flags |= IFF_DRV_RUNNING; sc->flags &= ~WPI_FLAG_HW_RADIO_OFF; - if (ic->ic_flags & IEEE80211_F_SCAN) - ieee80211_scan_next(ic); - - ieee80211_beacon_miss(ic); - - /* reset the led sequence */ - switch (ic->ic_state) { - case IEEE80211_S_SCAN: - wpi_set_led(sc, WPI_LED_LINK, 20, 2); - break; - - case IEEE80211_S_RUN: - if (ic->ic_opmode == IEEE80211_M_MONITOR) - wpi_set_led(sc, WPI_LED_LINK, 5, 5); - else + if (vap != NULL) { + if ((ic->ic_flags & IEEE80211_F_SCAN) == 0) { + if (vap->iv_opmode != IEEE80211_M_MONITOR) { + ieee80211_beacon_miss(ic); wpi_set_led(sc, WPI_LED_LINK, 0, 1); - break; - - default: - break; /* please compiler */ + } else + wpi_set_led(sc, WPI_LED_LINK, 5, 5); + } else { + ieee80211_scan_next(vap); + wpi_set_led(sc, WPI_LED_LINK, 20, 2); + } } callout_reset(&sc->watchdog_to, hz, wpi_watchdog, sc); } static void -wpi_init(void *arg) -{ - struct wpi_softc *sc = arg; - - WPI_LOCK(sc); - wpi_init_locked(sc, 0); - WPI_UNLOCK(sc); -} - -static void wpi_init_locked(struct wpi_softc *sc, int force) { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int ntries, qid; @@ -3143,29 +3124,27 @@ wpi_init_locked(struct wpi_softc *sc, int force) ifp->if_drv_flags |= IFF_DRV_RUNNING; out: callout_reset(&sc->watchdog_to, hz, wpi_watchdog, sc); - - if (ic->ic_opmode == IEEE80211_M_MONITOR) - ieee80211_new_state(ic, IEEE80211_S_RUN, -1); - else if (ic->ic_roaming != IEEE80211_ROAMING_MANUAL) - ieee80211_new_state(ic, IEEE80211_S_SCAN, -1); - return; } static void -wpi_stop(struct wpi_softc *sc) +wpi_init(void *arg) { + struct wpi_softc *sc = arg; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; WPI_LOCK(sc); - wpi_stop_locked(sc); + wpi_init_locked(sc, 0); WPI_UNLOCK(sc); + if (ifp->if_drv_flags & IFF_DRV_RUNNING) + ieee80211_start_all(ic); /* start all vaps */ } + static void wpi_stop_locked(struct wpi_softc *sc) - { - struct ieee80211com *ic = &sc->sc_ic; - struct ifnet *ifp = ic->ic_ifp; + struct ifnet *ifp = sc->sc_ifp; uint32_t tmp; int ac; @@ -3212,66 +3191,44 @@ wpi_stop_locked(struct wpi_softc *sc) tmp = WPI_READ(sc, WPI_RESET); WPI_WRITE(sc, WPI_RESET, tmp | WPI_SW_RESET); sc->flags &= ~WPI_FLAG_BUSY; - - ieee80211_new_state(ic, IEEE80211_S_INIT, -1); } static void -wpi_iter_func(void *arg, struct ieee80211_node *ni) +wpi_stop(struct wpi_softc *sc) { - struct wpi_softc *sc = arg; - struct wpi_node *wn = (struct wpi_node *)ni; - - ieee80211_amrr_choose(&sc->amrr, ni, &wn->amn); + WPI_LOCK(sc); + wpi_stop_locked(sc); + WPI_UNLOCK(sc); } static void wpi_newassoc(struct ieee80211_node *ni, int isnew) { - struct wpi_softc *sc = ni->ni_ic->ic_ifp->if_softc; - int i; + struct ieee80211vap *vap = ni->ni_vap; + struct wpi_vap *wvp = WPI_VAP(vap); - ieee80211_amrr_node_init(&sc->amrr, &((struct wpi_node *)ni)->amn); - - for (i = ni->ni_rates.rs_nrates - 1; - i > 0 && (ni->ni_rates.rs_rates[i] & IEEE80211_RATE_VAL) > 72; - i--); - ni->ni_txrate = i; + ieee80211_amrr_node_init(&wvp->amrr, &WPI_NODE(ni)->amn, ni); } static void wpi_calib_timeout(void *arg) { struct wpi_softc *sc = arg; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); int temp; - if (ic->ic_state != IEEE80211_S_RUN) + if (vap->iv_state != IEEE80211_S_RUN) return; - /* automatic rate control triggered every 500ms */ - if (ic->ic_fixed_rate == IEEE80211_FIXED_RATE_NONE) { - if (ic->ic_opmode == IEEE80211_M_STA) - wpi_iter_func(sc, ic->ic_bss); - else - ieee80211_iterate_nodes(&ic->ic_sta, wpi_iter_func, sc); - } - /* update sensor data */ temp = (int)WPI_READ(sc, WPI_TEMPERATURE); DPRINTFN(WPI_DEBUG_TEMP,("Temp in calibration is: %d\n", temp)); -#if 0 - //XXX Used by OpenBSD Sensor Framework - sc->sensor.value = temp + 260; -#endif - /* automatic power calibration every 60s */ - if (++sc->calib_cnt >= 120) { - wpi_power_calibration(sc, temp); - sc->calib_cnt = 0; - } + wpi_power_calibration(sc, temp); - callout_reset(&sc->calib_to, hz/2, wpi_calib_timeout, sc); + callout_reset(&sc->calib_to, 60*hz, wpi_calib_timeout, sc); } /* @@ -3281,6 +3238,10 @@ wpi_calib_timeout(void *arg) static void wpi_power_calibration(struct wpi_softc *sc, int temp) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + /* sanity-check read value */ if (temp < -260 || temp > 25) { /* this can't be correct, ignore */ @@ -3297,7 +3258,7 @@ wpi_power_calibration(struct wpi_softc *sc, int temp) sc->temp = temp; - if (wpi_set_txpower(sc, sc->sc_ic.ic_bss->ni_chan,1) != 0) { + if (wpi_set_txpower(sc, vap->iv_bss->ni_chan, 1) != 0) { /* just warn, too bad for the automatic calibration... */ device_printf(sc->sc_dev,"could not adjust Tx power\n"); } @@ -3310,7 +3271,8 @@ wpi_power_calibration(struct wpi_softc *sc, int temp) static void wpi_read_eeprom_channels(struct wpi_softc *sc, int n) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; const struct wpi_chan_band *band = &wpi_bands[n]; struct wpi_eeprom_chan channels[WPI_MAX_CHAN_PER_BAND]; int chan, i, offset, passive; @@ -3416,7 +3378,8 @@ wpi_read_eeprom_group(struct wpi_softc *sc, int n) static int wpi_set_txpower(struct wpi_softc *sc, struct ieee80211_channel *c, int async) { - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_power_group *group; struct wpi_cmd_txpower txpower; u_int chan; @@ -3476,7 +3439,8 @@ wpi_get_power_index(struct wpi_softc *sc, struct wpi_power_group *group, #define interpolate(x, x1, y1, x2, y2, n) \ ((y1) + fdivround(((x) - (x1)) * ((y2) - (y1)), (x2) - (x1), n)) - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; struct wpi_power_sample *sample; int pwr, idx; u_int chan; @@ -3587,13 +3551,12 @@ wpi_set_channel(struct ieee80211com *ic) * callback. */ static void -wpi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) +wpi_scan_curchan(struct ieee80211_scan_state *ss, unsigned long maxdwell) { - struct ifnet *ifp = ic->ic_ifp; + struct ieee80211vap *vap = ss->ss_vap; + struct ifnet *ifp = vap->iv_ic->ic_ifp; struct wpi_softc *sc = ifp->if_softc; - sc->maxdwell = maxdwell; - wpi_queue_cmd(sc, WPI_SCAN_CURCHAN, 0, WPI_QUEUE_NORMAL); } @@ -3604,7 +3567,7 @@ wpi_scan_curchan(struct ieee80211com *ic, unsigned long maxdwell) * us when it's finished and we have no way to interrupt it. */ static void -wpi_scan_mindwell(struct ieee80211com *ic) +wpi_scan_mindwell(struct ieee80211_scan_state *ss) { /* NB: don't try to abort scan; wait for firmware to finish */ } @@ -3619,8 +3582,10 @@ static void wpi_ops(void *arg0, int pending) { struct wpi_softc *sc = arg0; - struct ieee80211com *ic = &sc->sc_ic; + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; int cmd, arg, error; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); again: WPI_CMD_LOCK(sc); @@ -3659,6 +3624,8 @@ again: switch (cmd) { case WPI_SCAN_START: + /* make the link LED blink while we're scanning */ + wpi_set_led(sc, WPI_LED_LINK, 20, 2); sc->flags |= WPI_FLAG_SCANNING; break; @@ -3668,7 +3635,7 @@ again: case WPI_SCAN_CURCHAN: if (wpi_scan(sc)) - ieee80211_cancel_scan(ic); + ieee80211_cancel_scan(vap); break; case WPI_SET_CHAN: @@ -3680,29 +3647,36 @@ again: case WPI_AUTH: /* The node must be registered in the firmware before auth */ - error = wpi_auth(sc); + error = wpi_auth(sc, vap); + WPI_UNLOCK(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: could not move to auth state, error %d\n", __func__, error); - WPI_UNLOCK(sc); return; } - /* Send the auth frame now */ - sc->sc_newstate(ic, IEEE80211_S_AUTH, arg); - break; + IEEE80211_LOCK(ic); + WPI_VAP(vap)->newstate(vap, IEEE80211_S_AUTH, arg); + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, IEEE80211_S_AUTH, arg); + IEEE80211_UNLOCK(ic); + goto again; case WPI_RUN: - error = wpi_run(sc); + error = wpi_run(sc, vap); + WPI_UNLOCK(sc); if (error != 0) { device_printf(sc->sc_dev, "%s: could not move to run state, error %d\n", __func__, error); - WPI_UNLOCK(sc); return; } - sc->sc_newstate(ic, IEEE80211_S_RUN, arg); - break; + IEEE80211_LOCK(ic); + WPI_VAP(vap)->newstate(vap, IEEE80211_S_RUN, arg); + if (vap->iv_newstate_cb != NULL) + vap->iv_newstate_cb(vap, IEEE80211_S_RUN, arg); + IEEE80211_UNLOCK(ic); + goto again; } WPI_UNLOCK(sc); @@ -3800,9 +3774,12 @@ wpi_watchdog(void *arg) } } if (sc->sc_scan_timer > 0) { - if (--sc->sc_scan_timer == 0) { + struct ifnet *ifp = sc->sc_ifp; + struct ieee80211com *ic = ifp->if_l2com; + struct ieee80211vap *vap = TAILQ_FIRST(&ic->ic_vaps); + if (--sc->sc_scan_timer == 0 && vap != NULL) { device_printf(sc->sc_dev,"scan timeout\n"); - ieee80211_cancel_scan(&sc->sc_ic); + ieee80211_cancel_scan(vap); wpi_queue_cmd(sc, WPI_RESTART, 0, WPI_QUEUE_CLEAR); } } @@ -3814,25 +3791,25 @@ wpi_watchdog(void *arg) #ifdef WPI_DEBUG static const char *wpi_cmd_str(int cmd) { - switch(cmd) { - case WPI_DISABLE_CMD: return "WPI_DISABLE_CMD"; - case WPI_CMD_CONFIGURE: return "WPI_CMD_CONFIGURE"; - case WPI_CMD_ASSOCIATE: return "WPI_CMD_ASSOCIATE"; - case WPI_CMD_SET_WME: return "WPI_CMD_SET_WME"; - case WPI_CMD_TSF: return "WPI_CMD_TSF"; - case WPI_CMD_ADD_NODE: return "WPI_CMD_ADD_NODE"; - case WPI_CMD_TX_DATA: return "WPI_CMD_TX_DATA"; - case WPI_CMD_MRR_SETUP: return "WPI_CMD_MRR_SETUP"; - case WPI_CMD_SET_LED: return "WPI_CMD_SET_LED"; - case WPI_CMD_SET_POWER_MODE: return "WPI_CMD_SET_POWER_MODE"; - case WPI_CMD_SCAN: return "WPI_CMD_SCAN"; - case WPI_CMD_SET_BEACON:return "WPI_CMD_SET_BEACON"; - case WPI_CMD_TXPOWER: return "WPI_CMD_TXPOWER"; - case WPI_CMD_BLUETOOTH: return "WPI_CMD_BLUETOOTH"; - - default: + switch (cmd) { + case WPI_DISABLE_CMD: return "WPI_DISABLE_CMD"; + case WPI_CMD_CONFIGURE: return "WPI_CMD_CONFIGURE"; + case WPI_CMD_ASSOCIATE: return "WPI_CMD_ASSOCIATE"; + case WPI_CMD_SET_WME: return "WPI_CMD_SET_WME"; + case WPI_CMD_TSF: return "WPI_CMD_TSF"; + case WPI_CMD_ADD_NODE: return "WPI_CMD_ADD_NODE"; + case WPI_CMD_TX_DATA: return "WPI_CMD_TX_DATA"; + case WPI_CMD_MRR_SETUP: return "WPI_CMD_MRR_SETUP"; + case WPI_CMD_SET_LED: return "WPI_CMD_SET_LED"; + case WPI_CMD_SET_POWER_MODE: return "WPI_CMD_SET_POWER_MODE"; + case WPI_CMD_SCAN: return "WPI_CMD_SCAN"; + case WPI_CMD_SET_BEACON:return "WPI_CMD_SET_BEACON"; + case WPI_CMD_TXPOWER: return "WPI_CMD_TXPOWER"; + case WPI_CMD_BLUETOOTH: return "WPI_CMD_BLUETOOTH"; + + default: KASSERT(1, ("Unknown Command: %d\n", cmd)); - return "UNKNOWN CMD"; // Make the compiler happy + return "UNKNOWN CMD"; /* Make the compiler happy */ } } #endif diff --git a/sys/dev/wpi/if_wpivar.h b/sys/dev/wpi/if_wpivar.h index 39020df..1436592 100644 --- a/sys/dev/wpi/if_wpivar.h +++ b/sys/dev/wpi/if_wpivar.h @@ -110,6 +110,7 @@ struct wpi_node { struct ieee80211_node ni; /* must be the first */ struct ieee80211_amrr_node amn; }; +#define WPI_NODE(ni) ((struct wpi_node *)(ni)) struct wpi_power_sample { uint8_t index; @@ -118,26 +119,26 @@ struct wpi_power_sample { struct wpi_power_group { #define WPI_SAMPLES_COUNT 5 - struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; - uint8_t chan; - int8_t maxpwr; - int16_t temp; + struct wpi_power_sample samples[WPI_SAMPLES_COUNT]; + uint8_t chan; + int8_t maxpwr; + int16_t temp; }; -struct wpi_softc { - device_t sc_dev; - struct ifnet *sc_ifp; +struct wpi_vap { + struct ieee80211vap vap; + struct ieee80211_amrr amrr; - /* net80211 driver specifics */ - struct ieee80211com sc_ic; - int (*sc_newstate)(struct ieee80211com *, + int (*newstate)(struct ieee80211vap *, enum ieee80211_state, int); - unsigned long maxdwell; /* Max dwell time whilst scanning */ +}; +#define WPI_VAP(vap) ((struct wpi_vap *)(vap)) +struct wpi_softc { + device_t sc_dev; + struct ifnet *sc_ifp; struct mtx sc_mtx; - struct ieee80211_amrr amrr; - /* Flags indicating the current state the driver * expects the hardware to be in */ @@ -212,15 +213,15 @@ struct wpi_softc { int sc_cmd_next; /* last queued scan task */ struct mtx sc_cmdlock; - /* Task queues used to control the driver */ - struct taskqueue *sc_tq; /* Main command task queue */ - struct taskqueue *sc_tq2;/* firmware reset task queue */ + /* Task queues used to control the driver */ + struct taskqueue *sc_tq; /* Main command task queue */ + struct taskqueue *sc_tq2; /* firmware reset task queue */ - /* Tasks used by the driver */ - struct task sc_radioontask; /* enable rf transmitter task*/ - struct task sc_radioofftask;/* disable rf transmitter task*/ - struct task sc_opstask; /* operation handling task */ - struct task sc_restarttask; /* reset firmware task */ + /* Tasks used by the driver */ + struct task sc_radioontask; /* enable rf transmitter task*/ + struct task sc_radioofftask;/* disable rf transmitter task*/ + struct task sc_opstask; /* operation handling task */ + struct task sc_restarttask; /* reset firmware task */ /* Eeprom info */ uint8_t cap; @@ -228,7 +229,7 @@ struct wpi_softc { uint8_t type; struct wpi_power_group groups[WPI_POWER_GROUPS_COUNT]; int8_t maxpwr[IEEE80211_CHAN_MAX]; - char domain[4]; //reglatory domain //XXX + char domain[4]; /*reglatory domain XXX */ }; #define WPI_LOCK_INIT(_sc) \ mtx_init(&(_sc)->sc_mtx, device_get_nameunit((_sc)->sc_dev), \ @@ -236,7 +237,6 @@ struct wpi_softc { #define WPI_LOCK(_sc) mtx_lock(&(_sc)->sc_mtx) #define WPI_UNLOCK(_sc) mtx_unlock(&(_sc)->sc_mtx) #define WPI_LOCK_ASSERT(sc) mtx_assert(&(sc)->sc_mtx, MA_OWNED) -#define WPI_LOCK_OWNED(_sc) mtx_owned(&(_sc)->sc_mtx) #define WPI_LOCK_DESTROY(_sc) mtx_destroy(&(_sc)->sc_mtx) #define WPI_CMD_LOCK_INIT(_sc) \ -- cgit v1.1