diff --git a/CODEOWNERS b/CODEOWNERS index 0839a670d0..026eeac5c6 100644 --- a/CODEOWNERS +++ b/CODEOWNERS @@ -48,3 +48,6 @@ doc/* @b-gent /nrf_dm/ @Tschet1 @eriksandgren /lc3/ @koffes @alexsven /nrf_fuel_gauge/ @nordic-auko @aasinclair +/nrf_wifi/ @krish2718 @sachinthegreen @rado17 @rlubos +/nrf_wifi/fw_if/umac_if/inc/fw/ @udaynordic @srkanordic +/nrf_wifi/hw_if/hal/inc/fw/ @udaynordic @srkanordic diff --git a/README.rst b/README.rst index 81c8499b00..a7b2fcd307 100644 --- a/README.rst +++ b/README.rst @@ -24,5 +24,6 @@ Refer to their respective documentation for more information. nrf_dm/README openthread/README nrf_rpc/README + nrf_wifi/README softdevice_controller/README zboss/README diff --git a/nrf_wifi/README.rst b/nrf_wifi/README.rst new file mode 100644 index 0000000000..62a0eabe12 --- /dev/null +++ b/nrf_wifi/README.rst @@ -0,0 +1,14 @@ +.. _nrf_wifi_api: + +Low-level API documentation +*************************** + +The nRF70 Series Wi-Fi driver provides a low-level API for use cases where the application needs to access the nRF70 Series device directly. +This is typically intended for customers who want to use the nRF70 Series device on a different platform than Zephyr. + +.. toctree:: + :maxdepth: 1 + :caption: Modules: + :glob: + + doc/* diff --git a/nrf_wifi/bus_if/bal/inc/bal_api.h b/nrf_wifi/bus_if/bal/inc/bal_api.h new file mode 100644 index 0000000000..c9e5686e65 --- /dev/null +++ b/nrf_wifi/bus_if/bal/inc/bal_api.h @@ -0,0 +1,98 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing the API declarations for the Bus Abstraction Layer + * (BAL) of the Wi-Fi driver. + */ + +#ifndef __BAL_API_H__ +#define __BAL_API_H__ + +#include "osal_api.h" +#include "bal_structs.h" + +/** + * nrf_wifi_bal_init() - Initialize the BAL layer. + * + * @intr_callbk_fn: Pointer to the callback function which the user of this + * layer needs to implement to handle interrupts from the + * RPU. + * + * This API is used to initialize the BAL layer and is expected to be called + * before using the BAL layer. This API returns a pointer to the BAL context + * which might need to be passed to further API calls. + * + * Returns: Pointer to instance of BAL layer context. + */ +struct nrf_wifi_bal_priv *nrf_wifi_bal_init(struct nrf_wifi_osal_priv *opriv, + struct nrf_wifi_bal_cfg_params *cfg_params, + enum nrf_wifi_status (*intr_callbk_fn)(void *hal_ctx)); + + +/** + * nrf_wifi_bal_deinit() - Deinitialize the BAL layer. + * @bpriv: Pointer to the BAL layer context returned by the + * @nrf_wifi_bal_init API. + * + * This API is used to deinitialize the BAL layer and is expected to be called + * after done using the BAL layer. + * + * Returns: None. + */ +void nrf_wifi_bal_deinit(struct nrf_wifi_bal_priv *bpriv); + + +struct nrf_wifi_bal_dev_ctx *nrf_wifi_bal_dev_add(struct nrf_wifi_bal_priv *bpriv, + void *hal_dev_ctx); + +void nrf_wifi_bal_dev_rem(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx); + +enum nrf_wifi_status nrf_wifi_bal_dev_init(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx); + +void nrf_wifi_bal_dev_deinit(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx); + +unsigned int nrf_wifi_bal_read_word(void *ctx, + unsigned long addr_offset); + +void nrf_wifi_bal_write_word(void *ctx, + unsigned long addr_offset, + unsigned int val); + +void nrf_wifi_bal_read_block(void *ctx, + void *dest_addr, + unsigned long src_addr_offset, + size_t len); + +void nrf_wifi_bal_write_block(void *ctx, + unsigned long dest_addr_offset, + const void *src_addr, + size_t len); + +unsigned long nrf_wifi_bal_dma_map(void *ctx, + unsigned long virt_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir); + +unsigned long nrf_wifi_bal_dma_unmap(void *ctx, + unsigned long phy_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir); + +void nrf_wifi_bal_bus_access_rec_enab(void *ctx); + +void nrf_wifi_bal_bus_access_rec_disab(void *ctx); + +void nrf_wifi_bal_bus_access_cnt_print(void *ctx); + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +void nrf_wifi_bal_rpu_ps_sleep(void *ctx); + +void nrf_wifi_bal_rpu_ps_wake(void *ctx); + +int nrf_wifi_bal_rpu_ps_status(void *ctx); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +#endif /* __BAL_API_H__ */ diff --git a/nrf_wifi/bus_if/bal/inc/bal_ops.h b/nrf_wifi/bus_if/bal/inc/bal_ops.h new file mode 100644 index 0000000000..9e06a081ff --- /dev/null +++ b/nrf_wifi/bus_if/bal/inc/bal_ops.h @@ -0,0 +1,81 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing the OPs declarations for the Bus Abstraction Layer + * (BAL) of the Wi-Fi driver. + */ + +#ifndef __BAL_OPS_H__ +#define __BAL_OPS_H__ + +#include + +/** + * struct nrf_wifi_bal_ops - Ops to be provided by a particular bus + * implementation. + * @init: + * @deinit: + * @dev_init: + * @dev_deinit: + * @read_word: + * @write_word: + * @read_block: + * @write_block: + * @dma_map: + * @dma_unmap: + */ +struct nrf_wifi_bal_ops { + void * (*init)(struct nrf_wifi_osal_priv *opriv, + void *cfg_params, + enum nrf_wifi_status (*intr_callbk_fn)(void *hal_ctx)); + void (*deinit)(void *bus_priv); + void * (*dev_add)(void *bus_priv, + void *bal_dev_ctx); + void (*dev_rem)(void *bus_dev_ctx); + + enum nrf_wifi_status (*dev_init)(void *bus_dev_ctx); + void (*dev_deinit)(void *bus_dev_ctx); + unsigned int (*read_word)(void *bus_dev_ctx, + unsigned long addr_offset); + void (*write_word)(void *bus_dev_ctx, + unsigned long addr_offset, + unsigned int val); + void (*read_block)(void *bus_dev_ctx, + void *dest_addr, + unsigned long src_addr_offset, + size_t len); + void (*write_block)(void *bus_dev_ctx, + unsigned long dest_addr_offset, + const void *src_addr, + size_t len); + unsigned long (*dma_map)(void *bus_dev_ctx, + unsigned long virt_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir); + unsigned long (*dma_unmap)(void *bus_dev_ctx, + unsigned long phy_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir); +#ifdef CONFIG_NRF_WIFI_LOW_POWER + void (*rpu_ps_sleep)(void *bus_dev_ctx); + void (*rpu_ps_wake)(void *bus_dev_ctx); + int (*rpu_ps_status)(void *bus_dev_ctx); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +}; + + +/** + * get_bus_ops() - The BAL layer expects this Op return a initialized instance + * of Bus specific Ops. + * + * This Op is expected to be implemented by a specific Bus shim and is expected + * to return a pointer to a initialized instance of struct nrf_wifi_bal_ops. + * + * Returns: Pointer to instance of Bus specific Ops. + */ +struct nrf_wifi_bal_ops *get_bus_ops(void); +#endif /* __BAL_OPS_H__ */ diff --git a/nrf_wifi/bus_if/bal/inc/bal_structs.h b/nrf_wifi/bus_if/bal/inc/bal_structs.h new file mode 100644 index 0000000000..5cb2467a58 --- /dev/null +++ b/nrf_wifi/bus_if/bal/inc/bal_structs.h @@ -0,0 +1,55 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing the structure declarations for the Bus Abstraction + * Layer (BAL) of the Wi-Fi driver. + */ + +#ifndef __BAL_STRUCTS_H__ +#define __BAL_STRUCTS_H__ + +#include "osal_ops.h" +#include "bal_ops.h" + +struct nrf_wifi_bal_cfg_params { + unsigned long addr_pktram_base; +}; + +/** + * struct nrf_wifi_bal_priv - Structure to hold context information for the BAL + * @opriv: Pointer to the OSAL context. + * @bus_priv: Pointer to a specific bus context. + * @ops: Pointer to bus operations to be provided by a specific bus + * implementation. + * + * This structure maintains the context information necessary for the + * operation of the BAL. Some of the elements of the structure need to be + * initialized during the initialization of the BAL while others need to + * be kept updated over the duration of the BAL operation. + */ +struct nrf_wifi_bal_priv { + struct nrf_wifi_osal_priv *opriv; + void *bus_priv; + struct nrf_wifi_bal_ops *ops; + + enum nrf_wifi_status (*init_dev_callbk_fn)(void *ctx); + + void (*deinit_dev_callbk_fn)(void *ctx); + + enum nrf_wifi_status (*intr_callbk_fn)(void *ctx); +}; + + +struct nrf_wifi_bal_dev_ctx { + struct nrf_wifi_bal_priv *bpriv; + void *hal_dev_ctx; + void *bus_dev_ctx; +#ifdef CONFIG_NRF_WIFI_LOW_POWER + bool rpu_fw_booted; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +}; +#endif /* __BAL_STRUCTS_H__ */ diff --git a/nrf_wifi/bus_if/bal/src/bal.c b/nrf_wifi/bus_if/bal/src/bal.c new file mode 100644 index 0000000000..2e44566705 --- /dev/null +++ b/nrf_wifi/bus_if/bal/src/bal.c @@ -0,0 +1,344 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief API definitions for the Bus Abstraction Layer (BAL) of the Wi-Fi + * driver. + */ + + +#include "bal_api.h" + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG +#include "pal.h" + +static void nrf_wifi_rpu_bal_sleep_chk(struct nrf_wifi_bal_dev_ctx *bal_ctx, + unsigned long addr) +{ + unsigned int sleep_reg_val = 0; + unsigned int rpu_ps_state_mask = 0; + unsigned long sleep_reg_addr = 0; + + if (!bal_ctx->rpu_fw_booted) + return; + + sleep_reg_addr = pal_rpu_ps_ctrl_reg_addr_get(); + + if (sleep_reg_addr == addr) + return; + + sleep_reg_val = bal_ctx->bpriv->ops->read_word(bal_ctx->bus_dev_ctx, + sleep_reg_addr); + + rpu_ps_state_mask = ((1 << RPU_REG_BIT_PS_STATE) | + (1 << RPU_REG_BIT_READY_STATE)); + + if ((sleep_reg_val & rpu_ps_state_mask) != rpu_ps_state_mask) { + nrf_wifi_osal_log_err(bal_ctx->bpriv->opriv, + "%s:RPU is being accessed when it is not ready !!! (Reg val = 0x%X)\n", + __func__, + sleep_reg_val); + } +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + +struct nrf_wifi_bal_dev_ctx *nrf_wifi_bal_dev_add(struct nrf_wifi_bal_priv *bpriv, + void *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = nrf_wifi_osal_mem_zalloc(bpriv->opriv, + sizeof(*bal_dev_ctx)); + + if (!bal_dev_ctx) { + nrf_wifi_osal_log_err(bpriv->opriv, + "%s: Unable to allocate bal_dev_ctx\n", __func__); + goto out; + } + + bal_dev_ctx->bpriv = bpriv; + bal_dev_ctx->hal_dev_ctx = hal_dev_ctx; + + bal_dev_ctx->bus_dev_ctx = bpriv->ops->dev_add(bpriv->bus_priv, + bal_dev_ctx); + + if (!bal_dev_ctx->bus_dev_ctx) { + nrf_wifi_osal_log_err(bpriv->opriv, + "%s: Bus dev_add failed\n", __func__); + goto out; + } + + status = NRF_WIFI_STATUS_SUCCESS; +out: + if (status != NRF_WIFI_STATUS_SUCCESS) { + if (bal_dev_ctx) { + nrf_wifi_osal_mem_free(bpriv->opriv, + bal_dev_ctx); + bal_dev_ctx = NULL; + } + } + + return bal_dev_ctx; +} + + +void nrf_wifi_bal_dev_rem(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx) +{ + bal_dev_ctx->bpriv->ops->dev_rem(bal_dev_ctx->bus_dev_ctx); + + nrf_wifi_osal_mem_free(bal_dev_ctx->bpriv->opriv, + bal_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_bal_dev_init(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + bal_dev_ctx->rpu_fw_booted = true; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + status = bal_dev_ctx->bpriv->ops->dev_init(bal_dev_ctx->bus_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(bal_dev_ctx->bpriv->opriv, + "%s: dev_init failed\n", __func__); + goto out; + } +out: + return status; +} + + +void nrf_wifi_bal_dev_deinit(struct nrf_wifi_bal_dev_ctx *bal_dev_ctx) +{ + bal_dev_ctx->bpriv->ops->dev_deinit(bal_dev_ctx->bus_dev_ctx); +} + + +static enum nrf_wifi_status nrf_wifi_bal_isr(void *ctx) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + + status = bal_dev_ctx->bpriv->intr_callbk_fn(bal_dev_ctx->hal_dev_ctx); + + return status; +} + + +struct nrf_wifi_bal_priv * +nrf_wifi_bal_init(struct nrf_wifi_osal_priv *opriv, + struct nrf_wifi_bal_cfg_params *cfg_params, + enum nrf_wifi_status (*intr_callbk_fn)(void *hal_dev_ctx)) +{ + struct nrf_wifi_bal_priv *bpriv = NULL; + + bpriv = nrf_wifi_osal_mem_zalloc(opriv, + sizeof(*bpriv)); + + if (!bpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate memory for bpriv\n", __func__); + goto out; + } + + bpriv->opriv = opriv; + + bpriv->intr_callbk_fn = intr_callbk_fn; + + bpriv->ops = get_bus_ops(); + + bpriv->bus_priv = bpriv->ops->init(opriv, + cfg_params, + &nrf_wifi_bal_isr); + + if (!bpriv->bus_priv) { + nrf_wifi_osal_log_err(opriv, + "%s: Failed\n", __func__); + nrf_wifi_osal_mem_free(opriv, + bpriv); + bpriv = NULL; + } + +out: + return bpriv; +} + + +void nrf_wifi_bal_deinit(struct nrf_wifi_bal_priv *bpriv) +{ + bpriv->ops->deinit(bpriv->bus_priv); + + nrf_wifi_osal_mem_free(bpriv->opriv, + bpriv); +} + + +unsigned int nrf_wifi_bal_read_word(void *ctx, + unsigned long addr_offset) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + unsigned int val = 0; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG + nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx, + addr_offset); +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + val = bal_dev_ctx->bpriv->ops->read_word(bal_dev_ctx->bus_dev_ctx, + addr_offset); + + return val; +} + + +void nrf_wifi_bal_write_word(void *ctx, + unsigned long addr_offset, + unsigned int val) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG + nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx, + addr_offset); +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + bal_dev_ctx->bpriv->ops->write_word(bal_dev_ctx->bus_dev_ctx, + addr_offset, + val); +} + + +void nrf_wifi_bal_read_block(void *ctx, + void *dest_addr, + unsigned long src_addr_offset, + size_t len) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG + nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx, + src_addr_offset); +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + bal_dev_ctx->bpriv->ops->read_block(bal_dev_ctx->bus_dev_ctx, + dest_addr, + src_addr_offset, + len); +} + + +void nrf_wifi_bal_write_block(void *ctx, + unsigned long dest_addr_offset, + const void *src_addr, + size_t len) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG + nrf_wifi_rpu_bal_sleep_chk(bal_dev_ctx, + dest_addr_offset); +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + bal_dev_ctx->bpriv->ops->write_block(bal_dev_ctx->bus_dev_ctx, + dest_addr_offset, + src_addr, + len); +} + + +unsigned long nrf_wifi_bal_dma_map(void *ctx, + unsigned long virt_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + unsigned long phy_addr = 0; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + + phy_addr = bal_dev_ctx->bpriv->ops->dma_map(bal_dev_ctx->bus_dev_ctx, + virt_addr, + len, + dma_dir); + + return phy_addr; +} + + +unsigned long nrf_wifi_bal_dma_unmap(void *ctx, + unsigned long phy_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + unsigned long virt_addr = 0; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + + virt_addr = bal_dev_ctx->bpriv->ops->dma_unmap(bal_dev_ctx->bus_dev_ctx, + phy_addr, + len, + dma_dir); + + return virt_addr; +} + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +void nrf_wifi_bal_rpu_ps_sleep(void *ctx) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + + bal_dev_ctx->bpriv->ops->rpu_ps_sleep(bal_dev_ctx->bus_dev_ctx); +} + + +void nrf_wifi_bal_rpu_ps_wake(void *ctx) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + + bal_dev_ctx->bpriv->ops->rpu_ps_wake(bal_dev_ctx->bus_dev_ctx); +} + + +int nrf_wifi_bal_rpu_ps_status(void *ctx) +{ + struct nrf_wifi_bal_dev_ctx *bal_dev_ctx = NULL; + + bal_dev_ctx = (struct nrf_wifi_bal_dev_ctx *)ctx; + + return bal_dev_ctx->bpriv->ops->rpu_ps_status(bal_dev_ctx->bus_dev_ctx); +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ diff --git a/nrf_wifi/bus_if/bus/qspi/inc/qspi.h b/nrf_wifi/bus_if/bus/qspi/inc/qspi.h new file mode 100644 index 0000000000..eabd14f27a --- /dev/null +++ b/nrf_wifi/bus_if/bus/qspi/inc/qspi.h @@ -0,0 +1,46 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header for the QSPI bus layer specific structure declarations of the + * Wi-Fi driver. + */ + +#ifndef __QSPI_H__ +#define __QSPI_H__ + +/** + * struct nrf_wifi_bus_qspi_priv - Structure to hold context information for the QSPI bus. + * @opriv: Pointer to the OSAL context. + * @os_qspi_priv: + * @intr_callbk_fn: + * @cfg_params: + * + * This structure maintains the context information necessary for the operation + * of the QSPI bus. Some of the elements of the structure need to be initialized + * during the initialization of the QSPI bus while others need to be kept + * updated over the duration of the QSPI bus operation. + */ +struct nrf_wifi_bus_qspi_priv { + struct nrf_wifi_osal_priv *opriv; + void *os_qspi_priv; + + enum nrf_wifi_status (*intr_callbk_fn)(void *hal_ctx); + + /* TODO: See if this can be removed by getting the information from PAL */ + struct nrf_wifi_bal_cfg_params cfg_params; +}; + + +struct nrf_wifi_bus_qspi_dev_ctx { + struct nrf_wifi_bus_qspi_priv *qspi_priv; + void *bal_dev_ctx; + void *os_qspi_dev_ctx; + + unsigned long host_addr_base; + unsigned long addr_pktram_base; +}; +#endif /* __QSPI_H__ */ diff --git a/nrf_wifi/bus_if/bus/qspi/src/qspi.c b/nrf_wifi/bus_if/bus/qspi/src/qspi.c new file mode 100644 index 0000000000..d1949a15de --- /dev/null +++ b/nrf_wifi/bus_if/bus/qspi/src/qspi.c @@ -0,0 +1,371 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing QSPI Bus Layer specific function definitions of the + * Wi-Fi driver. + */ + +#include "bal_structs.h" +#include "qspi.h" +#include "pal.h" + + +static int nrf_wifi_bus_qspi_irq_handler(void *data) +{ + struct nrf_wifi_bus_qspi_dev_ctx *dev_ctx = NULL; + struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL; + int ret = 0; + + dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)data; + qspi_priv = dev_ctx->qspi_priv; + + ret = qspi_priv->intr_callbk_fn(dev_ctx->bal_dev_ctx); + + return ret; +} + + +static void *nrf_wifi_bus_qspi_dev_add(void *bus_priv, + void *bal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL; + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + struct nrf_wifi_osal_host_map host_map; + + qspi_priv = bus_priv; + + qspi_dev_ctx = nrf_wifi_osal_mem_zalloc(qspi_priv->opriv, + sizeof(*qspi_dev_ctx)); + + if (!qspi_dev_ctx) { + nrf_wifi_osal_log_err(qspi_priv->opriv, + "%s: Unable to allocate qspi_dev_ctx\n", __func__); + goto out; + } + + qspi_dev_ctx->qspi_priv = qspi_priv; + qspi_dev_ctx->bal_dev_ctx = bal_dev_ctx; + + qspi_dev_ctx->os_qspi_dev_ctx = nrf_wifi_osal_bus_qspi_dev_add(qspi_priv->opriv, + qspi_priv->os_qspi_priv, + qspi_dev_ctx); + + if (!qspi_dev_ctx->os_qspi_dev_ctx) { + nrf_wifi_osal_log_err(qspi_priv->opriv, + "%s: nrf_wifi_osal_bus_qspi_dev_add failed\n", __func__); + + nrf_wifi_osal_mem_free(qspi_priv->opriv, + qspi_dev_ctx); + + qspi_dev_ctx = NULL; + + goto out; + } + + nrf_wifi_osal_bus_qspi_dev_host_map_get(qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + &host_map); + + qspi_dev_ctx->host_addr_base = host_map.addr; + + qspi_dev_ctx->addr_pktram_base = qspi_dev_ctx->host_addr_base + + qspi_priv->cfg_params.addr_pktram_base; + + status = nrf_wifi_osal_bus_qspi_dev_intr_reg(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + qspi_dev_ctx, + &nrf_wifi_bus_qspi_irq_handler); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(qspi_dev_ctx->qspi_priv->opriv, + "%s: Unable to register interrupt to the OS\n", + __func__); + + nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); + + nrf_wifi_osal_bus_qspi_dev_rem(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); + + nrf_wifi_osal_mem_free(qspi_priv->opriv, + qspi_dev_ctx); + + qspi_dev_ctx = NULL; + + goto out; + } + +out: + return qspi_dev_ctx; +} + + +static void nrf_wifi_bus_qspi_dev_rem(void *bus_dev_ctx) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = bus_dev_ctx; + + nrf_wifi_osal_bus_qspi_dev_intr_unreg(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); + + nrf_wifi_osal_bus_qspi_dev_rem(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); + + nrf_wifi_osal_mem_free(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx); +} + + +static enum nrf_wifi_status nrf_wifi_bus_qspi_dev_init(void *bus_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = bus_dev_ctx; + + status = nrf_wifi_osal_bus_qspi_dev_init(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(qspi_dev_ctx->qspi_priv->opriv, + "%s: nrf_wifi_osal_qspi_dev_init failed\n", __func__); + + goto out; + } +out: + return status; +} + + +static void nrf_wifi_bus_qspi_dev_deinit(void *bus_dev_ctx) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = bus_dev_ctx; + + nrf_wifi_osal_bus_qspi_dev_deinit(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); +} + + +static void *nrf_wifi_bus_qspi_init(struct nrf_wifi_osal_priv *opriv, + void *params, + enum nrf_wifi_status (*intr_callbk_fn)(void *bal_dev_ctx)) +{ + struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL; + + qspi_priv = nrf_wifi_osal_mem_zalloc(opriv, + sizeof(*qspi_priv)); + + if (!qspi_priv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate memory for qspi_priv\n", + __func__); + goto out; + } + + qspi_priv->opriv = opriv; + + nrf_wifi_osal_mem_cpy(opriv, + &qspi_priv->cfg_params, + params, + sizeof(qspi_priv->cfg_params)); + + qspi_priv->intr_callbk_fn = intr_callbk_fn; + + qspi_priv->os_qspi_priv = nrf_wifi_osal_bus_qspi_init(opriv); + + if (!qspi_priv->os_qspi_priv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to register QSPI driver\n", + __func__); + + nrf_wifi_osal_mem_free(opriv, + qspi_priv); + + qspi_priv = NULL; + + goto out; + } +out: + return qspi_priv; +} + + +static void nrf_wifi_bus_qspi_deinit(void *bus_priv) +{ + struct nrf_wifi_bus_qspi_priv *qspi_priv = NULL; + + qspi_priv = bus_priv; + + nrf_wifi_osal_bus_qspi_deinit(qspi_priv->opriv, + qspi_priv->os_qspi_priv); + + nrf_wifi_osal_mem_free(qspi_priv->opriv, + qspi_priv); +} + + +static unsigned int nrf_wifi_bus_qspi_read_word(void *dev_ctx, + unsigned long addr_offset) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + unsigned int val = 0; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + val = nrf_wifi_osal_qspi_read_reg32(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + qspi_dev_ctx->host_addr_base + addr_offset); + + return val; +} + + +static void nrf_wifi_bus_qspi_write_word(void *dev_ctx, + unsigned long addr_offset, + unsigned int val) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_qspi_write_reg32(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + qspi_dev_ctx->host_addr_base + addr_offset, + val); +} + + +static void nrf_wifi_bus_qspi_read_block(void *dev_ctx, + void *dest_addr, + unsigned long src_addr_offset, + size_t len) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_qspi_cpy_from(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + dest_addr, + qspi_dev_ctx->host_addr_base + src_addr_offset, + len); +} + + +static void nrf_wifi_bus_qspi_write_block(void *dev_ctx, + unsigned long dest_addr_offset, + const void *src_addr, + size_t len) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_qspi_cpy_to(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx, + qspi_dev_ctx->host_addr_base + dest_addr_offset, + src_addr, + len); +} + + +static unsigned long nrf_wifi_bus_qspi_dma_map(void *dev_ctx, + unsigned long virt_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + unsigned long phy_addr = 0; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + phy_addr = qspi_dev_ctx->host_addr_base + (virt_addr - qspi_dev_ctx->addr_pktram_base); + + return phy_addr; +} + + +static unsigned long nrf_wifi_bus_qspi_dma_unmap(void *dev_ctx, + unsigned long phy_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + unsigned long virt_addr = 0; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + virt_addr = qspi_dev_ctx->addr_pktram_base + (phy_addr - qspi_dev_ctx->host_addr_base); + + return virt_addr; +} + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +static void nrf_wifi_bus_qspi_ps_sleep(void *dev_ctx) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_bus_qspi_ps_sleep(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); +} + + +static void nrf_wifi_bus_qspi_ps_wake(void *dev_ctx) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_bus_qspi_ps_wake(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); +} + + +static int nrf_wifi_bus_qspi_ps_status(void *dev_ctx) +{ + struct nrf_wifi_bus_qspi_dev_ctx *qspi_dev_ctx = NULL; + + qspi_dev_ctx = (struct nrf_wifi_bus_qspi_dev_ctx *)dev_ctx; + + return nrf_wifi_osal_bus_qspi_ps_status(qspi_dev_ctx->qspi_priv->opriv, + qspi_dev_ctx->os_qspi_dev_ctx); +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + +static struct nrf_wifi_bal_ops nrf_wifi_bus_qspi_ops = { + .init = &nrf_wifi_bus_qspi_init, + .deinit = &nrf_wifi_bus_qspi_deinit, + .dev_add = &nrf_wifi_bus_qspi_dev_add, + .dev_rem = &nrf_wifi_bus_qspi_dev_rem, + .dev_init = &nrf_wifi_bus_qspi_dev_init, + .dev_deinit = &nrf_wifi_bus_qspi_dev_deinit, + .read_word = &nrf_wifi_bus_qspi_read_word, + .write_word = &nrf_wifi_bus_qspi_write_word, + .read_block = &nrf_wifi_bus_qspi_read_block, + .write_block = &nrf_wifi_bus_qspi_write_block, + .dma_map = &nrf_wifi_bus_qspi_dma_map, + .dma_unmap = &nrf_wifi_bus_qspi_dma_unmap, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + .rpu_ps_sleep = &nrf_wifi_bus_qspi_ps_sleep, + .rpu_ps_wake = &nrf_wifi_bus_qspi_ps_wake, + .rpu_ps_status = &nrf_wifi_bus_qspi_ps_status, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +}; + + +struct nrf_wifi_bal_ops *get_bus_ops(void) +{ + return &nrf_wifi_bus_qspi_ops; +} diff --git a/nrf_wifi/bus_if/bus/spi/inc/spi.h b/nrf_wifi/bus_if/bus/spi/inc/spi.h new file mode 100644 index 0000000000..effc200a65 --- /dev/null +++ b/nrf_wifi/bus_if/bus/spi/inc/spi.h @@ -0,0 +1,49 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header for the Linux SPI bus layer specific structure declarations of the + * Wi-Fi driver. + */ + +#ifndef __LINUX_SPI_H__ +#define __LINUX_SPI_H__ + +#include "osal_structs.h" +#include "bal_structs.h" + +/** + * struct nrf_wifi_bus_spi_priv - Structure to hold context information for the Linux SPI bus. + * @opriv: Pointer to the OSAL context. + * @os_spi_priv: + * @intr_callbk_fn: + * @cfg_params: + * + * This structure maintains the context information necessary for the operation + * of the Linux SPI bus. Some of the elements of the structure need to be initialized + * during the initialization of the Linux SPI bus while others need to be kept + * updated over the duration of the Linux SPI bus operation. + */ +struct nrf_wifi_bus_spi_priv { + struct nrf_wifi_osal_priv *opriv; + void *os_spi_priv; + + enum nrf_wifi_status (*intr_callbk_fn)(void *hal_ctx); + + /* TODO: See if this can be removed by getting the information from PAL */ + struct nrf_wifi_bal_cfg_params cfg_params; +}; + + +struct nrf_wifi_bus_spi_dev_ctx { + struct nrf_wifi_bus_spi_priv *spi_priv; + void *bal_dev_ctx; + void *os_spi_dev_ctx; + + unsigned long host_addr_base; + unsigned long addr_pktram_base; +}; +#endif /* __LINUX_SPI_H__ */ diff --git a/nrf_wifi/bus_if/bus/spi/src/spi.c b/nrf_wifi/bus_if/bus/spi/src/spi.c new file mode 100644 index 0000000000..bdc2650839 --- /dev/null +++ b/nrf_wifi/bus_if/bus/spi/src/spi.c @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing QSPI Bus Layer specific function definitions of the + * Wi-Fi driver. + */ + +#include "bal_structs.h" +#include "spi.h" +#include "pal.h" + + +static int nrf_wifi_bus_spi_irq_handler(void *data) +{ + struct nrf_wifi_bus_spi_dev_ctx *dev_ctx = NULL; + struct nrf_wifi_bus_spi_priv *spi_priv = NULL; + int ret = 0; + + dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)data; + spi_priv = dev_ctx->spi_priv; + + ret = spi_priv->intr_callbk_fn(dev_ctx->bal_dev_ctx); + + return ret; +} + + +static void *nrf_wifi_bus_spi_dev_add(void *bus_priv, + void *bal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_bus_spi_priv *spi_priv = NULL; + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + struct nrf_wifi_osal_host_map host_map; + + spi_priv = bus_priv; + + spi_dev_ctx = nrf_wifi_osal_mem_zalloc(spi_priv->opriv, + sizeof(*spi_dev_ctx)); + + if (!spi_dev_ctx) { + nrf_wifi_osal_log_err(spi_priv->opriv, + "%s: Unable to allocate spi_dev_ctx\n", __func__); + goto out; + } + + spi_dev_ctx->spi_priv = spi_priv; + spi_dev_ctx->bal_dev_ctx = bal_dev_ctx; + + spi_dev_ctx->os_spi_dev_ctx = nrf_wifi_osal_bus_spi_dev_add(spi_priv->opriv, + spi_priv->os_spi_priv, + spi_dev_ctx); + + if (!spi_dev_ctx->os_spi_dev_ctx) { + nrf_wifi_osal_log_err(spi_priv->opriv, + "%s: nrf_wifi_osal_bus_spi_dev_add failed\n", __func__); + + nrf_wifi_osal_mem_free(spi_priv->opriv, + spi_dev_ctx); + + spi_dev_ctx = NULL; + + goto out; + } + + nrf_wifi_osal_bus_spi_dev_host_map_get(spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + &host_map); + + spi_dev_ctx->host_addr_base = host_map.addr; + + spi_dev_ctx->addr_pktram_base = spi_dev_ctx->host_addr_base + + spi_priv->cfg_params.addr_pktram_base; + + status = nrf_wifi_osal_bus_spi_dev_intr_reg(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + spi_dev_ctx, + &nrf_wifi_bus_spi_irq_handler); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(spi_dev_ctx->spi_priv->opriv, + "%s: Unable to register interrupt to the OS\n", + __func__); + + nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); + + nrf_wifi_osal_bus_spi_dev_rem(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); + + nrf_wifi_osal_mem_free(spi_priv->opriv, + spi_dev_ctx); + + spi_dev_ctx = NULL; + + goto out; + } + +out: + return spi_dev_ctx; +} + + +static void nrf_wifi_bus_spi_dev_rem(void *bus_dev_ctx) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = bus_dev_ctx; + + nrf_wifi_osal_bus_spi_dev_intr_unreg(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); + + nrf_wifi_osal_mem_free(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx); +} + + +static enum nrf_wifi_status nrf_wifi_bus_spi_dev_init(void *bus_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = bus_dev_ctx; + + status = nrf_wifi_osal_bus_spi_dev_init(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(spi_dev_ctx->spi_priv->opriv, + "%s: nrf_wifi_osal_spi_dev_init failed\n", __func__); + + goto out; + } +out: + return status; +} + + +static void nrf_wifi_bus_spi_dev_deinit(void *bus_dev_ctx) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = bus_dev_ctx; + + nrf_wifi_osal_bus_spi_dev_deinit(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); +} + + +static void *nrf_wifi_bus_spi_init(struct nrf_wifi_osal_priv *opriv, + void *params, + enum nrf_wifi_status (*intr_callbk_fn)(void *bal_dev_ctx)) +{ + struct nrf_wifi_bus_spi_priv *spi_priv = NULL; + + spi_priv = nrf_wifi_osal_mem_zalloc(opriv, + sizeof(*spi_priv)); + + if (!spi_priv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate memory for spi_priv\n", + __func__); + goto out; + } + + spi_priv->opriv = opriv; + + nrf_wifi_osal_mem_cpy(opriv, + &spi_priv->cfg_params, + params, + sizeof(spi_priv->cfg_params)); + + spi_priv->intr_callbk_fn = intr_callbk_fn; + + spi_priv->os_spi_priv = nrf_wifi_osal_bus_spi_init(opriv); + if (!spi_priv->os_spi_priv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to register QSPI driver\n", + __func__); + + nrf_wifi_osal_mem_free(opriv, + spi_priv); + + spi_priv = NULL; + + goto out; + } +out: + return spi_priv; +} + + +static void nrf_wifi_bus_spi_deinit(void *bus_priv) +{ + struct nrf_wifi_bus_spi_priv *spi_priv = NULL; + + spi_priv = bus_priv; + + nrf_wifi_osal_bus_spi_deinit(spi_priv->opriv, + spi_priv->os_spi_priv); + + nrf_wifi_osal_mem_free(spi_priv->opriv, + spi_priv); +} + + +static unsigned int nrf_wifi_bus_spi_read_word(void *dev_ctx, + unsigned long addr_offset) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + unsigned int val = 0; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + val = nrf_wifi_osal_spi_read_reg32(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + spi_dev_ctx->host_addr_base + addr_offset); + return val; +} + + +static void nrf_wifi_bus_spi_write_word(void *dev_ctx, + unsigned long addr_offset, + unsigned int val) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_spi_write_reg32(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + spi_dev_ctx->host_addr_base + addr_offset, + val); +} + + +static void nrf_wifi_bus_spi_read_block(void *dev_ctx, + void *dest_addr, + unsigned long src_addr_offset, + size_t len) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_spi_cpy_from(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + dest_addr, + spi_dev_ctx->host_addr_base + src_addr_offset, + len); +} + + +static void nrf_wifi_bus_spi_write_block(void *dev_ctx, + unsigned long dest_addr_offset, + const void *src_addr, + size_t len) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_spi_cpy_to(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx, + spi_dev_ctx->host_addr_base + dest_addr_offset, + src_addr, + len); +} + + +static unsigned long nrf_wifi_bus_spi_dma_map(void *dev_ctx, + unsigned long virt_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + unsigned long phy_addr = 0; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + phy_addr = spi_dev_ctx->host_addr_base + (virt_addr - spi_dev_ctx->addr_pktram_base); + + + return phy_addr; +} + + +static unsigned long nrf_wifi_bus_spi_dma_unmap(void *dev_ctx, + unsigned long phy_addr, + size_t len, + enum nrf_wifi_osal_dma_dir dma_dir) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + unsigned long virt_addr = 0; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + virt_addr = spi_dev_ctx->addr_pktram_base + (phy_addr - spi_dev_ctx->host_addr_base); + + return virt_addr; +} + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +static void nrf_wifi_bus_spi_ps_sleep(void *dev_ctx) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_bus_qspi_ps_sleep(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); +} + + +static void nrf_wifi_bus_spi_ps_wake(void *dev_ctx) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + nrf_wifi_osal_bus_qspi_ps_wake(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); +} + + +static int nrf_wifi_bus_spi_ps_status(void *dev_ctx) +{ + struct nrf_wifi_bus_spi_dev_ctx *spi_dev_ctx = NULL; + + spi_dev_ctx = (struct nrf_wifi_bus_spi_dev_ctx *)dev_ctx; + + return nrf_wifi_osal_bus_qspi_ps_status(spi_dev_ctx->spi_priv->opriv, + spi_dev_ctx->os_spi_dev_ctx); +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + +static struct nrf_wifi_bal_ops nrf_wifi_bus_spi_ops = { + .init = &nrf_wifi_bus_spi_init, + .deinit = &nrf_wifi_bus_spi_deinit, + .dev_add = &nrf_wifi_bus_spi_dev_add, + .dev_rem = &nrf_wifi_bus_spi_dev_rem, + .dev_init = &nrf_wifi_bus_spi_dev_init, + .dev_deinit = &nrf_wifi_bus_spi_dev_deinit, + .read_word = &nrf_wifi_bus_spi_read_word, + .write_word = &nrf_wifi_bus_spi_write_word, + .read_block = &nrf_wifi_bus_spi_read_block, + .write_block = &nrf_wifi_bus_spi_write_block, + .dma_map = &nrf_wifi_bus_spi_dma_map, + .dma_unmap = &nrf_wifi_bus_spi_dma_unmap, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + .rpu_ps_sleep = &nrf_wifi_bus_spi_ps_sleep, + .rpu_ps_wake = &nrf_wifi_bus_spi_ps_wake, + .rpu_ps_status = &nrf_wifi_bus_spi_ps_status, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +}; + + +struct nrf_wifi_bal_ops *get_bus_ops(void) +{ + return &nrf_wifi_bus_spi_ops; +} diff --git a/nrf_wifi/doc/low_api_common.rst b/nrf_wifi/doc/low_api_common.rst new file mode 100644 index 0000000000..c3a8dc7250 --- /dev/null +++ b/nrf_wifi/doc/low_api_common.rst @@ -0,0 +1,12 @@ +Common +###### + +The common API is used for both normal operation and Radio Test mode. + +| Header file: :file:`nrf_wifi/fw_if/umac_if/inc/fmac_structs_common.h` +| Source file: :file:`nrf_wifi/fw_if/umac_if/src/fmac_api_common.c` + + +.. doxygengroup:: nrf_wifi_api_common + :project: nrfxlib + :members: diff --git a/nrf_wifi/doc/low_api_radio_test.rst b/nrf_wifi/doc/low_api_radio_test.rst new file mode 100644 index 0000000000..20fe2b8325 --- /dev/null +++ b/nrf_wifi/doc/low_api_radio_test.rst @@ -0,0 +1,15 @@ +Radio Test mode +############### + +The Radio Test mode is used for testing the RF performance of the nRF70 Series device, mainly to characterize the RF. + +.. note:: + + Documentation for data structure definitions is disabled for this module. + It will be enabled in the future. + +| Source file: :file:`nrf_wifi/fw_if/umac_if/src/radio_test/fmac_api.c` + +.. doxygengroup:: nrf_wifi_api_radio_test + :project: nrfxlib + :members: diff --git a/nrf_wifi/doc/low_api_wifi.rst b/nrf_wifi/doc/low_api_wifi.rst new file mode 100644 index 0000000000..0bf8d81779 --- /dev/null +++ b/nrf_wifi/doc/low_api_wifi.rst @@ -0,0 +1,11 @@ +Wi-Fi mode +########## + +The Wi-Fi mode is used for normal operation of the nRF70 Series device in, for example, STA mode or other modes that are supported in the future. + +| Header file: :file:`nrf_wifi/fw_if/umac_if/inc/default/fmac_api.h` +| Source file: :file:`nrf_wifi/fw_if/umac_if/src/default/fmac_api.c` + +.. doxygengroup:: nrf_wifi_api + :project: nrfxlib + :members: diff --git a/nrf_wifi/fw_if/umac_if/inc/default/fmac_api.h b/nrf_wifi/fw_if/umac_if/inc/default/fmac_api.h new file mode 100644 index 0000000000..373e8d5265 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/default/fmac_api.h @@ -0,0 +1,992 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @file + * + * @addtogroup nrf_wifi_api FMAC API + * @{ + * + * @brief Header containing API declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_API_H__ +#define __FMAC_API_H__ + +#include + +#include "osal_api.h" +#include "host_rpu_umac_if.h" +#include "host_rpu_data_if.h" +#include "host_rpu_sys_if.h" + +#include "fmac_structs.h" +#include "fmac_cmd.h" +#include "fmac_event.h" +#include "fmac_vif.h" +#include "fmac_bb.h" +#include "fmac_api_common.h" + + + +/** + * @brief Initializes the UMAC IF layer. + * + * @param data_config Pointer to configuration of data queues. + * @param rx_buf_pools Pointer to configuration of Rx queue buffers. + * See rx_buf_pool_params + * @param callbk_fns Pointer to callback functions for addressing events + * from the UMAC layer. e.g. callback function to process + * packet received from RPU firmware, scan result etc + * + * This function initializes the UMAC IF layer.It does the following: + * - Creates and initializes the context for the UMAC IF layer. + * - Initializes the HAL layer. + * - Initializes the OS abstraction Layer. + * - Initializes TX queue token sizes. + * - Initializes the RX buffer pool. + * + * @return Pointer to the context of the UMAC IF layer. + */ +struct nrf_wifi_fmac_priv *nrf_wifi_fmac_init(struct nrf_wifi_data_config_params *data_config, + struct rx_buf_pool_params *rx_buf_pools, + struct nrf_wifi_fmac_callbk_fns *callbk_fns); + +/** + * @brief Issue a scan request to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the scan is to be performed. + * @param scan_info The parameters needed by the RPU for scan operation. + * + * This function is used to send a command to: + * Instruct the RPU firmware to trigger a scan. The scan can be performed in two + * modes: + * + * Auto Mode (%AUTO_SCAN): + * In this mode, the host does not need to specify any scan specific + * parameters. The RPU firmware will perform the scan on all the channels + * permitted by and abiding by the regulations imposed by the + * WORLD (common denominator of all regulatory domains) regulatory domain. + * The scan will be performed using the wildcard SSID. + * + * Channel Map Mode (%CHANNEL_MAPPING_SCAN): + * In this mode the host can have fine grained control over the scan + * specific parameters to be used (for example, Passive/Active scan selection, + * Number of probe requests per active scan, Channel list to scan, + * Permanence on each channel, SSIDs to scan etc.). This mode expects + * the regulatory restrictions to be taken care by the invoker of the + * API. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_scan(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_scan_info *scan_info); + + +/** + * @brief Issue a scan results request to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the scan results are to be fetched. + * @param scan_type The scan type (i.e. DISPLAY or CONNECT scan). + * + * This function is used to send a command to: + * - Instruct the RPU firmware to return the results of a scan. + * - scan_type defines if the scan is performed for a + * connection request (SCAN_CONNECT) or to display the + * scan results to user (SCAN_DISPLAY) + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_scan_res_get(void *fmac_dev_ctx, + unsigned char if_idx, + int scan_type); + +/** + * @brief Issue abort of an ongoing scan to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the ongoing scan is to be aborted. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to abort an ongoing scan request + * - The \p if_idx provides the interface index on which the ongoing scan is + * to be aborted + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_abort_scan(void *fmac_dev_ctx, + unsigned char if_idx); + +#if defined(CONFIG_NRF700X_STA_MODE) || defined(__DOXYGEN__) +/** + * @brief Issue an 802.11 authentication request to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the authentication is to be + * performed. + * @param auth_info The parameters needed by the RPU firmware to generate + * the authentication request. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to initiate an authentication + * request to an AP on the interface identified with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_auth(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_auth_info *auth_info); + + +/** + * @brief Issue an 802.11 de-authentication request to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the de-authentication is to be + * performed. + * @param deauth_info De-authentication specific information required by the RPU firmware. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to initiate a de-authentication notification to an AP + * on the interface identified with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_deauth(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_disconn_info *deauth_info); + + +/** + * @brief Issue an 802.11 association request to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the association is to be + * performed. + * @param assoc_info The parameters needed by the RPU firmware to generate the association + * request. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to initiate a association request to an AP on the + * interface identified with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_assoc(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_assoc_info *assoc_info); + + +/** + * @brief Issue an 802.11 disassociation request to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the disassociation is to be + * performed. + * @param disassoc_info Disassociation specific information required by the RPU firmware. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to initiate a disassociation notification to an AP + * on the interface identified with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_disassoc(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_disconn_info *disassoc_info); + + +/** + * @brief Add an 802.11 security key into the RPU security database. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the key is to be added. + * @param key_info Key specific information which needs to be passed to the RPU firmware. + * @param mac_addr MAC address of the peer with which the key is associated. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to add a key to its security database. + * The key is for the peer identified by \p mac_addr on the + * interface identified with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_add_key(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_key_info *key_info, + const char *mac_addr); + + +/** + * @brief Delete an 802.11 key from the RPU security database. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface for which the key is to be deleted. + * @param key_info Key specific information which needs to be passed to the RPU firmware. + * @param mac_addr MAC address of the peer with which the key is associated. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to delete a key from its security database. + * - The key is for the peer identified by \p mac_addr on the + * interface identified with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_del_key(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_key_info *key_info, + const char *mac_addr); + + +/** + * @brief Set a key as a default for data or management + * traffic in the RPU security database. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the key is to be set. + * @param key_info Key specific information which needs to be passed to the RPU firmware. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to set a key as a default key in its security database. + * - The key is either for data or management traffic and is classified based on + * the flags element set in \p key_info parameter. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_key(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_key_info *key_info); + + +/** + * @brief Set BSS parameters for an AP mode interface in the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the BSS parameters are to be set. + * @param bss_info BSS specific parameters which need to be passed to the RPU firmware. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to set the BSS parameter for an AP mode interface. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_bss(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_bss_info *bss_info); + + +/** + * @brief Update the Beacon Template. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the Beacon Template is to be updated. + * @param data Beacon Template which need to be passed to the RPU firmware. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to update beacon template for an AP mode interface. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_chg_bcn(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_set_beacon_info *data); + +/** + * @brief Start a SoftAP. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the SoftAP is to be started. + * @param ap_info AP operation specific parameters which need to be passed to the RPU firmware. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to start a SoftAP on an interface identified with + * \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_start_ap(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_start_ap_info *ap_info); + + +/** + * @brief Stop a SoftAP. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the SoftAP is to be stopped. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to stop a SoftAP on an interface identified with + * \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_stop_ap(void *fmac_dev_ctx, + unsigned char if_idx); + + +/** + * @brief Start P2P mode on an interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the P2P mode is to be started. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to start P2P mode on an interface identified with + * \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_p2p_dev_start(void *fmac_dev_ctx, + unsigned char if_idx); + + +/** + * @brief Start P2P mode on an interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the P2P mode is to be started. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to start P2P mode on an interface identified with + * \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_p2p_dev_stop(void *fmac_dev_ctx, + unsigned char if_idx); + +/** + * @brief Start p2p remain on channel. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface to be kept on channel and stay there. + * @param roc_info Contains channel and time in ms to stay on. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to put p2p device in + * listen state for a duration. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_p2p_roc_start(void *fmac_dev_ctx, + unsigned char if_idx, + struct remain_on_channel_info *roc_info); + +/** + * @brief Stop p2p remain on channel. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface to be kept on channel and stay there. + * @param cookie cancel p2p listen state of the matching cookie. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to put p2p device out + * of listen state. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_p2p_roc_stop(void *fmac_dev_ctx, + unsigned char if_idx, + unsigned long long cookie); + +/** + * @brief Transmit a management frame. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the frame is to be + * transmitted. + * @param mgmt_tx_info Information regarding the management frame to be + * transmitted. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to transmit a management frame. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_mgmt_tx(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_mgmt_tx_info *mgmt_tx_info); + + +/** + * @brief Remove a station. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the STA is connected. + * @param del_sta_info Information regarding the station to be removed. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to remove a station entry and send a + * de-authentication/disassociation frame to the station. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_del_sta(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_del_sta_info *del_sta_info); + + +/** + * @brief Indicate a new STA connection to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the STA is connected. + * @param add_sta_info Information regarding the new station. + * + * This function is used to indicate to the RPU firmware that a new STA has + * successfully connected to the AP. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_add_sta(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_add_sta_info *add_sta_info); + +/** + * @brief Indicate changes to STA connection parameters to the RPU firmware. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the STA is connected. + * @param chg_sta_info Information regarding updates to the station parameters. + * + * This function is used to indicate changes in the connected STA parameters + * to the RPU firmware. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_chg_sta(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_chg_sta_info *chg_sta_info); + + + +/** + * @brief Register the mgmt frame type which needs to be sent up to the host by the RPU firmware. + * + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface from which the received frame is to be + * sent up. + * @param frame_info Information regarding the management frame to be sent up. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to pass frames matching that type/subtype to be + * passed upto the host driver. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_mgmt_frame_reg(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_mgmt_frame_info *frame_info); + +#endif /* CONFIG_NRF700X_STA_MODE */ +/** + * @brief Get unused MAC address from base mac address. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param addr Memory to copy the mac address to. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_mac_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *addr); + +/** + * @brief Assign a index for a new VIF. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * + * This function searches for an unused VIF index and returns it. + * + * @return Index to be used for the new VIF + * In case of error MAX_NUM_VIFS will be returned. + */ +unsigned char nrf_wifi_fmac_vif_idx_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +/** + * @brief Add a new virtual interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param os_vif_ctx Pointer to VIF context that the UMAC IF passes + * up the stack during invocation of callback functions like + * rx_frm_callbk_fn() etc. + * @param vif_info Information regarding the interface to be added. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to add a new interface with parameters specified by + * \p vif_info. + * + * @return Index (maintained by the UMAC IF layer) of the VIF that was added. + * In case of error MAX_NUM_VIFS will be returned. + */ +unsigned char nrf_wifi_fmac_add_vif(void *fmac_dev_ctx, + void *os_vif_ctx, + struct nrf_wifi_umac_add_vif_info *vif_info); + + +/** + * @brief Deletes a virtual interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface to be deleted. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to delete an interface which was added using + * \p nrf_wifi_fmac_add_vif. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_del_vif(void *fmac_dev_ctx, + unsigned char if_idx); + +/** + * @brief Change the attributes of an interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the functionality is to be + * bound. + * @param vif_info Interface specific information which needs to be passed to the + * RPU firmware. + * + * This function is used to change the attributes of an interface identified + * with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_chg_vif(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_chg_vif_attr_info *vif_info); + + +/** + * @brief Change the state of a virtual interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface whose state needs to be changed. + * @param vif_info State information to be changed for the interface. + * + * This function is used to send a command to: + * - Instruct the RPU firmware to change the state of an interface identified by an index + * \p if_idx and parameters specified by \p vif_info. + * - The different states that can be configured are + * - NRF_WIFI_FMAC_IF_OP_STATE_DOWN + * - NRF_WIFI_FMAC_IF_OP_STATE_UP + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_chg_vif_state(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_chg_vif_state_info *vif_info); + + +/** + * @brief Set MAC address on interface. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface whose MAC address is to be changed. + * @param mac_addr MAC address to set. + * + * This function is used to set the MAC address of an interface identified + * with \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_vif_macaddr(void *fmac_dev_ctx, + unsigned char if_idx, + unsigned char *mac_addr); + +/** + * @brief Transmit a frame to the RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the frame is to be + * transmitted. + * @param netbuf Pointer to the OS specific network buffer. + * + * This function takes care of transmitting a frame to the RPU firmware. + * It does the following: + * + * - Queues the frames to a transmit queue. + * - Based on token availability, sends one or more frames to the RPU using + * the command for transmission. + * - The firmware sends an event once the command has + * been processed to indicate whether the frame(s) have been + * transmitted/aborted. + * - The driver can cleanup the frame buffers after receiving this event. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_start_xmit(void *fmac_dev_ctx, + unsigned char if_idx, + void *netbuf); + +/** + * @brief Inform the RPU firmware that host is going to suspend state. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * + * This function is used to send a command to: + * - Inform the RPU firmware that host is going to suspend state. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_suspend(void *fmac_dev_ctx); + + +/** + * @brief Notify RPU firmware that host has resumed from a suspended state. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * + * This function is used to send a command to: + * - Inform the RPU firmware that host has resumed from a suspended state. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_resume(void *fmac_dev_ctx); + + +/** + * @brief Get tx power + * + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx VIF index. + * + * This function is used to send a command to: + * - Get the transmit power on a particular interface given + * by \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_get_tx_power(void *fmac_dev_ctx, + unsigned int if_idx); + +/** + * @brief Get channel definition. + * + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx VIF index. + * + * This function is used to send a command to: + * - Get the channel configured on a particular interface given by /p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_get_channel(void *fmac_dev_ctx, + unsigned int if_idx); + +/** + * @brief Get station statistics + * + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx: VIF index. + * @param mac MAC address of the station. + * + * This function is used to send a command to: + * - Get station statistics using a MAC address. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_get_station(void *fmac_dev_ctx, + unsigned int if_idx, + unsigned char *mac); + + +/* @brief Get interface statistics + * + * @param dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx VIF index. + * + * This function is used to send a command to: + * - Get interface statistics using interface index \p if_idx. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_get_interface(void *dev_ctx, + unsigned int if_idx); + + +/** + * @brief Configure WLAN power management. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which power management is to be set. + * @param state Enable/Disable of WLAN power management. + * + * This function is used to send a command to: + * - The RPU firmware to Enable/Disable WLAN Power management. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_power_save(void *fmac_dev_ctx, + unsigned char if_idx, + bool state); + +/** + * @brief Configure WLAN U-APSD queue. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which power management is to be set. + * @param uapsd_queue Queue to be set for U-APSD. + * + * This function is used to send a command (%NRF_WIFI_UMAC_CMD_CONFIG_UAPSD) to: + * - The RPU firmware to set a U-APSD queue value. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_uapsd_queue(void *fmac_dev_ctx, + unsigned char if_idx, + unsigned int uapsd_queue); + +/** + * @brief Configure Power save timeout. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which power management is to be set. + * @param ps_timeout Power save inactivity time. + * + * This function is used to send a command (%NRF_WIFI_UMAC_CMD_SET_POWER_SAVE_TIMEOUT) to: + * - The RPU firmware to set power save inactivity time. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_power_save_timeout(void *fmac_dev_ctx, + unsigned char if_idx, + int ps_timeout); + +/** + * @brief Configure qos_map of for data + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the qos map be set. + * @param qos_info qos_map information. + * + * This function is used to send a command to: + * - The RPU firmware to set QOS map information. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_qos_map(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_qos_map_info *qos_info); + +/** + * @brief Configure WoWLAN. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param var Wakeup trigger condition. + * + * This function is used to send a command to the RPU firmware to: + * - Configure wakeup trigger condition in RPU. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_wowlan(void *fmac_dev_ctx, + unsigned int var); + +/** + * @brief Get PHY configuration. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the CMD needs to be sent. + * + * This function is used to get PHY configuration from the RPU firmware. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_get_wiphy(void *fmac_dev_ctx, unsigned char if_idx); + +/** + * @brief Register to get MGMT frames. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the CMD needs to be sent. + * @param frame_info Information regarding the management frame. + * + * Register with the RPU firmware to receive specific MGMT frames from the RPU to the host side. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_register_frame(void *fmac_dev_ctx, unsigned char if_idx, + struct nrf_wifi_umac_mgmt_frame_info *frame_info); + +/** + * @brief Set wiphy parameters + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the CMD needs to be sent. + * @param wiphy_info wiphy parameters + * + * This function is used to send a command to the RPU firmware to: + * - Configure parameters interface specific parameters on an interface identified + * by \p if_idx + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ + +enum nrf_wifi_status nrf_wifi_fmac_set_wiphy_params(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_set_wiphy_info *wiphy_info); + +/** + * @brief TWT setup command + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the TWT parameters be set. + * @param twt_info TWT parameters. + * + * This function is used to send a command to the RPU firmware to: + * - Configure TWT setup specific parameters. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_twt_setup(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_config_twt_info *twt_info); + +/** + * @brief TWT teardown command + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which the TWT parameters are to be set. + * @param twt_info TWT parameters. + * + * This function is used to send a command to the RPU firmware to: + * - Tear down an existing TWT session. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_twt_teardown(void *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_config_twt_info *twt_info); + +/** + * @brief Get connection info from RPU + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface. + * + * This function is used to send a command to the RPU firmware to: + * - Fetch connection information. + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_get_conn_info(void *fmac_dev_ctx, + unsigned char if_idx); + +/** + * @brief De-initializes the UMAC IF layer. + * @param fpriv Pointer to the context of the UMAC IF layer. + * + * This function de-initializes the UMAC IF layer of the RPU WLAN FullMAC + * driver. It does the following: + * - De-initializes the HAL layer. + * - Frees the context for the UMAC IF layer. + * + * @return None + */ +void nrf_wifi_fmac_deinit(struct nrf_wifi_fmac_priv *fpriv); + +/** + * @brief Removes a RPU instance. + * @param fmac_dev_ctx Pointer to the context of the RPU instance to be removed. + * + * This is a wrapper function which frees the memory for + * an RPU instance at the UMAC layer. + * + * @return None. + */ +void nrf_wifi_fmac_dev_rem(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + + +/** + * @brief Initializes a RPU instance. + * @param fmac_dev_ctx Pointer to the context of the RPU instance to be removed. + * @param rf_params_usr RF parameters (if any) to be passed to the RPU. + * @param sleep_type Type of RPU sleep. + * @param phy_calib PHY calibration flags to be passed to the RPU. + * @param op_band Operating band of the RPU. + * @param beamforming Enable/disable Wi-Fi beamforming. + * @param tx_pwr_ctrl_params TX power control parameters to be passed to the RPU. + * @param tx_pwr_ceil_params TX power ceil parameters for both frequency bands. + * + * This function initializes the firmware of an RPU instance. The following is addressed + * - BAL layer device initialization + * - HAL layer device initialization + * - FW initialization and PHY calibration data is sent to PHY + * - RX and TX buffers are initialized, tasklets assigned + * + * @retval NRF_WIFI_STATUS_SUCCESS On success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *rf_params_usr, +#if defined(CONFIG_NRF_WIFI_LOW_POWER) || defined(__DOXYGEN__) + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params, + struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params); + + +/** + * @brief De-initializes a RPU instance. + * @param fmac_dev_ctx Pointer to the context of the RPU instance to be removed. + * + * This function de-initializes the firmware of an RPU instance. + * - RPU UMAC deinitialization command is executed + * - RX and TX is deallocated for firmware via UMAC command + * + * @return None. + */ +void nrf_wifi_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +/** + * @brief Configure WLAN listen interval. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which power management is to be set. + * @param listen_interval listen interval to be configured. + * + * This function is used to send a command to RPU to configure listen interval. + * Refer section 9.4.1.6 is 802.11-2020 standard for details on listen interval + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_listen_interval(void *fmac_dev_ctx, + unsigned char if_idx, + unsigned short listen_interval); + +/** + * @brief Configure WLAN PS wakeup mode to DTIM interval or listen interval. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which power management is to be set. + * @param ps_wakeup_mode Enable listen interval based ps(default is DTIM based) + * + * This function is used to configure PS wakeup mode, PS wakeup mode can be + * configured to: + * - DTIM interval based PS mode + * - Listen interval based PS mode + * Default mode is set to DTIM interval based PS mode + * + *@retval NRF_WIFI_STATUS_SUCCESS On success + *@retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_ps_wakeup_mode(void *fmac_dev_ctx, + unsigned char if_idx, + bool ps_wakeup_mode); +/** + * @} + */ +#endif /* __FMAC_API_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h b/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h new file mode 100644 index 0000000000..c4453012af --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/default/fmac_structs.h @@ -0,0 +1,433 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @file + * + * @addtogroup nrf_wifi_api FMAC API + * @{ + * + * @brief Header containing declarations for utility functions for + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_STRUCTS_H__ +#define __FMAC_STRUCTS_H__ + +#include + +#include "osal_api.h" +#include "host_rpu_umac_if.h" +#include "fmac_structs_common.h" + +#define MAX_PEERS 5 +#define MAX_SW_PEERS (MAX_PEERS + 1) +#define NRF_WIFI_AC_TWT_PRIORITY_EMERGENCY 0xFF + + +/** + * @brief WLAN access categories. + * + */ +enum nrf_wifi_fmac_ac { + /** Background access category. */ + NRF_WIFI_FMAC_AC_BK, + /** Best-effort access category. */ + NRF_WIFI_FMAC_AC_BE, + /** Video access category. */ + NRF_WIFI_FMAC_AC_VI, + /** Voice access category. */ + NRF_WIFI_FMAC_AC_VO, + /** Multicast access category. */ + NRF_WIFI_FMAC_AC_MC, + /** Maximum number of WLAN access categories. */ + NRF_WIFI_FMAC_AC_MAX +}; + + +/** + * @brief The operational state of an interface. + * + */ +enum nrf_wifi_fmac_if_op_state { + /** Interface is non-operational. */ + NRF_WIFI_FMAC_IF_OP_STATE_DOWN, + /** Interface is operational. */ + NRF_WIFI_FMAC_IF_OP_STATE_UP, + /** Invalid value. Used for error checks. */ + NRF_WIFI_FMAC_IF_OP_STATE_INVALID +}; + + +/** + * @brief The carrier state of an interface. + * + */ +enum nrf_wifi_fmac_if_carr_state { + /** Interface is not ready. */ + NRF_WIFI_FMAC_IF_CARR_STATE_OFF, + /** Interface is ready. */ + NRF_WIFI_FMAC_IF_CARR_STATE_ON, + /** Invalid value. Used for error checks. */ + NRF_WIFI_FMAC_IF_CARR_STATE_INVALID +}; + + +/** + * @brief Callback functions to be invoked by UMAC IF layer when a particular event occurs. + * + * This structure contains function pointers to all the callback functions that + * the UMAC IF layer needs to invoke for various events. + */ +struct nrf_wifi_fmac_callbk_fns { + /** Callback function to be called when a scan is started. */ + void (*scan_start_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_trigger_scan *scan_start_event, + unsigned int event_len); + + /** Callback function to be called when a scan is done. */ + void (*scan_done_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_trigger_scan *scan_done_event, + unsigned int event_len); + + /** Callback function to be called when a scan is aborted. */ + void (*scan_abort_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_trigger_scan *scan_done_event, + unsigned int event_len); + + /** Callback function to be called when a scan result is received. */ + void (*scan_res_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_new_scan_results *scan_res, + unsigned int event_len, + bool more_res); + + /** Callback function to be called when a display scan result is received. */ + void (*disp_scan_res_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_new_scan_display_results *scan_res, + unsigned int event_len, + bool more_res); + +#if defined(CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS) || defined(__DOXYGEN__) + /** Callback function to be called when a beacon/probe response is received. */ + void (*rx_bcn_prb_resp_callbk_fn)(void *os_vif_ctx, + void *frm, + unsigned short frequency, + signed short signal); +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + +#if defined(CONFIG_NRF700X_STA_MODE) || defined(__DOXYGEN__) + /** Callback function to be called when an interface association state changes. */ + enum nrf_wifi_status (*if_carr_state_chg_callbk_fn)(void *os_vif_ctx, + enum nrf_wifi_fmac_if_carr_state cs); + + /** Callback function to be called when a frame is received. */ + void (*rx_frm_callbk_fn)(void *os_vif_ctx, + void *frm); + + /** Callback function to be called when an authentication response is received. */ + void (*auth_resp_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *auth_resp_event, + unsigned int event_len); + + /** Callback function to be called when an association response is received. */ + void (*assoc_resp_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *assoc_resp_event, + unsigned int event_len); + + /** Callback function to be called when a deauthentication frame is received. */ + void (*deauth_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *deauth_event, + unsigned int event_len); + + /** Callback function to be called when a disassociation frame is received. */ + void (*disassoc_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *disassoc_event, + unsigned int event_len); + + /** Callback function to be called when a management frame is received. */ + void (*mgmt_rx_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *mgmt_rx_event, + unsigned int event_len); + + /** Callback function to be called when an unprotected management frame is received. */ + void (*unprot_mlme_mgmt_rx_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *unprot_mlme_event, + unsigned int event_len); + + /** Callback function to be called when a get TX power response is received. */ + void (*tx_pwr_get_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_get_tx_power *info, + unsigned int event_len); + + /** Callback function to be called when a get channel response is received. */ + void (*chnl_get_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_get_channel *info, + unsigned int event_len); + + /** Callback function to be called when a cookie response is received. */ + void (*cookie_rsp_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_cookie_rsp *cookie_rsp, + unsigned int event_len); + + /** Callback function to be called when a TX status is received. */ + void (*tx_status_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_mlme *tx_status_event, + unsigned int event_len); + + /** Callback function to be called when a set interface response is received. */ + void (*set_if_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_set_interface *set_if_event, + unsigned int event_len); + + /** Callback function to be called when a remain on channel response is received. */ + void (*roc_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_event_remain_on_channel *roc_event, + unsigned int event_len); + + /** Callback function to be called when a remain on channel cancel response is received. */ + void (*roc_cancel_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_event_remain_on_channel *roc_cancel_event, + unsigned int event_len); + + /** Callback function to be called when a get station response is received. */ + void (*get_station_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_new_station *info, + unsigned int event_len); + + /** Callback function to be called when a get interface response is received. */ + void (*get_interface_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_interface_info *info, + unsigned int event_len); + + /** Callback function to be called when a management TX status is received. */ + void (*mgmt_tx_status)(void *if_priv, + struct nrf_wifi_umac_event_mlme *mlme_event, + unsigned int event_len); + + /** Callback function to be called when a TWT configuration response is received. */ + void (*twt_config_callbk_fn)(void *if_priv, + struct nrf_wifi_umac_cmd_config_twt *twt_config_event_info, + unsigned int event_len); + + /** Callback function to be called when a TWT teardown response is received. */ + void (*twt_teardown_callbk_fn)(void *if_priv, + struct nrf_wifi_umac_cmd_teardown_twt *twt_teardown_event_info, + unsigned int event_len); + + /** Callback function to be called when a get wiphy response is received. */ + void (*event_get_wiphy)(void *if_priv, + struct nrf_wifi_event_get_wiphy *get_wiphy, + unsigned int event_len); + + /** Callback function to be called when a TWT sleep response is received. */ + void (*twt_sleep_callbk_fn)(void *if_priv, + struct nrf_wifi_umac_event_twt_sleep *twt_sleep_event_info, + unsigned int event_len); + + /** Callback function to be called when a get regulatory response is received. */ + void (*event_get_reg)(void *if_priv, + struct nrf_wifi_reg *get_reg, + unsigned int event_len); + + /** Callback function to be called when a get power save information + * response is received. + */ + void (*event_get_ps_info)(void *if_priv, + struct nrf_wifi_umac_event_power_save_info *get_ps_config, + unsigned int event_len); + + /** Callback function to be called when a get connection info response is received. */ + void (*get_conn_info_callbk_fn)(void *os_vif_ctx, + struct nrf_wifi_umac_event_conn_info *info, + unsigned int event_len); + + /** Callback function to be called when rssi is to be processed from the received frame. */ + void (*process_rssi_from_rx)(void *os_vif_ctx, + signed short signal); +#endif /* CONFIG_NRF700X_STA_MODE */ +}; + +#if defined(CONFIG_NRF700X_STA_MODE) || defined(__DOXYGEN__) +/** + * @brief The TWT sleep state of device. + * + */ +enum nrf_wifi_fmac_twt_state { + /** RPU in TWT sleep state. */ + NRF_WIFI_FMAC_TWT_STATE_SLEEP, + /** RPU in TWT awake state. */ + NRF_WIFI_FMAC_TWT_STATE_AWAKE +}; + +/** + * @brief Structure to hold peer context information. + * + * This structure holds context information for a peer that the RPU is + * connected with. + */ +struct peers_info { + /** Peer ID. */ + int peer_id; + /** VIF index. */ + unsigned char if_idx; + /** Power save state. */ + unsigned char ps_state; + /** Legacy or HT/VHT/HE. */ + unsigned char is_legacy; + /** QoS supported. */ + unsigned char qos_supported; + /** Pending queue bitmap. */ + unsigned char pend_q_bmp; + /** Receiver address. */ + unsigned char ra_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Pairwise cipher. */ + unsigned int pairwise_cipher; + /** 802.11 power save token count. */ + int ps_token_count; +}; + +/** + * @brief Structure to hold transmit path context information. + * + */ +struct tx_config { + /** Lock used to make code portions in the TX path atomic. */ + void *tx_lock; + /** Context information about peers that the RPU firmware is connected to. */ + struct peers_info peers[MAX_SW_PEERS]; + /** Coalesce count of TX frames. */ + unsigned int *send_pkt_coalesce_count_p; + /** per-peer/per-AC Queue for frames waiting to be passed to the RPU firmware for TX. */ + void *data_pending_txq[MAX_SW_PEERS][NRF_WIFI_FMAC_AC_MAX]; + /** Queue for peers which have woken up from 802.11 power save. */ + void *wakeup_client_q; + /** Used to store tx descs(buff pool ids). */ + unsigned long *buf_pool_bmp_p; + /** TX descriptors which have been queued to the RPU firmware. */ + unsigned int outstanding_descs[NRF_WIFI_FMAC_AC_MAX]; + /** Peer who will be get the next opportunity for TX. */ + unsigned int curr_peer_opp[NRF_WIFI_FMAC_AC_MAX]; + /** Access category which will get the next spare descriptor. */ + unsigned int next_spare_desc_ac; + /** Frame context information. */ + struct tx_pkt_info *pkt_info_p; + /** Map for the spare descriptor queues + * - First four bits : Spare desc1 queue number, + * - Second four bits: Spare desc2 queue number. + */ + unsigned int spare_desc_queue_map; +#if defined(CONFIG_NRF700X_TX_DONE_WQ_ENABLED) || defined(__DOXYGEN__) + /** Queue for TX done tasklet. */ + void *tx_done_tasklet_event_q; +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ +}; +#endif /* CONFIG_NRF700X_STA_MODE */ + +/** + * @brief Structure to hold context information for the UMAC IF layer. + * + * This structure maintains the context information necessary for the + * operation of the UMAC IF layer. + */ +struct nrf_wifi_fmac_priv_def { + /** Callback functions to be called on various events. */ + struct nrf_wifi_fmac_callbk_fns callbk_fns; + /** Data path configuration parameters. */ + struct nrf_wifi_data_config_params data_config; + /** RX buffer pool configuration data. */ + struct rx_buf_pool_params rx_buf_pools[MAX_NUM_OF_RX_QUEUES]; + /** Starting RX descriptor number for a RX buffer pool. */ + unsigned int rx_desc[MAX_NUM_OF_RX_QUEUES]; + /** Maximum number of host buffers needed for RX frames. */ + unsigned int num_rx_bufs; +#if defined(CONFIG_NRF700X_STA_MODE) + /** Maximum number of tokens available for TX. */ + unsigned char num_tx_tokens; + /** Maximum number of TX tokens available reserved per AC. */ + unsigned char num_tx_tokens_per_ac; + /** Number of spare tokens (common to all ACs) available for TX. */ + unsigned char num_tx_tokens_spare; + /** Maximum supported AMPDU length per token. */ + unsigned int max_ampdu_len_per_token; + /** Available (remaining) AMPDU length per token. */ + unsigned int avail_ampdu_len_per_token; +#endif /* CONFIG_NRF700X_STA_MODE */ +}; + +/** + * @brief Structure to hold per device context information for the UMAC IF layer. + * + * This structure maintains the context information necessary for the + * a single instance of an FullMAC based RPU. + */ +struct nrf_wifi_fmac_dev_ctx_def { + /** Array of pointers to virtual interfaces created on this device. */ + struct nrf_wifi_fmac_vif_ctx *vif_ctx[MAX_NUM_VIFS]; +#if defined(CONFIG_NRF700X_RX_WQ_ENABLED) + /** Tasklet for RX. */ + void *rx_tasklet; + /** Queue for RX tasklet. */ + void *rx_tasklet_event_q; +#endif /* CONFIG_NRF700X_RX_WQ_ENABLED */ + /** Host statistics. */ + struct rpu_host_stats host_stats; + /** Number of interfaces in STA mode. */ + unsigned char num_sta; + /** Number of interfaces in AP mode. */ + unsigned char num_ap; + /** Queue for storing mapping info of RX buffers. */ + struct nrf_wifi_fmac_buf_map_info *rx_buf_info; +#if defined(CONFIG_NRF700X_STA_MODE) + /** Queue for storing mapping info of TX buffers. */ + struct nrf_wifi_fmac_buf_map_info *tx_buf_info; + /** Context information related to TX path. */ + struct tx_config tx_config; + /** TWT state of the RPU. */ + enum nrf_wifi_fmac_twt_state twt_sleep_status; +#if defined(CONFIG_NRF700X_TX_DONE_WQ_ENABLED) + /** Tasklet for TX done. */ + void *tx_done_tasklet; +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ +#endif /* CONFIG_NRF700X_STA_MODE */ +}; + +/** + * @brief Structure to hold per VIF context information for the UMAC IF layer. + * + * This structure maintains the context information necessary for the + * a single instance of an VIF. + */ +struct nrf_wifi_fmac_vif_ctx { + /** Handle to the FMAC IF abstraction layer. */ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx; + /** Handle to the OS abstraction layer. */ + void *os_vif_ctx; + /** MAC address of the VIF. */ + char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Groupwise cipher being used on this VIF. */ + int groupwise_cipher; + /** Interface flags related to this VIF. */ + bool ifflags; + /** Interface type of this VIF. */ + int if_type; + /** BSSID of the AP to which this VIF is connected (applicable only in STA mode). */ + unsigned char bssid[NRF_WIFI_ETH_ADDR_LEN]; +}; + +/** + * @brief Structure to hold TX/RX buffer pool configuration data. + * + */ +struct nrf_wifi_fmac_buf_map_info { + /** Flag indicating whether the buffer is mapped or not. */ + bool mapped; + /** The number of words in the buffer. */ + unsigned long nwb; +}; + +/** + * @} + */ +#endif /* __FMAC_STRUCTS_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_ap.h b/nrf_wifi/fw_if/umac_if/inc/fmac_ap.h new file mode 100644 index 0000000000..9f909a41c4 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_ap.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing SoftAP specific declarations for the FMAC IF Layer + * of the Wi-Fi driver. + */ + +#ifndef __FMAC_AP_H__ +#define __FMAC_AP_H__ + +#include "host_rpu_data_if.h" +#include "fmac_structs.h" + + +enum nrf_wifi_status sap_client_update_pmmode(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_sap_client_pwrsave *config); + +enum nrf_wifi_status sap_client_ps_get_frames(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_sap_ps_get_frames *config); +#endif /* __FMAC_AP_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_api_common.h b/nrf_wifi/fw_if/umac_if/inc/fmac_api_common.h new file mode 100644 index 0000000000..2a561bdf00 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_api_common.h @@ -0,0 +1,232 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @file + * + * @addtogroup nrf_wifi_api_common FMAC API common + * @{ + * + * @brief Header containing API declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ +#ifndef __FMAC_API_COMMON_H__ +#define __FMAC_API_COMMON_H__ + +#include + +#include "osal_api.h" +#include "host_rpu_umac_if.h" +#include "host_rpu_data_if.h" +#include "host_rpu_sys_if.h" + +#include "fmac_structs.h" +#include "fmac_cmd.h" +#include "fmac_event.h" +#include "fmac_vif.h" +#include "fmac_bb.h" + +/** + * @brief Adds a RPU instance. + * @param fpriv Pointer to the context of the UMAC IF layer. + * @param os_dev_ctx Pointer to the OS specific context of the RPU instance. + * + * This function adds an RPU instance. This function will return the + * pointer to the context of the RPU instance. This pointer will need to be + * supplied while invoking further device specific APIs, + * for example, nrf_wifi_fmac_scan() etc. + * + * @return Pointer to the context of the RPU instance. + */ +struct nrf_wifi_fmac_dev_ctx *nrf_wifi_fmac_dev_add(struct nrf_wifi_fmac_priv *fpriv, + void *os_dev_ctx); + +/** + * @brief Issue a request to get stats from the RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param op_mode RPU operation mode. + * @param stats Pointer to memory where the stats are to be copied. + * + * This function is used to send a command to + * instruct the firmware to return the current RPU statistics. The RPU will + * send the event with the current statistics. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + enum rpu_op_mode op_mode, + struct rpu_op_stats *stats); + + +/** + * @brief Loads the Firmware(s) to the RPU WLAN device. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device, + * which was passed as \p fmac_dev_ctx parameter via the + * \p add_dev_callbk_fn() callback function. + * @param fmac_fw Information about the FullMAC firmware(s) to be loaded. + * + * This function loads the FullMAC firmware(s) to the RPU WLAN device. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_fw_load(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_fmac_fw_info *fmac_fw); + + +/** + * @brief Get FW versions from the RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param fw_ver Pointer to the address where the FW versions needs to be copied. + * + * This function is used to get Firmware versions from the RPU. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_ver_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int *fw_ver); + +/** + * @brief Configure HE LTF and GI parameters. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param he_ltf HE LTF parameter which will be configured in RPU. + * @param he_gi HE GI parameter which will be configured in RPU. + * @param enabled enable/disable HE LTF and GI parameter configured. + * + * This function is used to send a command to RPU + * to configure HE LTF and GI parameters in RPU. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_conf_ltf_gi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char he_ltf, + unsigned char he_gi, + unsigned char enabled); + +#if defined(CONFIG_NRF700X_UTIL) || defined(__DOXYGEN__) +enum nrf_wifi_status nrf_wifi_fmac_set_tx_rate(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char rate_flag, + int data_rate); +#if defined(CONFIG_NRF_WIFI_LOW_POWER) || defined(__DOXYGEN__) +/** + * @brief Get the RPU power save status from host perspective. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param rpu_ps_ctrl_state Pointer to the address where the current RPU power save state + * from host perspective needs to be copied. + * + * This function is used to fetch the RPU power save status + * from host perspective. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_get_host_rpu_ps_ctrl_state(void *fmac_dev_ctx, + int *rpu_ps_ctrl_state); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +#endif /* CONFIG_NRF700X_UTIL */ +/** + * @brief Configure Bluetooth coexistence parameters in RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param cmd Bluetooth coexistence parameters which will be configured in RPU. + * @param cmd_len Command length. + * + * This function is used to send a command to RPU to configure + * Bluetooth coexistence parameters in RPU. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_conf_btcoex(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *cmd, unsigned int cmd_len); + + +/** + * @brief Set the Multicast filter address. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface whose state needs to be changed. + * @param mcast_info Multicast information to be set. + * + * This function is used to send a command (%NRF_WIFI_UMAC_CMD_MCAST_FILTER) to + * instruct the firmware to set the multicast filter address to an interface + * with index \p if_idx and parameters specified by \p mcast_info. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_set_mcast_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_mcast_cfg *mcast_info); + + +/** + * @brief Fetch MAC address from OTP. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param vif_idx Interface index for which the MAC address is to be fetched. + * @param mac_addr Pointer to the address where the MAC address needs to be copied. + * + * This function is used to fetch MAC address from the OTP. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_otp_mac_addr_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char vif_idx, + unsigned char *mac_addr); + + +/** + * @brief Get the RF parameters to be programmed to the RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param rf_params Pointer to the address where the RF params information needs to be copied. + * @param tx_pwr_ceil_params Pointer to the address where TX ceil information is available for + * both frequency bands. + * + * This function is used to fetch RF parameters information from the RPU and + * update the default RF parameter with the OTP values. The updated RF + * parameters are then returned in the \p f_params. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_params_get( + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *rf_params, + struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params); + +/** + * @brief Set regulatory domain in RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param reg_info Pointer to the address where the regulatory domain information. + * needs to be copied. + * This function is used to set regulatory domain in the RPU. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_set_reg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_fmac_reg_info *reg_info); + +/** + * @brief Get regulatory domain from RPU. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param reg_info Pointer to the address where the regulatory domain information. + * needs to be copied. + * This function is used to get regulatory domain from the RPU. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_get_reg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_fmac_reg_info *reg_info); + +/** + * @brief Get the current power save information. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param if_idx Index of the interface on which power management is to be set. + * + * This function is used to send a command + * to RPU to Enable/Disable WLAN Power management. + * + * @return Command execution status + */ +enum nrf_wifi_status nrf_wifi_fmac_get_power_save_info(void *fmac_dev_ctx, + unsigned char if_idx); + +/** + * @} + */ +#endif /* __FMAC_API_COMMON_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_bb.h b/nrf_wifi/fw_if/umac_if/inc/fmac_bb.h new file mode 100644 index 0000000000..8cd7fb13a8 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_bb.h @@ -0,0 +1,24 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing bounce buffer specific declarations for the FMAC IF Layer + * of the Wi-Fi driver. + */ + +#ifndef __FMAC_BB_H__ +#define __FMAC_BB_H__ + +#define HOST_PKTRAM_BB_START 0x02C00000 +#define HOST_PKTRAM_BB_LEN (4 * 1024 * 1024) + +#ifndef VIRT_TO_PHYS +#define VIRT_TO_PHYS(addr) (HOST_PKTRAM_BB_START + (addr - fmac_ctx->base_addr_host_pktram_bb)) +#endif + +void bb_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +#endif /* __FMAC_BB_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_cmd.h b/nrf_wifi/fw_if/umac_if/inc/fmac_cmd.h new file mode 100644 index 0000000000..97e3b59d64 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_cmd.h @@ -0,0 +1,74 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing command specific declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_CMD_H__ +#define __FMAC_CMD_H__ + +#define NRF_WIFI_FMAC_STATS_RECV_TIMEOUT 50 /* ms */ +#define NRF_WIFI_FMAC_PS_CONF_EVNT_RECV_TIMEOUT 50 /* ms */ +#ifdef CONFIG_NRF700X_RADIO_TEST +#define NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT 50 /* 5s */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + +struct host_rpu_msg *umac_cmd_alloc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int type, + int size); + +enum nrf_wifi_status umac_cmd_cfg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *params, + int len); + +enum nrf_wifi_status umac_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#ifndef CONFIG_NRF700X_RADIO_TEST + unsigned char *rf_params, + bool rf_params_valid, + struct nrf_wifi_data_config_params *config, +#endif /* !CONFIG_NRF700X_RADIO_TEST */ +#ifdef CONFIG_NRF_WIFI_LOW_POWER + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params); + +enum nrf_wifi_status umac_cmd_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +enum nrf_wifi_status umac_cmd_btcoex(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *cmd, unsigned int cmd_len); + +enum nrf_wifi_status umac_cmd_he_ltf_gi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char he_ltf, + unsigned char he_gi, + unsigned char enabled); + +#ifdef CONFIG_NRF700X_RADIO_TEST +enum nrf_wifi_status umac_cmd_prog_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_radio_test_init_info *init_params); + +enum nrf_wifi_status umac_cmd_prog_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params); + +enum nrf_wifi_status umac_cmd_prog_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_rx_radio_test_params *rx_params); + +enum nrf_wifi_status umac_cmd_prog_rf_test(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *rf_test_params, + unsigned int rf_test_params_sz); +#endif /* CONFIG_NRF700X_RADIO_TEST */ + +enum nrf_wifi_status umac_cmd_prog_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#ifdef CONFIG_NRF700X_RADIO_TEST + int op_mode, +#endif /* CONFIG_NRF700X_RADIO_TEST */ + int stat_type); + +#endif /* __FMAC_CMD_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_event.h b/nrf_wifi/fw_if/umac_if/inc/fmac_event.h new file mode 100644 index 0000000000..a0d2b8a837 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_event.h @@ -0,0 +1,32 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing event specific declarations for the FMAC IF Layer + * of the Wi-Fi driver. + */ + +#ifndef __FMAC_EVENT_H__ +#define __FMAC_EVENT_H__ + +/** + * nrf_wifi_fmac_event_callback() - RPU event classifier and handler. + * @data: Pointer to the device driver context. + * @event_data: Pointer to event data. + * @len: Length of event data pointed to by @event_data. + * + * This callback classifies and processes an event. This classification of the + * event is based on whether it contains data or control messages + * and invokes further handlers based on that. + * + * Return: Status + * Pass: NRF_WIFI_STATUS_SUCCESS + * Fail: NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status nrf_wifi_fmac_event_callback(void *data, + void *event_data, + unsigned int len); +#endif /* __FMAC_EVENT_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_peer.h b/nrf_wifi/fw_if/umac_if/inc/fmac_peer.h new file mode 100644 index 0000000000..9c2a6247df --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_peer.h @@ -0,0 +1,33 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing peer handling specific declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_PEER_H__ +#define __FMAC_PEER_H__ + +#include "fmac_structs.h" + +int nrf_wifi_fmac_peer_get_id(struct nrf_wifi_fmac_dev_ctx *fmac_ctx, + const unsigned char *mac_addr); + +int nrf_wifi_fmac_peer_add(struct nrf_wifi_fmac_dev_ctx *fmac_ctx, + unsigned char if_idx, + const unsigned char *mac_addr, + unsigned char is_legacy, + unsigned char qos_supported); + +void nrf_wifi_fmac_peer_remove(struct nrf_wifi_fmac_dev_ctx *fmac_ctx, + unsigned char if_idx, + int peer_id); + +void nrf_wifi_fmac_peers_flush(struct nrf_wifi_fmac_dev_ctx *fmac_ctx, + unsigned char if_idx); + +#endif /* __FMAC_PEER_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_rx.h b/nrf_wifi/fw_if/umac_if/inc/fmac_rx.h new file mode 100644 index 0000000000..ee9fb85021 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_rx.h @@ -0,0 +1,42 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing RX data path specific declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_RX_H__ +#define __FMAC_RX_H__ + +#include "host_rpu_data_if.h" +#include "fmac_structs.h" + +#define RX_BUF_HEADROOM 4 + +enum nrf_wifi_fmac_rx_cmd_type { + NRF_WIFI_FMAC_RX_CMD_TYPE_INIT, + NRF_WIFI_FMAC_RX_CMD_TYPE_DEINIT, + NRF_WIFI_FMAC_RX_CMD_TYPE_MAX, +}; + + +struct nrf_wifi_fmac_rx_pool_map_info { + unsigned int pool_id; + unsigned int buf_id; +}; + + +enum nrf_wifi_status nrf_wifi_fmac_rx_cmd_send(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + enum nrf_wifi_fmac_rx_cmd_type cmd_type, + unsigned int desc_id); + +enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_rx_buff *config); + +void nrf_wifi_fmac_rx_tasklet(void *data); + +#endif /* __FMAC_RX_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_structs_common.h b/nrf_wifi/fw_if/umac_if/inc/fmac_structs_common.h new file mode 100644 index 0000000000..8395777cb0 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_structs_common.h @@ -0,0 +1,146 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @file + * + * @addtogroup nrf_wifi_api_common FMAC API common + * @{ + * + * @brief Header containing declarations for utility functions for + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_STRUCTS_COMMON_H__ +#define __FMAC_STRUCTS_COMMON_H__ + +#include + +#include "osal_api.h" +#include "host_rpu_umac_if.h" + +/** + * @brief Structure to hold host specific statistics. + * + */ +struct rpu_host_stats { + /** Total number of TX frames transmitted. */ + unsigned long long total_tx_pkts; + /** Total number of TX dones received. */ + unsigned long long total_tx_done_pkts; + /** Total number of TX frames dropped. */ + unsigned long long total_tx_drop_pkts; + /** Total number of RX frames received. */ + unsigned long long total_rx_pkts; + /** Total number of RX frames dropped. */ + unsigned long long total_rx_drop_pkts; +}; + +/** + * @brief - Structure to hold per device host and firmware statistics. + * + */ +struct rpu_op_stats { + /** Host statistics. */ + struct rpu_host_stats host; + /** Firmware statistics. */ + struct rpu_fw_stats fw; +}; + +/** + * @brief Structure to hold FW patch information. + * + */ +struct nrf_wifi_fw_info { + /** Pointer to the FW patch data. */ + void *data; + /** Size of the FW patch data. */ + unsigned int size; +}; + + +/** + * @brief Structure to hold FW patch information for LMAC and UMAC. + * + */ +struct nrf_wifi_fmac_fw_info { + /** Primary LMAC FW patch information. */ + struct nrf_wifi_fw_info lmac_patch_pri; + /** Secondary LMAC FW patch information. */ + struct nrf_wifi_fw_info lmac_patch_sec; + /** Primary UMAC FW patch information. */ + struct nrf_wifi_fw_info umac_patch_pri; + /** Secondary UMAC FW patch information. */ + struct nrf_wifi_fw_info umac_patch_sec; +}; + + +/** + * @brief Structure to hold OTP region information. + * + */ +struct nrf_wifi_fmac_otp_info { + /** OTP region information. */ + struct host_rpu_umac_info info; + /** Flags indicating which OTP regions are valid. */ + unsigned int flags; +}; + +/** + * @brief Structure to hold Regulatory parameter data. + * + */ +struct nrf_wifi_fmac_reg_info { + /** ISO IEC Country code. */ + unsigned char alpha2[NRF_WIFI_COUNTRY_CODE_LEN]; + /** Forcefully set regulatory. */ + bool force; +}; + +/** + * @brief Structure to hold common fmac priv parameter data. + * + */ +struct nrf_wifi_fmac_priv { + /** Handle to the OS abstraction layer. */ + struct nrf_wifi_osal_priv *opriv; + /** Handle to the HAL layer. */ + struct nrf_wifi_hal_priv *hpriv; + /** Data pointer to mode specific parameters */ + char priv[]; +}; + +/** + * @brief Structure to hold common fmac dev context parameter data. + * + */ +struct nrf_wifi_fmac_dev_ctx { + /** Handle to the FMAC IF abstraction layer. */ + struct nrf_wifi_fmac_priv *fpriv; + /** Handle to the OS abstraction layer. */ + void *os_dev_ctx; + /** Handle to the HAL layer. */ + void *hal_dev_ctx; + /** Firmware statistics. */ + struct rpu_fw_stats *fw_stats; + /** Firmware statistics requested. */ + bool stats_req; + /** Firmware boot done. */ + bool fw_boot_done; + /** Firmware init done. */ + bool fw_init_done; + /** Firmware deinit done. */ + bool fw_deinit_done; + /** Alpha2 valid. */ + bool alpha2_valid; + /** Alpha2 country code, last byte is reserved for null character. */ + unsigned char alpha2[3]; + /** Data pointer to mode specific parameters */ + char priv[]; +}; +/** + * @} + */ +#endif /* __FMAC_STRUCTS_COMMON_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_tx.h b/nrf_wifi/fw_if/umac_if/inc/fmac_tx.h new file mode 100644 index 0000000000..cb9adf4797 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_tx.h @@ -0,0 +1,75 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing TX data path specific declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_TX_H__ +#define __FMAC_TX_H__ + +#include "host_rpu_data_if.h" +#include "fmac_structs.h" + +#define TX_DESC_BUCKET_BOUND 32 +#define DOT11_WMM_PARAMS_LEN 2 + +/* 4 bits represent 4 access categories. + * (VOVIBEBO) respectively + */ +#define SPARE_DESC_Q_MAP_SIZE 4 + +/** + * enum nrf_wifi_fmac_tx_status - The status of a TX operation performed by the + * RPU driver. + * @NRF_WIFI_FMAC_TX_STATUS_SUCCESS: The TX operation was successful (sent packet to RPU). + * @NRF_WIFI_FMAC_TX_STATUS_QUEUED: The TX operation was successful (packet queued in driver). + * @NRF_WIFI_FMAC_TX_STATUS_FAIL: The TX operation failed. + * + * This enum lists the possible outcomes of a TX operation performed by the + * RPU driver. + */ +enum nrf_wifi_fmac_tx_status { + NRF_WIFI_FMAC_TX_STATUS_SUCCESS, + NRF_WIFI_FMAC_TX_STATUS_QUEUED = 1, + NRF_WIFI_FMAC_TX_STATUS_FAIL = -1, +}; + +struct tx_pkt_info { + void *pkt; + unsigned int peer_id; +}; + +struct tx_cmd_prep_info { + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx; + struct nrf_wifi_tx_buff *config; +}; + +enum nrf_wifi_status tx_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +void tx_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +enum nrf_wifi_status nrf_wifi_fmac_tx_done_event_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_tx_buff_done *config); + +unsigned int tx_desc_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int queue); + +enum nrf_wifi_status tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc, + unsigned int ac); + +enum nrf_wifi_status tx_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *txq, + int desc, + int peer_id); + +unsigned int tx_buff_req_free(struct nrf_wifi_fmac_dev_ctx *fmac_ctx, + unsigned int desc, + unsigned char *ac); + +#endif /* __FMAC_TX_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_util.h b/nrf_wifi/fw_if/umac_if/inc/fmac_util.h new file mode 100644 index 0000000000..bcbf36620e --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_util.h @@ -0,0 +1,140 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing utility declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ +#ifndef __FMAC_UTIL_H__ +#define __FMAC_UTIL_H__ + +#ifndef CONFIG_NRF700X_RADIO_TEST +#include +#include "fmac_structs.h" +#include "pack_def.h" + + +#define NRF_WIFI_FMAC_ETH_ADDR_LEN 6 +#define NRF_WIFI_FMAC_ETH_HDR_LEN 14 + +#define NRF_WIFI_FMAC_FTYPE_DATA 0x0008 +#define NRF_WIFI_FMAC_STYPE_DATA 0x0000 +#define NRF_WIFI_FMAC_STYPE_QOS_DATA 0x0080 + +#define NRF_WIFI_FMAC_FCTL_FTYPE 0x000c +#define NRF_WIFI_FMAC_FCTL_PROTECTED 0x4000 +#define NRF_WIFI_FMAC_FCTL_TODS 0x0100 +#define NRF_WIFI_FMAC_FCTL_FROMDS 0x0200 + +#define NRF_WIFI_FMAC_CIPHER_SUITE_WEP40 0x000FAC01 +#define NRF_WIFI_FMAC_CIPHER_SUITE_WEP104 0x000FAC05 +#define NRF_WIFI_FMAC_CIPHER_SUITE_TKIP 0x000FAC02 +#define NRF_WIFI_FMAC_CIPHER_SUITE_CCMP 0x000FAC04 +#define NRF_WIFI_FMAC_CIPHER_SUITE_CCMP_256 0x000FAC0A +#define NRF_WIFI_FMAC_CIPHER_SUITE_OPEN 0x0 +#define NRF_WIFI_FMAC_CIPHER_SUITE_SMS4 0x00147201 + +#define NRF_WIFI_FMAC_CCMP_HDR_LEN 8 +#define NRF_WIFI_FMAC_CCMP_256_HDR_LEN 8 +#define NRF_WIFI_FMAC_SMS4_HDR_LEN 18 + +#define NRF_WIFI_FMAC_WEP_IV_LEN 4 +#define NRF_WIFI_FMAC_TKIP_IV_LEN 8 + +#define NRF_WIFI_FCTL_TODS 0x0100 +#define NRF_WIFI_FCTL_FROMDS 0x0200 +#define NRF_WIFI_FMAC_ETH_P_8021Q 0x8100 /* 802.1Q VLAN Extended Header */ +#define NRF_WIFI_FMAC_ETH_P_8021AD 0x88A8 /* 802.1ad Service VLAN */ +#define NRF_WIFI_FMAC_ETH_P_MPLS_UC 0x8847 /* MPLS Unicast traffic */ +#define NRF_WIFI_FMAC_ETH_P_MPLS_MC 0x8848 /* MPLS Multicast traffic */ +#define NRF_WIFI_FMAC_ETH_P_IP 0x0800 /* Internet Protocol packet */ +#define NRF_WIFI_FMAC_ETH_P_IPV6 0x86DD /* IPv6 over bluebook */ +#define NRF_WIFI_FMAC_ETH_P_80221 0x8917 /* IEEE 802.21 Media Independent Handover Protocol */ +#define NRF_WIFI_FMAC_ETH_P_AARP 0x80F3 /* Appletalk AARP */ +#define NRF_WIFI_FMAC_ETH_P_IPX 0x8137 /* IPX over DIX */ +#define NRF_WIFI_FMAC_ETH_P_802_3_MIN 0x0600 /* If the value in the ethernet type is less than + * this value then the frame is Ethernet II. + * Else it is 802.3 + */ +#define NRF_WIFI_FMAC_VLAN_PRIO_SHIFT 0x0D /* 13 bit */ +#define NRF_WIFI_FMAC_VLAN_PRIO_MASK 0xE000 +#define NRF_WIFI_FMAC_MPLS_LS_TC_MASK 0x00000E00 +#define NRF_WIFI_FMAC_MPLS_LS_TC_SHIFT 0x09 +#define NRF_WIFI_FMAC_IPV6_TOS_MASK 0x0FF0 +#define NRF_WIFI_FMAC_IPV6_TOS_SHIFT 0x04 /* 4bit */ +#define NRF_WIFI_FMAC_ETH_TYPE_MASK 0xFFFF + +struct nrf_wifi_fmac_ieee80211_hdr { + unsigned short fc; + unsigned short dur_id; + unsigned char addr_1[NRF_WIFI_FMAC_ETH_ADDR_LEN]; + unsigned char addr_2[NRF_WIFI_FMAC_ETH_ADDR_LEN]; + unsigned char addr_3[NRF_WIFI_FMAC_ETH_ADDR_LEN]; + unsigned short seq_ctrl; + unsigned char addr_4[NRF_WIFI_FMAC_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + + +struct nrf_wifi_fmac_eth_hdr { + unsigned char dst[NRF_WIFI_FMAC_ETH_ADDR_LEN]; /* destination eth addr */ + unsigned char src[NRF_WIFI_FMAC_ETH_ADDR_LEN]; /* source ether addr */ + unsigned short proto; /* packet type ID field */ +} __NRF_WIFI_PKD; + + +struct nrf_wifi_fmac_amsdu_hdr { + unsigned char dst[NRF_WIFI_FMAC_ETH_ADDR_LEN]; /* destination eth addr */ + unsigned char src[NRF_WIFI_FMAC_ETH_ADDR_LEN]; /* source ether addr */ + unsigned short length; /* length*/ +} __NRF_WIFI_PKD; + +bool nrf_wifi_util_is_multicast_addr(const unsigned char *addr); + +bool nrf_wifi_util_is_unicast_addr(const unsigned char *addr); + +bool nrf_wifi_util_ether_addr_equal(const unsigned char *addr_1, + const unsigned char *addr_2); + +int nrf_wifi_util_get_tid(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb); + +int nrf_wifi_util_get_vif_indx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + const unsigned char *mac_addr); + +unsigned char *nrf_wifi_util_get_ra(struct nrf_wifi_fmac_vif_ctx *vif, + void *nwb); + +unsigned char *nrf_wifi_util_get_src(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb); + +unsigned char *nrf_wifi_util_get_dest(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb); + +unsigned short nrf_wifi_util_tx_get_eth_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb); + +unsigned short nrf_wifi_util_rx_get_eth_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb); + +int nrf_wifi_util_get_skip_header_bytes(unsigned short eth_type); + +void nrf_wifi_util_convert_to_eth(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb, + struct nrf_wifi_fmac_ieee80211_hdr *hdr, + unsigned short eth_type); + +void nrf_wifi_util_rx_convert_amsdu_to_eth(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb); + +bool nrf_wifi_util_is_arr_zero(unsigned char *arr, + unsigned int arr_sz); + +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + +void *wifi_fmac_priv(struct nrf_wifi_fmac_priv *def); +void *wifi_dev_priv(struct nrf_wifi_fmac_dev_ctx *def); + +#endif /* __FMAC_UTIL_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fmac_vif.h b/nrf_wifi/fw_if/umac_if/inc/fmac_vif.h new file mode 100644 index 0000000000..c05e334bb6 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fmac_vif.h @@ -0,0 +1,35 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing virtual interface (VIF) specific declarations for + * the FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_VIF_H__ +#define __FMAC_VIF_H__ + +#include "fmac_structs.h" + +int nrf_wifi_fmac_vif_check_if_limit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_type); + +void nrf_wifi_fmac_vif_incr_if_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_type); + +void nrf_wifi_fmac_vif_decr_if_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_type); + +void nrf_wifi_fmac_vif_clear_ctx(void *fmac_dev_ctx, + unsigned char if_idx); + +void nrf_wifi_fmac_vif_update_if_type(void *fmac_dev_ctx, + unsigned char if_idx, + int if_type); + +unsigned int nrf_wifi_fmac_get_num_vifs(void *fmac_dev_ctx); + +#endif /* __FMAC_VIF_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_common_if.h b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_common_if.h new file mode 100644 index 0000000000..6278429f12 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_common_if.h @@ -0,0 +1,121 @@ +/* + * + *Copyright (c) 2022 Nordic Semiconductor ASA + * + *SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * @brief Common interface between host and RPU + * + */ +#ifndef __NRF_WIFI_HOST_RPU_COMMON_IFACE_H__ +#define __NRF_WIFI_HOST_RPU_COMMON_IFACE_H__ + +#include "rpu_if.h" + +#include "pack_def.h" + +#define NRF_WIFI_UMAC_VER(version) (((version)&0xFF000000) >> 24) +#define NRF_WIFI_UMAC_VER_MAJ(version) (((version)&0x00FF0000) >> 16) +#define NRF_WIFI_UMAC_VER_MIN(version) (((version)&0x0000FF00) >> 8) +#define NRF_WIFI_UMAC_VER_EXTRA(version) (((version)&0x000000FF) >> 0) +#define RPU_MEM_UMAC_BOOT_SIG 0xB0000000 +#define RPU_MEM_UMAC_VER 0xB0000004 +#define RPU_MEM_UMAC_PEND_Q_BMP 0xB0000008 +#define RPU_MEM_UMAC_CMD_ADDRESS 0xB00007A8 +#define RPU_MEM_UMAC_EVENT_ADDRESS 0xB0000E28 +#define RPU_MEM_UMAC_PATCH_BIN 0x8008C000 +#define RPU_MEM_UMAC_PATCH_BIMG 0x80099400 + +#define NRF_WIFI_UMAC_BOOT_SIG 0x5A5A5A5A +#define NRF_WIFI_UMAC_ROM_PATCH_OFFSET (RPU_MEM_UMAC_PATCH_BIMG - RPU_ADDR_UMAC_CORE_RET_START) +#define NRF_WIFI_UMAC_BOOT_EXCP_VECT_0 0x3c1a8000 +#define NRF_WIFI_UMAC_BOOT_EXCP_VECT_1 0x275a0000 +#define NRF_WIFI_UMAC_BOOT_EXCP_VECT_2 0x03400008 +#define NRF_WIFI_UMAC_BOOT_EXCP_VECT_3 0x00000000 + +/** + * @brief This enum defines the different categories of messages that can be exchanged between + * the Host and the RPU. + * + */ +enum nrf_wifi_host_rpu_msg_type { + /** System interface messages */ + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + /** Unused */ + NRF_WIFI_HOST_RPU_MSG_TYPE_SUPPLICANT, + /** Data path messages */ + NRF_WIFI_HOST_RPU_MSG_TYPE_DATA, + /** Control path messages */ + NRF_WIFI_HOST_RPU_MSG_TYPE_UMAC +}; +/** + * @brief This structure defines the common message header used to encapsulate each message + * exchanged between the Host and UMAC. + * + */ + +struct host_rpu_msg { + /** Header */ + struct host_rpu_msg_hdr hdr; + /** Type of the RPU message see &enum nrf_wifi_host_rpu_msg_type */ + signed int type; + /** Actual message */ + signed char msg[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_PENDING_FRAMES_BITMAP_AC_VO (1 << 0) +#define NRF_WIFI_PENDING_FRAMES_BITMAP_AC_VI (1 << 1) +#define NRF_WIFI_PENDING_FRAMES_BITMAP_AC_BE (1 << 2) +#define NRF_WIFI_PENDING_FRAMES_BITMAP_AC_BK (1 << 3) + +/** + * @brief This structure represents the bitmap of STA (Station) pending frames in + * SoftAP power save mode. + * + */ + +struct sap_pend_frames_bitmap { + /** STA MAC address */ + unsigned char mac_addr[6]; + /** Pending frames bitmap for each access category */ + unsigned char pend_frames_bitmap; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the information related to UMAC. + * + */ +struct host_rpu_umac_info { + /** Boot status signature */ + unsigned int boot_status; + /** UMAC version */ + unsigned int version; + /** @ref sap_pend_frames_bitmap */ + struct sap_pend_frames_bitmap sap_bitmap[4]; + /** Hardware queues info &enum host_rpu_hpqm_info */ + struct host_rpu_hpqm_info hpqm_info; + /** OTP params */ + unsigned int info_part; + /** OTP params */ + unsigned int info_variant; + /** OTP params */ + unsigned int info_lromversion; + /** OTP params */ + unsigned int info_uromversion; + /** OTP params */ + unsigned int info_uuid[4]; + /** OTP params */ + unsigned int info_spare0; + /** OTP params */ + unsigned int info_spare1; + /** OTP params */ + unsigned int mac_address0[2]; + /** OTP params */ + unsigned int mac_address1[2]; + /** OTP params */ + unsigned int calib[9]; +} __NRF_WIFI_PKD; +#endif /* __NRF_WIFI_HOST_RPU_IFACE_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_data_if.h b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_data_if.h new file mode 100644 index 0000000000..a3507088c7 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_data_if.h @@ -0,0 +1,263 @@ +/* + * + *Copyright (c) 2022 Nordic Semiconductor ASA + * + *SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * @brief Data interface between host and RPU + */ + +#ifndef __HOST_RPU_DATA_IF_H__ +#define __HOST_RPU_DATA_IF_H__ + +#include "host_rpu_common_if.h" +#include "host_rpu_sys_if.h" + +#include "pack_def.h" + +#define NRF_WIFI_ETH_ADDR_LEN 6 +#define TX_BUF_HEADROOM 52 + +/** + * @brief UMAC data interface commands and events. + * + */ +enum nrf_wifi_umac_data_commands { + /** Unused. */ + NRF_WIFI_CMD_MGMT_BUFF_CONFIG, + /** Transmit data packet @ref nrf_wifi_tx_buff */ + NRF_WIFI_CMD_TX_BUFF, + /** TX done event @ref nrf_wifi_tx_buff_done */ + NRF_WIFI_CMD_TX_BUFF_DONE, + /** RX packet event @ref nrf_wifi_rx_buff*/ + NRF_WIFI_CMD_RX_BUFF, + /** Event to indicate interface is operational + * @ref nrf_wifi_data_carrier_state + */ + NRF_WIFI_CMD_CARRIER_ON, + /** Event to indicate interface is non-operational + * @ref nrf_wifi_data_carrier_state + */ + NRF_WIFI_CMD_CARRIER_OFF, + /** Event to indicate softap client's power save mode + * If client is in power save mode, host should start buffering + * packets until it receives NRF_WIFI_CMD_PS_GET_FRAMES event. + */ + NRF_WIFI_CMD_PM_MODE, + /** Event to indicate to start sending buffered packets for + * softap client @ref nrf_wifi_sap_ps_get_frames. + */ + NRF_WIFI_CMD_PS_GET_FRAMES, +}; + +/** + * @brief Data interface Command and Event header. + * + */ +struct nrf_wifi_umac_head { + /** Command or Event id see &enum nrf_wifi_umac_data_commands */ + unsigned int cmd; + /** length */ + unsigned int len; + +} __NRF_WIFI_PKD; + +#define DSCP_TOS_MASK 0xFFFF +#define DSCP_OR_TOS_TWT_EMERGENCY_TX (1 << 31) + +/** + * @brief Tx mac80211 header information. + * + */ +struct tx_mac_hdr_info { + /** Unused */ + signed int umac_fill_flags; + /** frame control */ + unsigned short fc; + /** source Mac header */ + unsigned char dest[6]; + /** destination Mac address */ + unsigned char src[6]; + /** Ethernet type */ + unsigned short etype; + /** Type of Service */ + unsigned int dscp_or_tos; + /** more frames queued */ + unsigned char more_data; + /** End Of Service Period flag(applicable in U-APSD) */ + unsigned char eosp; +} __NRF_WIFI_PKD; + +/** + * @brief This structure provides the information of each packet in the tx command. + * + */ + +struct nrf_wifi_tx_buff_info { + /** Tx packet length */ + unsigned short pkt_length; + /** Tx packet address */ + unsigned int ddr_ptr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure provides the parameters for the tx command. + * + */ +struct nrf_wifi_tx_buff { + /** Command header @ref nrf_wifi_umac_head */ + struct nrf_wifi_umac_head umac_head; + /** Interface id */ + unsigned char wdev_id; + /** Descriptor id */ + unsigned char tx_desc_num; + /** Common mac header for all packets in this command + * @ref tx_mac_hdr_info + */ + struct tx_mac_hdr_info mac_hdr_info; + /** Pending buffer size at host to encode queue size + * in qos control field of mac header in TWT enable case + */ + unsigned int pending_buf_size; + /** Number of packets sending in this command */ + unsigned char num_tx_pkts; + /** Each packets information @ref nrf_wifi_tx_buff_info */ + struct nrf_wifi_tx_buff_info tx_buff_info[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_TX_STATUS_SUCCESS 0 +#define NRF_WIFI_TX_STATUS_FAILED 1 + +/** + * @brief This structure represents the Tx done event(NRF_WIFI_CMD_TX_BUFF_DONE). + * + */ +struct nrf_wifi_tx_buff_done { + /** Header @ref nrf_wifi_umac_head */ + struct nrf_wifi_umac_head umac_head; + /** Descriptor id */ + unsigned char tx_desc_num; + /** Number of packets in this Tx done event */ + unsigned char num_tx_status_code; + /** Frame sent time at Phy */ + unsigned char timestamp_t1[6]; + /** Frame ack received time at Phy */ + unsigned char timestamp_t4[6]; + /** Status of Tx packet. Maximum of MAX_TX_AGG_SIZE */ + unsigned char tx_status_code[0]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the type of received packet. + * + */ +enum nrf_wifi_rx_pkt_type { + /** The Rx packet is of type data */ + NRF_WIFI_RX_PKT_DATA, + /** RX packet is beacon or probe response */ + NRF_WIFI_RX_PKT_BCN_PRB_RSP +}; + +/** + * @brief This structure provides information about the parameters in the RX data event. + * + */ +struct nrf_wifi_rx_buff_info { + /** Descriptor id */ + unsigned short descriptor_id; + /** Rx packet length */ + unsigned short rx_pkt_len; + /** type PKT_TYPE_MPDU/PKT_TYPE_MSDU_WITH_MAC/PKT_TYPE_MSDU */ + unsigned char pkt_type; + /** Frame received time at Phy */ + unsigned char timestamp_t2[6]; + /** Ack sent time at Phy */ + unsigned char timestamp_t3[6]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents RX data event(NRF_WIFI_CMD_RX_BUFF). + * + */ +struct nrf_wifi_rx_buff { + /** Header @ref nrf_wifi_umac_head */ + struct nrf_wifi_umac_head umac_head; + /** Rx packet type. see &enum nrf_wifi_rx_pkt_type */ + signed int rx_pkt_type; + /** Interface id */ + unsigned char wdev_id; + /** Number of packets in this event */ + unsigned char rx_pkt_cnt; + /** Depricated */ + unsigned char reserved; + /** MAC header length. Same for all packets in this event */ + unsigned char mac_header_len; + /** Frequency on which this packet received */ + unsigned short frequency; + /** signal strength */ + signed short signal; + /** Information of each packet. @ref nrf_wifi_rx_buff_info */ + struct nrf_wifi_rx_buff_info rx_buff_info[0]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure provides information about the carrier (interface) state. + * + */ +struct nrf_wifi_data_carrier_state { + /** Header @ref nrf_wifi_umac_head */ + struct nrf_wifi_umac_head umac_head; + /** Interface id */ + unsigned int wdev_id; + +} __NRF_WIFI_PKD; + +/** SoftAP client is in active mode */ +#define NRF_WIFI_CLIENT_ACTIVE 0 +/** SoftAP client is in power save mode */ +#define NRF_WIFI_CLIENT_PS_MODE 1 + +/** + * @brief This structure describes an event related to the power save state of the softap's client. + * When the client is in PS mode (NRF_WIFI_CLIENT_PS_MODE), the host should queue Tx packets. + * When the client is in wakeup mode (NRF_WIFI_CLIENT_ACTIVE), the host should send all + * buffered and upcoming Tx packets. + * + */ +struct nrf_wifi_sap_client_pwrsave { + /** Header @ref nrf_wifi_umac_head */ + struct nrf_wifi_umac_head umac_head; + /** Interface id */ + unsigned int wdev_id; + /** state NRF_WIFI_CLIENT_ACTIVE or NRF_WIFI_CLIENT_PS_MODE */ + unsigned char sta_ps_state; + /** STA MAC Address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents an event that instructs the host to transmit a specific + * number of frames that host queued when softap's client is in power save mode. + * This event is primarily used when Softap's client operates in legacy power save mode. + * In this scenario, the access point (AP) is required to send a single packet for every PS POLL + * frame it receives from the client. Additionally, this mechanism will also be utilized in + * UAPSD power save. + * + */ +struct nrf_wifi_sap_ps_get_frames { + /** Header @ref nrf_wifi_umac_head */ + struct nrf_wifi_umac_head umac_head; + /** Interface id */ + unsigned int wdev_id; + /** STA MAC Address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Number of frames to be transmitted in this service period */ + signed char num_frames; + +} __NRF_WIFI_PKD; + +#endif /* __HOST_RPU_DATA_IF_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_sys_if.h b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_sys_if.h new file mode 100644 index 0000000000..e1de7f4bab --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_sys_if.h @@ -0,0 +1,1340 @@ +/* + * + *Copyright (c) 2022 Nordic Semiconductor ASA + * + *SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * @brief System interface between host and RPU + */ + +#ifndef __HOST_RPU_SYS_IF_H__ +#define __HOST_RPU_SYS_IF_H__ + +#include "host_rpu_common_if.h" +#include "lmac_if_common.h" + +#include "pack_def.h" + +#define USE_PROTECTION_NONE 0 +#define USE_PROTECTION_RTS 1 +#define USE_PROTECTION_CTS2SELF 2 + +#define USE_SHORT_PREAMBLE 0 +#define DONT_USE_SHORT_PREAMBLE 1 + +#define MARK_RATE_AS_MCS_INDEX 0x80 +#define MARK_RATE_AS_RATE 0x00 + +#define ENABLE_GREEN_FIELD 0x01 +#define ENABLE_CHNL_WIDTH_40MHZ 0x02 +#define ENABLE_SGI 0x04 +#define ENABLE_11N_FORMAT 0x08 +#define ENABLE_VHT_FORMAT 0x10 +#define ENABLE_CHNL_WIDTH_80MHZ 0x20 + +#define MAX_TX_AGG_SIZE 16 +#define MAX_RX_BUFS_PER_EVNT 64 +#define MAX_MGMT_BUFS 16 + +/*#define ETH_ADDR_LEN 6*/ +#define MAX_RF_CALIB_DATA 900 + +#define NRF_WIFI_ETH_ADDR_LEN 6 + +#define PHY_THRESHOLD_NORMAL (-65) +#define PHY_THRESHOLD_PROD_MODE (-93) + +#define MAX_TX_STREAMS 1 +#define MAX_RX_STREAMS 1 + +#define MAX_NUM_VIFS 2 +#define MAX_NUM_STAS 2 +#define MAX_NUM_APS 1 + +#define NRF_WIFI_COUNTRY_CODE_LEN 2 + +/** + * @brief This enum provides a list of different operating modes. + * + */ +enum rpu_op_mode { + /** Radio test mode is used for performing radio tests using + * continuous Tx/Rx on a configured channel at a particular rate or power. + */ + RPU_OP_MODE_RADIO_TEST, + /** In this mode different types of calibration like RF calibration can be performed */ + RPU_OP_MODE_FCM, + /** Regular mode of operation */ + RPU_OP_MODE_REG, + /** Debug mode can be used to control certain parameters like TX rate + * in order to debug functional issues. + */ + RPU_OP_MODE_DBG, + /** Highest mode number currently defined */ + RPU_OP_MODE_MAX +}; + +/** + * @brief This enum defines various types of statistics. + */ +enum rpu_stats_type { + /** All statistics includes PHY, LMAC & UMAC */ + RPU_STATS_TYPE_ALL, + /** Host statistics */ + RPU_STATS_TYPE_HOST, + /** UMAC statistics */ + RPU_STATS_TYPE_UMAC, + /** LMAC statistics*/ + RPU_STATS_TYPE_LMAC, + /** PHY statistics */ + RPU_STATS_TYPE_PHY, + /** Highest statistics type number currently defined */ + RPU_STATS_TYPE_MAX +}; + +/** + * @brief- Throughput mode + * Throughput mode to be used for transmitting the packet. + */ +enum rpu_tput_mode { + /** Legacy mode */ + RPU_TPUT_MODE_LEGACY, + /** High Throuput mode(11n) */ + RPU_TPUT_MODE_HT, + /** Very hight throughput(11ac) */ + RPU_TPUT_MODE_VHT, + /** HE SU mode */ + RPU_TPUT_MODE_HE_SU, + /** HE ER SU mode */ + RPU_TPUT_MODE_HE_ER_SU, + /** HE TB mode */ + RPU_TPUT_MODE_HE_TB, + /** Highest throughput mode currently defined */ + RPU_TPUT_MODE_MAX +}; + +/** + * @brief - System commands. + * + */ +enum nrf_wifi_sys_commands { + /** Command to initialize RPU and RPU responds with NRF_WIFI_EVENT_INIT_DONE */ + NRF_WIFI_CMD_INIT, + /** command to send a Tx packet in radiotest mode */ + NRF_WIFI_CMD_TX, + /** Unused */ + NRF_WIFI_CMD_IF_TYPE, + /** command to specify mode of operation */ + NRF_WIFI_CMD_MODE, + /** command to get statistics */ + NRF_WIFI_CMD_GET_STATS, + /** command to clear statistics */ + NRF_WIFI_CMD_CLEAR_STATS, + /** command to ENABLE/DISABLE receiving packets in radiotest mode */ + NRF_WIFI_CMD_RX, + /** Command to measure battery voltage and RPU responds with NRF_WIFI_EVENT_PWR_DATA */ + NRF_WIFI_CMD_PWR, + /** RPU De-initialization */ + NRF_WIFI_CMD_DEINIT, + /** Command for WIFI & Bluetooth coexistence */ + NRF_WIFI_CMD_BTCOEX, + /** Command to start RF test */ + NRF_WIFI_CMD_RF_TEST, + /** Configure HE_GI & HE_LTF */ + NRF_WIFI_CMD_HE_GI_LTF_CONFIG, + /** Command for getting UMAC memory statistics */ + NRF_WIFI_CMD_UMAC_INT_STATS, + /** Command for Setting the channel & Rf params in radiotest mode */ + NRF_WIFI_CMD_RADIO_TEST_INIT, + /** Command for setting country in radiotest mode */ + NRF_WIFI_CMD_RT_REQ_SET_REG, + /** Command to enable/disable fixed data rate in regular mode */ + NRF_WIFI_CMD_TX_FIX_DATA_RATE, +}; + +/** + * @brief - Events from the RPU. + * + */ +enum nrf_wifi_sys_events { + /** Response to NRF_WIFI_CMD_PWR */ + NRF_WIFI_EVENT_PWR_DATA, + /** Response to NRF_WIFI_CMD_INIT */ + NRF_WIFI_EVENT_INIT_DONE, + /** Response to NRF_WIFI_CMD_GET_STATS */ + NRF_WIFI_EVENT_STATS, + /** Response to NRF_WIFI_CMD_DEINIT */ + NRF_WIFI_EVENT_DEINIT_DONE, + /** Response to NRF_WIFI_CMD_RF_TEST */ + NRF_WIFI_EVENT_RF_TEST, + /** Response to NRF_WIFI_CMD_BTCOEX. */ + NRF_WIFI_EVENT_COEX_CONFIG, + /** Response to NRF_WIFI_CMD_UMAC_INT_STATS */ + NRF_WIFI_EVENT_INT_UMAC_STATS, + /** Command status events for radio test commands*/ + NRF_WIFI_EVENT_RADIOCMD_STATUS +}; + +/** + * @brief - Channel Bandwidth types. + * + **/ +enum rpu_ch_bw { + /** 20MHz bandwidth */ + RPU_CH_BW_20, + /** 40MHz bandwidth */ + RPU_CH_BW_40, + /** 80MHz bandwidth */ + RPU_CH_BW_MAX +}; + +/** + * @brief - This structure specifies the parameters required to configure a specific channel. + * + */ +struct chan_params { + /** Primary channel number */ + unsigned int primary_num; + /** Channel bandwidth */ + unsigned char bw; + /** 20Mhz offset value */ + signed int sec_20_offset; + /** 40Mhz offset value */ + signed int sec_40_offset; +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the parameters required to start or stop the RX (receive) + * operation in radiotest mode. + * + */ +struct rpu_conf_rx_radio_test_params { + /** Number of spatial streams supported. Currently unused. */ + unsigned char nss; + /* Input to the RF for operation */ + unsigned char rf_params[NRF_WIFI_RF_PARAMS_SIZE]; + /** An array containing RF and baseband control params */ + struct chan_params chan; + /** Copy OTP params to this memory */ + signed char phy_threshold; + /** Calibration bit map value. More information can be found in the phy_rf_params.h file. + */ + unsigned int phy_calib; + /** Start Rx : 1, Stop Rx :0 */ + unsigned char rx; +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the UMAC (Upper MAC) RX (receive) debug parameters + * specifically designed for debugging purpose. + * + */ + +struct umac_rx_dbg_params { + /** Total lmac events received to UMAC */ + unsigned int lmac_events; + /** Total Rx events(LMAC_EVENT_RX) received in ISR */ + unsigned int rx_events; + /** Received coalised events from LMAC */ + unsigned int rx_coalesce_events; + /** Total Rx packets received from LMAC */ + unsigned int total_rx_pkts_from_lmac; + /** Maximum RX packets buffered at any point of time in UMAC.*/ + unsigned int max_refill_gap; + /** Difference between rx packets received from lmac and packets sent to host */ + unsigned int current_refill_gap; + /** Number of Packets queued to reorder buffer due to out of order */ + unsigned int out_of_order_mpdus; + /** Number of packets removed from reorder buffer */ + unsigned int reorder_free_mpdus; + /** Number of Rx packets resubmitted to LMAC by UMAC */ + unsigned int umac_consumed_pkts; + /** Number of Rx packets sent to Host for resubmiting */ + unsigned int host_consumed_pkts; + /** Total events posted to UMAC RX thread from LMAC */ + unsigned int rx_mbox_post; + /** Total events received to UMAC RX thread from LMAC */ + unsigned int rx_mbox_receive; + /** Number of packets received in out of order */ + unsigned int reordering_ampdu; + /** Messages posted to TX mbox from timer ISR */ + unsigned int timer_mbox_post; + /** Messages received from timer ISR */ + unsigned int timer_mbox_rcv; + /** Messages posted to TX mbox from work scheduler */ + unsigned int work_mbox_post; + /** Messages received from work scheduler */ + unsigned int work_mbox_rcv; + /** Messages posted to TX mbox from tasklet function */ + unsigned int tasklet_mbox_post; + /** Messages received from tasklet function */ + unsigned int tasklet_mbox_rcv; + /** Management frames sent to userspace */ + unsigned int userspace_offload_frames; + /** Number of times where requested buffer size is not available + * and allocated from next available memory buffer + */ + unsigned int alloc_buf_fail; + /** Total packets count in RX thread */ + unsigned int rx_packet_total_count; + /** Number of data packets received */ + unsigned int rx_packet_data_count; + /** Number of Qos data packets received */ + unsigned int rx_packet_qos_data_count; + /** Number of protected data packets received */ + unsigned int rx_packet_protected_data_count; + /** Number of management packets received */ + unsigned int rx_packet_mgmt_count; + /** Number of beacon packets received */ + unsigned int rx_packet_beacon_count; + /** Number of probe response packets received */ + unsigned int rx_packet_probe_resp_count; + /** Number of authentication packets received */ + unsigned int rx_packet_auth_count; + /** Number of deauthentication packets received */ + unsigned int rx_packet_deauth_count; + /** Number of assoc response packets received */ + unsigned int rx_packet_assoc_resp_count; + /** Number of disassociation packets received */ + unsigned int rx_packet_disassoc_count; + /** Number of action frames received */ + unsigned int rx_packet_action_count; + /** Number of probe request packets received */ + unsigned int rx_packet_probe_req_count; + /** Other management packets received */ + unsigned int rx_packet_other_mgmt_count; + /** Maximum coalised packets received from LMAC in any RX event */ + signed char max_coalesce_pkts; + /** Packets received with null skb pointer from LMAC */ + unsigned int null_skb_pointer_from_lmac; + /** Number of unexpected management packets received in coalesce event */ + unsigned int unexpected_mgmt_pkt; + +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the UMAC TX (transmit) debug parameters used for + * debugging purposes. + * + */ +struct umac_tx_dbg_params { + /** Total number of tx commands received from host */ + unsigned int tx_cmd; + /** Non coalesce packets received */ + unsigned int tx_non_coalesce_pkts_rcvd_from_host; + /** coalesce packets received */ + unsigned int tx_coalesce_pkts_rcvd_from_host; + /** Maximum number of coalesce packets received in any + * TX command coalesce packets received + */ + unsigned int tx_max_coalesce_pkts_rcvd_from_host; + /** Maximum Tx commands currently in process at any point of time in UMAC */ + unsigned int tx_cmds_max_used; + /** Number of Tx commands that are currently in process in UMAC */ + unsigned int tx_cmds_currently_in_use; + /** Number of tx done events sent to host */ + unsigned int tx_done_events_send_to_host; + /** Number of tx done success packets sent to host */ + unsigned int tx_done_success_pkts_to_host; + /** Number of tx done failure packets sent to host */ + unsigned int tx_done_failure_pkts_to_host; + /** Number of packets received from host that needs to be encrypted */ + unsigned int tx_cmds_with_crypto_pkts_rcvd_from_host; + /** Number of packets received from host that need not to be encrypted */ + unsigned int tx_cmds_with_non_crypto_pkts_rcvd_from_host; + /** Number of broadcast packets received from host */ + unsigned int tx_cmds_with_broadcast_pkts_rcvd_from_host; + /** Number of multicast packets received from host */ + unsigned int tx_cmds_with_multicast_pkts_rcvd_from_host; + /** Number of unicast packets received from host */ + unsigned int tx_cmds_with_unicast_pkts_rcvd_from_host; + /** UMAC internal count */ + unsigned int xmit; + /** Number of addba requests sent */ + unsigned int send_addba_req; + /** Total ADD BA responses received from host */ + unsigned int addba_resp; + /** Total packets received in softmac tx function */ + unsigned int softmac_tx; + /** Number of packets generated internally in UMAC */ + unsigned int internal_pkts; + /** Number of packets Received from host */ + unsigned int external_pkts; + /** Total tx commmands sent to lmac */ + unsigned int tx_cmds_to_lmac; + /** Tx dones received from LMAC */ + unsigned int tx_dones_from_lmac; + /** Total commands sent to lmac in UMAC hal */ + unsigned int total_cmds_to_lmac; + /** Number of data packets sent */ + unsigned int tx_packet_data_count; + /** Number of management packets sent */ + unsigned int tx_packet_mgmt_count; + /** Number of beacon packets sent */ + unsigned int tx_packet_beacon_count; + /** Number of probe request packets sent */ + unsigned int tx_packet_probe_req_count; + /** Number of authentication packets sent */ + unsigned int tx_packet_auth_count; + /** Number of deauthentication packets sent */ + unsigned int tx_packet_deauth_count; + /** Number of association request packets sent */ + unsigned int tx_packet_assoc_req_count; + /** Number of disassociation packets sent */ + unsigned int tx_packet_disassoc_count; + /** Number of action packets sent */ + unsigned int tx_packet_action_count; + /** Other management packets sent */ + unsigned int tx_packet_other_mgmt_count; + /** Number of Non management packets sent */ + unsigned int tx_packet_non_mgmt_data_count; + +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the UMAC command and event debug parameters used for + * debugging purpose. + * + */ +struct umac_cmd_evnt_dbg_params { + /** Number of command init received from host */ + unsigned char cmd_init; + /** Number of init_done events sent to host */ + unsigned char event_init_done; + /** Number of rf test command received from host */ + unsigned char cmd_rf_test; + /** Number of connect command received from host */ + unsigned char cmd_connect; + /** Number of get_stats command received from host */ + unsigned int cmd_get_stats; + /** Number of power save state events sent to host */ + unsigned int event_ps_state; + /** Unused*/ + unsigned int cmd_set_reg; + /** Number of get regulatory commands received from host */ + unsigned int cmd_get_reg; + /** Number of request set regulatory commands received from host */ + unsigned int cmd_req_set_reg; + /** Number of trigger scan commands received from host */ + unsigned int cmd_trigger_scan; + /** Number of scan done events sent to host */ + unsigned int event_scan_done; + /** Number of get scan commands received from the host to get scan results */ + unsigned int cmd_get_scan; + /** Number of scan commands sent to LMAC */ + unsigned int umac_scan_req; + /** Number of scan complete events received from LMAC */ + unsigned int umac_scan_complete; + /** Number of scan requests received from host when previous scan is in progress */ + unsigned int umac_scan_busy; + /** Number of authentication requests received from host */ + unsigned int cmd_auth; + /** Number of association requests received from host */ + unsigned int cmd_assoc; + /** Number of deauthentication requests received from host */ + unsigned int cmd_deauth; + /** Number of register frame commands received from host to register + * a management frame type which should be passed to host + */ + unsigned int cmd_register_frame; + /** Number of command frames from host which will be used for + * transmitting management frames + */ + unsigned int cmd_frame; + /** Number of delete key commands from host */ + unsigned int cmd_del_key; + /** Number of new key commands received from host */ + unsigned int cmd_new_key; + /** Number of set key commands received from host */ + unsigned int cmd_set_key; + /** Number of get key commands received from host */ + unsigned int cmd_get_key; + /** Number of beacon hint events sent to host */ + unsigned int event_beacon_hint; + /** Number of regulatory change events sent to host when regulatory change command + * received from host such as in response to command NL80211_CMD_REG_CHANGE + */ + unsigned int event_reg_change; + /** Number of regulatory change events sent to host other than + * host request for regulatory change + */ + unsigned int event_wiphy_reg_change; + /** Number of set station commands received from host */ + unsigned int cmd_set_station; + /** Number of new station commands received from host */ + unsigned int cmd_new_station; + /** Number of del station commands received from host */ + unsigned int cmd_del_station; + /** Number of new interface commands received from host */ + unsigned int cmd_new_interface; + /** Number of set interface commands received from host */ + unsigned int cmd_set_interface; + /** Number of get interface commands received from host */ + unsigned int cmd_get_interface; + /** Number of set_ifflags commands received from host */ + unsigned int cmd_set_ifflags; + /** Number of set_ifflags events sent to host */ + unsigned int cmd_set_ifflags_done; + /** Number of set bss command received from host */ + unsigned int cmd_set_bss; + /** Number of set wiphy command received from host */ + unsigned int cmd_set_wiphy; + /** Number of start access point command received from host */ + unsigned int cmd_start_ap; + /** Number of power save configuration commands sent to LMAC */ + unsigned int LMAC_CMD_PS; + /** Current power save state configured to LMAC through LMAC_CMD_PS command */ + unsigned int CURR_STATE; +} __NRF_WIFI_PKD; + +#ifndef CONFIG_NRF700X_RADIO_TEST + +/** + * @brief This structure specifies the UMAC interface debug parameters used for debugging purpose. + * + */ +struct nrf_wifi_interface_stats { + /** Number of unicast packets sent */ + unsigned int tx_unicast_pkt_count; + /** Number of multicast packets sent */ + unsigned int tx_multicast_pkt_count; + /** Number of broadcast packets sent */ + unsigned int tx_broadcast_pkt_count; + /** Number of tx data bytes sent */ + unsigned int tx_bytes; + /** Number of unicast packets received */ + unsigned int rx_unicast_pkt_count; + /** Number of multicast packets received */ + unsigned int rx_multicast_pkt_count; + /** Number of broadcast packets received */ + unsigned int rx_broadcast_pkt_count; + /** Number of beacon packets received */ + unsigned int rx_beacon_success_count; + /** Number of beacon packets missed */ + unsigned int rx_beacon_miss_count; + /** Number of rx data bytes received */ + unsigned int rx_bytes; + /** Number of packets with checksum mismatch received */ + unsigned int rx_checksum_error_count; + /** Number of duplicate packets received */ + unsigned int replay_attack_drop_cnt; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the UMAC debug statistics. It contains the necessary parameters + * and fields used to gather and present debugging statistics within the UMAC layer. + * + */ +struct rpu_umac_stats { + /** Transmit debug statistics @ref umac_tx_dbg_params */ + struct umac_tx_dbg_params tx_dbg_params; + /** Receive debug statistics @ref umac_rx_dbg_params */ + struct umac_rx_dbg_params rx_dbg_params; + /** Command Event debug statistics @ref umac_cmd_evnt_dbg_params */ + struct umac_cmd_evnt_dbg_params cmd_evnt_dbg_params; + /** Interface debug parameters @ref nrf_wifi_interface_stats */ + struct nrf_wifi_interface_stats interface_data_stats; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the LMAC debug parameters. + * + */ +struct rpu_lmac_stats { + /** Number of reset command counts from UMAC */ + unsigned int reset_cmd_cnt; + /** Number of reset complete events sent to UMAC */ + unsigned int reset_complete_event_cnt; + /** Number of events unable to generate */ + unsigned int unable_gen_event; + /** Number of channel program commands from UMAC */ + unsigned int ch_prog_cmd_cnt; + /** Number of channel program done events to UMAC */ + unsigned int channel_prog_done; + /** Number of Tx commands from UMAC */ + unsigned int tx_pkt_cnt; + /** Number of Tx done events to UMAC */ + unsigned int tx_pkt_done_cnt; + /** Unused */ + unsigned int scan_pkt_cnt; + /** Number of internal Tx packets */ + unsigned int internal_pkt_cnt; + /** Number of Tx dones for internal packets */ + unsigned int internal_pkt_done_cnt; + /** Number of acknowledgment responses */ + unsigned int ack_resp_cnt; + /** Number of transmit timeouts */ + unsigned int tx_timeout; + /** Number of deaggregation ISRs */ + unsigned int deagg_isr; + /** Number of deaggregation input descriptor empties */ + unsigned int deagg_inptr_desc_empty; + /** Number of deaggregation circular buffer full events */ + unsigned int deagg_circular_buffer_full; + /** Number of LMAC received ISRs */ + unsigned int lmac_rxisr_cnt; + /** Number of received packets decrypted */ + unsigned int rx_decryptcnt; + /** Number of packet decryption failures during processing */ + unsigned int process_decrypt_fail; + /** Number of RX event preparation failures */ + unsigned int prepa_rx_event_fail; + /** Number of RX core pool full counts */ + unsigned int rx_core_pool_full_cnt; + /** Number of RX MPDU CRC successes */ + unsigned int rx_mpdu_crc_success_cnt; + /** Number of RX MPDU CRC failures */ + unsigned int rx_mpdu_crc_fail_cnt; + /** Number of RX OFDM CRC successes */ + unsigned int rx_ofdm_crc_success_cnt; + /** Number of RX OFDM CRC failures */ + unsigned int rx_ofdm_crc_fail_cnt; + /** Number of RX DSSS CRC successes */ + unsigned int rxDSSSCrcSuccessCnt; + /** Number of RX DSSS CRC failures */ + unsigned int rxDSSSCrcFailCnt; + /** Number of RX crypto start counts */ + unsigned int rx_crypto_start_cnt; + /** Number of RX crypto done counts */ + unsigned int rx_crypto_done_cnt; + /** Number of RX event buffer full counts */ + unsigned int rx_event_buf_full; + /** Number of RX external RAM buffer full counts */ + unsigned int rx_extram_buf_full; + /** Number of scan requests receive from UMAC */ + unsigned int scan_req; + /** Number of scan complete events sent to UMAC */ + unsigned int scan_complete; + /** Number of scan abort requests */ + unsigned int scan_abort_req; + /** Number of scan abort complete events */ + unsigned int scan_abort_complete; + /** Number of internal buffer pool null counts */ + unsigned int internal_buf_pool_null; +} __NRF_WIFI_PKD; + +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + +/** + * @brief This structure defines the PHY (Physical Layer) debug statistics. + * + */ +struct rpu_phy_stats { + /** Rssi average value received from LMAC */ + signed char rssi_avg; + /** Unused */ + unsigned char pdout_val; + /** Number of OFDM CRC Pass packets */ + unsigned int ofdm_crc32_pass_cnt; + /** Number of OFDM CRC Fail packets */ + unsigned int ofdm_crc32_fail_cnt; + /** Number of DSSS CRC Pass packets */ + unsigned int dsss_crc32_pass_cnt; + /** Number of DSSS CRC Fail packets */ + unsigned int dsss_crc32_fail_cnt; +} __NRF_WIFI_PKD; + +/** + * @brief The UMAC header structure for system commands and events defines the format + * used to transmit and receive system-level commands and events. + * + */ +struct nrf_wifi_sys_head { + /** Command/Event id */ + unsigned int cmd_event; + /** message length */ + unsigned int len; +} __NRF_WIFI_PKD; + +/** Feature Disable */ +#define NRF_WIFI_FEATURE_DISABLE 0 +/** Feature Enable */ +#define NRF_WIFI_FEATURE_ENABLE 1 + +/** + * @brief The maximum Rx (receive) A-MPDU size in KB. + * + */ +enum max_rx_ampdu_size { + /** 8KB AMPDU Size */ + MAX_RX_AMPDU_SIZE_8KB, + /** 16KB AMPDU Size */ + MAX_RX_AMPDU_SIZE_16KB, + /** 32KB AMPDU Size */ + MAX_RX_AMPDU_SIZE_32KB, + /** 64KB AMPDU Size */ + MAX_RX_AMPDU_SIZE_64KB +}; + +/** + * @brief This structure specifies the configuration parameters used for configuring + * data-related settings. + * + */ + +struct nrf_wifi_data_config_params { + /** rate_protection_type:0->NONE, 1->RTS/CTS, 2->CTS2SELF */ + unsigned char rate_protection_type; + /** Aggregation is enabled(NRF_WIFI_FEATURE_ENABLE) or + * disabled(NRF_WIFI_FEATURE_DISABLE) + */ + unsigned char aggregation; + /** WMM is enabled(NRF_WIFI_FEATURE_ENABLE) or + * disabled(NRF_WIFI_FEATURE_DISABLE) + */ + unsigned char wmm; + /** Max number of aggregated TX sessions */ + unsigned char max_num_tx_agg_sessions; + /** Max number of aggregated RX sessions */ + unsigned char max_num_rx_agg_sessions; + /** maximum aggregation size */ + unsigned char max_tx_aggregation; + /** Reorder buffer size (1 to 64) */ + unsigned char reorder_buf_size; + /** Max RX AMPDU size (8/16/32/64 KB), see &enum max_rx_ampdu_size */ + signed int max_rxampdu_size; +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the parameters that need to be provided for the command + * NRF_WIFI_CMD_INIT. The NRF_WIFI_CMD_INIT command is typically used to initialize the + * Wi-Fi module and prepare it for further communication. + * + */ + +struct nrf_wifi_sys_params { + /** enable rpu sleep */ + unsigned int sleep_enable; + /** Normal/FTM mode */ + unsigned int hw_bringup_time; + /** Antenna Configuration, applicable only for 1x1 */ + unsigned int sw_bringup_time; + /** Internal tuning parameter */ + unsigned int bcn_time_out; + /** Set to 1 if rpu is expected to perform sleep clock calibration */ + unsigned int calib_sleep_clk; + /** calib bit map value. More info can be found in phy_rf_params.h NRF_WIFI_DEF_PHY_CALIB */ + unsigned int phy_calib; +#ifndef CONFIG_NRF700X_RADIO_TEST + /** MAC address of the interface */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** An array containing RF & baseband control params */ + unsigned char rf_params[NRF_WIFI_RF_PARAMS_SIZE]; + /** Indicates whether the rf_params has a valid value */ + unsigned char rf_params_valid; +#endif /* !CONFIG_NRF700X_RADIO_TEST */ +} __NRF_WIFI_PKD; + + +/** + * @brief This structure defines the parameters used to control the transmit (TX) power. + * + */ + +struct nrf_wifi_tx_pwr_ctrl_params { + /** Antenna gain for 2.4 GHz band */ + unsigned char ant_gain_2g; + /** Antenna gain for 5 GHz band (5150 MHz - 5350 MHz) */ + unsigned char ant_gain_5g_band1; + /** Antenna gain for 5 GHz band (5470 MHz - 5730 MHz) */ + unsigned char ant_gain_5g_band2; + /** Antenna gain for 5 GHz band (5730 MHz - 5895 MHz) */ + unsigned char ant_gain_5g_band3; + /** Transmit power backoff (in dB) for lower edge of 2.4 GHz frequency band */ + unsigned char band_edge_2g_lo; + /** Transmit power backoff (in dB) for upper edge of 2.4 GHz frequency band */ + unsigned char band_edge_2g_hi; + /** Transmit power backoff (in dB) for lower edge of UNII-1 frequency band */ + unsigned char band_edge_5g_unii_1_lo; + /** Transmit power backoff (in dB) for upper edge of UNII-1 frequency band */ + unsigned char band_edge_5g_unii_1_hi; + /** Transmit power backoff (in dB) for lower edge of UNII-2A frequency band */ + unsigned char band_edge_5g_unii_2a_lo; + /** Transmit power backoff (in dB) for upper edge of UNII-2A frequency band */ + unsigned char band_edge_5g_unii_2a_hi; + /** Transmit power backoff (in dB) for lower edge of UNII-2C frequency band */ + unsigned char band_edge_5g_unii_2c_lo; + /** Transmit power backoff (in dB) for upper edge of UNII-2C frequency band */ + unsigned char band_edge_5g_unii_2c_hi; + /** Transmit power backoff (in dB) for lower edge of UNII-3 frequency band */ + unsigned char band_edge_5g_unii_3_lo; + /** Transmit power backoff (in dB) for upper edge of UNII-3 frequency band */ + unsigned char band_edge_5g_unii_3_hi; + /** Transmit power backoff (in dB) for lower edge of UNII-4 frequency band */ + unsigned char band_edge_5g_unii_4_lo; + /** Transmit power backoff (in dB) for upper edge of UNII-4 frequency band */ + unsigned char band_edge_5g_unii_4_hi; +} __NRF_WIFI_PKD; + +/** + * @brief This enum defines different types of operating bands. + * + */ +enum op_band { + /** All bands */ + BAND_ALL, + /** 2.4Ghz band */ + BAND_24G +}; + +#define TWT_EXTEND_SP_EDCA 0x1 + +/** + * @brief This structure defines the command responsible for initializing the UMAC. + * After the host driver brings up, the host sends NRF_WIFI_CMD_INIT to the RPU. + * The RPU then performs the initialization and responds with NRF_WIFI_EVENT_INIT_DONE + * once the initialization is completed. + * + */ + +struct nrf_wifi_cmd_sys_init { + /** umac header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** id of the interface */ + unsigned int wdev_id; + /** @ref nrf_wifi_sys_params */ + struct nrf_wifi_sys_params sys_params; + /** LMAC Rx buffs pool params, @ref rx_buf_pool_params */ + struct rx_buf_pool_params rx_buf_pools[MAX_NUM_OF_RX_QUEUES]; + /** Data configuration params, @ref nrf_wifi_data_config_params */ + struct nrf_wifi_data_config_params data_config_params; + /** Calibration trigger control info based on battery voltage and temperature changes. + * @ref temp_vbat_config from lmac_if_common.h + */ + struct temp_vbat_config temp_vbat_config_params; + /** 0:umac checksum disable 1: umac checksum enable */ + unsigned char tcp_ip_checksum_offload; + /** Country code to set */ + unsigned char country_code[NRF_WIFI_COUNTRY_CODE_LEN]; + /** Operating band see enum op_band */ + unsigned int op_band; + /** System parameters provided for controlling the TX power */ + struct nrf_wifi_tx_pwr_ctrl_params tx_pwr_ctrl_params; + /** Offload mgmt buffer refill to UMAC when enabled */ + unsigned char mgmt_buff_offload; + /** Enable features from driver config */ + unsigned int feature_flags; + /** To deactivate beamforming, By default the RPU enables the beamforming feature. + * If a user wishes to turn it off, they should set this parameter to 1. + */ + unsigned int disable_beamforming; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to de-initialize the RPU. + * + */ + +struct nrf_wifi_cmd_sys_deinit { + /** umac header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_HE_GI_800NS 0 +#define NRF_WIFI_HE_GI_1600NS 1 +#define NRF_WIFI_HE_GI_3200NS 2 + +#define NRF_WIFI_HE_LTF_3200NS 0 +#define NRF_WIFI_HE_LTF_6400NS 1 +#define NRF_WIFI_HE_LTF_12800NS 2 + +/** + * @brief This structure defines the command used to configure + * High-Efficiency Guard Interval(HE-GI) and High-Efficiency Long Training Field (HE-LTF). + * + * HE-GI duration determines the guard interval length used in the HE transmission. + * HE-LTF is used for channel estimation and signal detection in HE transmissions. + * + */ + +struct nrf_wifi_cmd_he_gi_ltf_config { + /** umac header, see &nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** wdev interface id */ + unsigned char wdev_id; + /** HE GI type (NRF_WIFI_HE_GI_800NS/NRF_WIFI_HE_GI_1600NS/NRF_WIFI_HE_GI_3200NS) */ + unsigned char he_gi_type; + /** HE LTF (NRF_WIFI_HE_LTF_3200NS/NRF_WIFI_HE_LTF_6400NS/NRF_WIFI_HE_LTF_12800NS) */ + unsigned char he_ltf; + /** Fixed HE GI & LTF values can be enabled and disabled */ + unsigned char enable; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_DISABLE 0 +#define NRF_WIFI_ENABLE 1 +/** + * @brief This enum represents the different types of preambles used. + * Preambles are sequences of known symbols transmitted before the actual + * data transmission to enable synchronization, channel estimation, and + * frame detection at the receiver. + * + */ +enum rpu_pkt_preamble { + /** Short preamble packet */ + RPU_PKT_PREAMBLE_SHORT, + /** Long preamble packet */ + RPU_PKT_PREAMBLE_LONG, + /** mixed preamble packet */ + RPU_PKT_PREAMBLE_MIXED, + /** Highest preamble type currently defined */ + RPU_PKT_PREAMBLE_MAX, +}; + + +/** + * @brief This structure describes different Physical Layer (PHY) configuration parameters used + * in RF test and Radio test scenarios. These parameters are specific to testing and evaluating + * the performance of the radio hardware. + * + */ +struct rpu_conf_params { + /** Unused. Number of spatial streams supported. Support is there for 1x1 only. */ + unsigned char nss; + /** Unused */ + unsigned char antenna_sel; + /** An array containing RF & baseband control params */ + unsigned char rf_params[NRF_WIFI_RF_PARAMS_SIZE]; + /** Not required */ + unsigned char tx_pkt_chnl_bw; + /** WLAN packet formats. 0->Legacy 1->HT 2->VHT 3->HE(SU) 4->HE(ERSU) and 5->HE(TB) */ + unsigned char tx_pkt_tput_mode; + /** Short Guard enable/disable */ + unsigned char tx_pkt_sgi; + /** Not required */ + unsigned char tx_pkt_nss; + /** Preamble type. 0->short, 1->Long and 2->Mixed */ + unsigned char tx_pkt_preamble; + /** Not used */ + unsigned char tx_pkt_stbc; + /** 0->BCC 1->LDPC. Supporting only BCC in nRF7002 */ + unsigned char tx_pkt_fec_coding; + /** Valid MCS number between 0 to 7 */ + signed char tx_pkt_mcs; + /** Legacy rate to be used in Mbps (1, 2, 5.5, 11, 6, 9, 12, 18, 24, 36, 48, 54) */ + signed char tx_pkt_rate; + /** Copy OTP params to this memory */ + signed char phy_threshold; + /** Calibration bit map value. refer NRF_WIFI_DEF_PHY_CALIB */ + unsigned int phy_calib; + /** Radio test mode or System mode selection */ + signed int op_mode; + /** Channel related info viz, channel, bandwidth, primary 20 offset */ + struct chan_params chan; + /** Value of 0 means continuous transmission.Greater than 1 is invalid */ + unsigned char tx_mode; + /** Number of packets to be transmitted. Any number above 0. + * Set -1 for continuous transmission + */ + signed int tx_pkt_num; + /** Length of the packet (in bytes) to be transmitted */ + unsigned short tx_pkt_len; + /** Desired TX power in dBm in the range 0 dBm to 21 dBm in steps of 1 dBm */ + unsigned int tx_power; + /** Transmit WLAN packet */ + unsigned char tx; + /** Receive WLAN packet */ + unsigned char rx; + /** Not required */ + unsigned char aux_adc_input_chain_id; + /** Unused */ + unsigned char agg; + /** Select HE LTF type viz, 0->1x, 1->2x and 2->4x */ + unsigned char he_ltf; + /** Select HE LTF type viz, 0->0.8us, 1->1.6us and 2->3.2us */ + unsigned char he_gi; + /** Not required */ + unsigned char set_he_ltf_gi; + /** Not required */ + unsigned char power_save; + /** Not required */ + unsigned int rts_threshold; + /** Not required */ + unsigned int uapsd_queue; + /** Interval between TX packets in us (Min: 200, Max: 200000, Default: 200) */ + unsigned int tx_pkt_gap_us; + /** Configure WLAN antenna switch(0-separate/1-shared) */ + unsigned char wlan_ant_switch_ctrl; + /** Switch to control the BLE antenna or shared WiFi antenna */ + unsigned char ble_ant_switch_ctrl; + /** Resource unit (RU) size (26,52,106 or 242) */ + unsigned char ru_tone; + /** Location of resource unit (RU) in 20 MHz spectrum */ + unsigned char ru_index; + /** Desired tone frequency to be transmitted */ + signed char tx_tone_freq; + /** RX LNA gain */ + unsigned char lna_gain; + /** RX BB gain */ + unsigned char bb_gain; + /** Number of RX samples to be captured */ + unsigned short int capture_length; + /** Configure WLAN to bypass regulatory */ + unsigned char bypass_regulatory; + /** Two letter country code (00: Default for WORLD) */ + unsigned char country_code[NRF_WIFI_COUNTRY_CODE_LEN]; + /** Contention window value to be configured */ + unsigned int tx_pkt_cw; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to configure the RPU with different + * PHY configuration parameters specifically designed for RF test and Radio test scenarios. + * The command is intended to set up the RPU for testing and evaluating the performance + * of the radio hardware. + * + */ + +struct nrf_wifi_cmd_mode_params { + /** UMAC header, See &struct nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** configuration parameters of different modes see &union rpu_conf_params */ + struct rpu_conf_params conf; + /** Packet length */ + unsigned short pkt_length[MAX_TX_AGG_SIZE]; + /** Packet ddr pointer */ + unsigned int ddr_ptrs[MAX_TX_AGG_SIZE]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the parameters required to initialize a radio test. + * + */ +struct nrf_wifi_radio_test_init_info { + /** An array containing RF & baseband control params */ + unsigned char rf_params[NRF_WIFI_RF_PARAMS_SIZE]; + /** Channel related info viz, channel, bandwidth, primary 20 offset */ + struct chan_params chan; + /** Phy threshold value to be sent to LMAC in channel programming */ + signed char phy_threshold; + /** Calibration bit map value. refer phy_rf_params.h NRF_WIFI_DEF_PHY_CALIB */ + unsigned int phy_calib; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to initialize a radio test. + * + */ +struct nrf_wifi_cmd_radio_test_init { + /** UMAC header, @ref nrf_wifi_sys_head*/ + struct nrf_wifi_sys_head sys_head; + /** radiotest init configuration parameters @ref nrf_wifi_radio_test_init_info */ + struct nrf_wifi_radio_test_init_info conf; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to enable or disable the reception (Rx). + * It allows controlling the radio hardware's receive functionality to start or stop listening + * for incoming data frames. + */ + +struct nrf_wifi_cmd_rx { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** rx configuration parameters @ref rpu_conf_rx_radio_test_params */ + struct rpu_conf_rx_radio_test_params conf; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to retrieve statistics from the RPU. + * + */ +struct nrf_wifi_cmd_get_stats { + /** UMAC header, @ref nrf_wifi_sys_head*/ + struct nrf_wifi_sys_head sys_head; + /** Statistics type &enum rpu_stats_type */ + signed int stats_type; + /** Production mode or FCM mode */ + signed int op_mode; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to clear or reset statistics. + * + * + */ +struct nrf_wifi_cmd_clear_stats { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** Type of statistics to clear &enum rpu_stats_type */ + signed int stats_type; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command used to obtain power monitor information + * specific to different data types. + * + */ +struct nrf_wifi_cmd_pwr { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** Type of Control info that host need */ + signed int data_type; +} __NRF_WIFI_PKD; + +/** + * @brief Structure for coexistence (coex) switch configuration. + * + */ +struct coex_wlan_switch_ctrl { + /** Host to coexistence manager message id */ + signed int rpu_msg_id; + /** Switch configuration value */ + signed int switch_A; +} __NRF_WIFI_PKD; + +/** + * @brief The structure represents the command used to configure the Wi-Fi side shared switch + * for Bluetooth coexistence (btcoex). + * + */ +struct nrf_wifi_cmd_btcoex { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** Switch configuration data */ + struct coex_wlan_switch_ctrl conf; +} __NRF_WIFI_PKD; + +/** + * @brief The structure defines the parameters used to configure the coexistence hardware. + * + */ + +struct rpu_cmd_coex_config_info { + /** Length of coexistence configuration data */ + unsigned int len; + /** Coexistence configuration data */ + unsigned char coex_cmd[0]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to configure the coexistence hardware. + * + */ +struct nrf_wifi_cmd_coex_config { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** Coexistence configuration data. @ref rpu_cmd_coex_config_info */ + struct rpu_cmd_coex_config_info coex_config_info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure describes the coexistence configuration data received + * in the NRF_WIFI_EVENT_COEX_CONFIG event. + * + */ +struct rpu_evnt_coex_config_info { + /** Length of coexistence configuration data */ + unsigned int len; + /** Coexistence configuration data */ + unsigned char coex_event[0]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the event used to represent coexistence configuration. + * + */ +struct nrf_wifi_event_coex_config { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** Coexistence configuration data in the event. @ref rpu_evnt_coex_config_info */ + struct rpu_evnt_coex_config_info coex_config_info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to fix the transmission (Tx) data rate. + * The command allows setting a specific data rate for data transmission, ensuring that the + * system uses the designated rate instead of dynamically adapting to changing channel conditions. + * + */ + +struct nrf_wifi_cmd_fix_tx_rate { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** refer see &enum rpu_tput_mode */ + unsigned char rate_flags; + /** fixed_rate: -1 Disable fixed rate and use ratecontrol selected rate + * fixed rate: >0 legacy rates: 1,2,55,11,6,9,12,18,24,36,48,54 + * 11N VHT HE : MCS index 0 to 7. + */ + int fixed_rate; +} __NRF_WIFI_PKD; + +/** + * @brief This structure describes rf test command information. + * + */ +struct rpu_cmd_rftest_info { + /** length of the rf test command */ + unsigned int len; + /** Rf test command data */ + unsigned char rfcmd[0]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used for RF (Radio Frequency) testing. + * RF test commands are specifically designed to configure and control the radio hardware + * for conducting tests and evaluating its performance in various scenarios. + * + */ +struct nrf_wifi_cmd_rftest { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** @ref rpu_cmd_rftest_info */ + struct rpu_cmd_rftest_info rf_test_info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure describes rf test event information. + * + */ +struct rpu_evnt_rftest_info { + /** length of the rf test event */ + unsigned int len; + /** Rf test event data */ + unsigned char rfevent[0]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure describes the event generated during RF (Radio Frequency) testing. + * + */ +struct nrf_wifi_event_rftest { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** @ref rpu_evnt_rftest_info */ + struct rpu_evnt_rftest_info rf_test_info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the power data event generated in response to + * the NRF_WIFI_CMD_PWR command. + * + * The NRF_WIFI_CMD_PWR command is used to retrieve power-related data or measurements + * from the radio hardware. + * + */ +struct nrf_wifi_event_pwr_data { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** Power monitor command status info */ + signed int mon_status; + /** Data */ + signed int data_type; + /** Data that host may want to read from Power IP */ + struct nrf_wifi_rpu_pwr_data data; +} __NRF_WIFI_PKD; + +/** + * @brief This structure is a comprehensive combination of all the firmware statistics + * that the RPU (Radio Processing Unit) can provide. + * + */ +struct rpu_fw_stats { + /** PHY statistics @ref rpu_phy_stats */ + struct rpu_phy_stats phy; +#ifndef CONFIG_NRF700X_RADIO_TEST + /** LMAC statistics @ref rpu_lmac_stats */ + struct rpu_lmac_stats lmac; + /** UMAC statistics @ref rpu_umac_stats */ + struct rpu_umac_stats umac; +#endif /* !CONFIG_NRF700X_RADIO_TEST */ +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the event that provides RPU statistics in response + * to the command NRF_WIFI_CMD_GET_STATS in a wireless communication system. + * + * The NRF_WIFI_CMD_GET_STATS command is used to request various statistics from the RPU. + * + */ + +struct nrf_wifi_umac_event_stats { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** All the statistics that the firmware can provide @ref rpu_fw_stats*/ + struct rpu_fw_stats fw; +} __NRF_WIFI_PKD; + +/** + * @brief This enum defines various error status values that may occur during a radio test. + * + */ +enum nrf_wifi_radio_test_err_status { + /** Command success */ + NRF_WIFI_UMAC_CMD_SUCCESS = 1, + /** Invalid channel error */ + NRF_WIFI_UMAC_INVALID_CHNL +}; + +/** + * @brief This structure defines an event that indicates the error status values that may occur + * during a radio test. It serves as a response to the radio test commands. + * + */ +struct nrf_wifi_umac_event_err_status { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** status of the command, Fail/success &enum nrf_wifi_radio_test_err_status */ + unsigned int status; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the UMAC initialization done event. + * The event is sent by the RPU (Radio Processing Unit) in response to + * the NRF_WIFI_CMD_INIT command, indicating that the RPU initialization + * process has been completed successfully. + */ + +struct nrf_wifi_event_init_done { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; +} __NRF_WIFI_PKD; + +/** + * @brief structure for UMAC memory pool information. + * + */ +struct pool_data_to_host { + /** Size of the memory buffer */ + unsigned int buffer_size; + /** Number of pool items available for the above memory buffer */ + unsigned char num_pool_items; + /** Maximum pools allocated at any point of time */ + unsigned char items_num_max_allocated; + /** Currently allocated pools */ + unsigned char items_num_cur_allocated; + /** Total number of pool allocated */ + unsigned int items_num_total_allocated; + /** Number of times this memory pool is full */ + unsigned int items_num_not_allocated; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the event that provides UMAC (Upper MAC) internal + * memory statistics in response to the NRF_WIFI_CMD_UMAC_INT_STATS command. + * + */ +struct umac_int_stats { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; + /** See @ref pool_data_to_host */ + struct pool_data_to_host scratch_dynamic_memory_info[56]; + /** See @ref pool_data_to_host */ + struct pool_data_to_host retention_dynamic_memory_info[56]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the event that indicates the completion of UMAC + * deinitialization. The RPU sends this event as a response to the NRF_WIFI_CMD_DEINIT + * command, signaling that the UMAC has been successfully deinitialized. + */ + +struct nrf_wifi_event_deinit_done { + /** UMAC header, @ref nrf_wifi_sys_head */ + struct nrf_wifi_sys_head sys_head; +} __NRF_WIFI_PKD; + +#endif /* __HOST_RPU_SYS_IF_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_umac_if.h b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_umac_if.h new file mode 100644 index 0000000000..7b9cb9089d --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fw/host_rpu_umac_if.h @@ -0,0 +1,3472 @@ +/* + * + *Copyright (c) 2022 Nordic Semiconductor ASA + * + *SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @file + * @brief Control interface between host and RPU + */ + +#ifndef __HOST_RPU_UMAC_IF_H +#define __HOST_RPU_UMAC_IF_H + +#include "host_rpu_data_if.h" +#include "host_rpu_sys_if.h" + +#include "pack_def.h" + +#define MAX_NRF_WIFI_UMAC_CMD_SIZE 400 + +/** + * @brief The host can send the following commands to the RPU. + * + */ +enum nrf_wifi_umac_commands { + /** Trigger a new scan @ref nrf_wifi_umac_cmd_scan */ + NRF_WIFI_UMAC_CMD_TRIGGER_SCAN, + /** Request for scan results @ref nrf_wifi_umac_cmd_get_scan_results */ + NRF_WIFI_UMAC_CMD_GET_SCAN_RESULTS, + /** Send authentication request to AP @ref nrf_wifi_umac_cmd_auth */ + NRF_WIFI_UMAC_CMD_AUTHENTICATE, + /** Send associate request to AP @ref nrf_wifi_umac_cmd_assoc */ + NRF_WIFI_UMAC_CMD_ASSOCIATE, + /** Send deauthentication request to AP @ref nrf_wifi_umac_cmd_disconn */ + NRF_WIFI_UMAC_CMD_DEAUTHENTICATE, + /** Set wiphy parameters @ref nrf_wifi_umac_cmd_set_wiphy */ + NRF_WIFI_UMAC_CMD_SET_WIPHY, + /** Add new key @ref nrf_wifi_umac_cmd_key */ + NRF_WIFI_UMAC_CMD_NEW_KEY, + /** Delete key @ref nrf_wifi_umac_cmd_key */ + NRF_WIFI_UMAC_CMD_DEL_KEY, + /** Set default key to use @ref nrf_wifi_umac_cmd_set_key */ + NRF_WIFI_UMAC_CMD_SET_KEY, + /** Unused */ + NRF_WIFI_UMAC_CMD_GET_KEY, + /** Unused */ + NRF_WIFI_UMAC_CMD_NEW_BEACON, + /** Change the beacon on an AP interface @ref nrf_wifi_umac_cmd_set_beacon */ + NRF_WIFI_UMAC_CMD_SET_BEACON, + /** Set the BSS @ref nrf_wifi_umac_cmd_set_bss */ + NRF_WIFI_UMAC_CMD_SET_BSS, + /** Start soft AP operation on an AP interface @ref nrf_wifi_umac_cmd_start_ap */ + NRF_WIFI_UMAC_CMD_START_AP, + /** Stop soft AP operation @ref nrf_wifi_umac_cmd_stop_ap */ + NRF_WIFI_UMAC_CMD_STOP_AP, + /** Create new interface @ref nrf_wifi_umac_cmd_add_vif */ + NRF_WIFI_UMAC_CMD_NEW_INTERFACE, + /** Change interface configuration @ref nrf_wifi_umac_cmd_chg_vif_attr*/ + NRF_WIFI_UMAC_CMD_SET_INTERFACE, + /** Delete interface @ref nrf_wifi_umac_cmd_del_vif */ + NRF_WIFI_UMAC_CMD_DEL_INTERFACE, + /** Change interface flags @ref nrf_wifi_umac_cmd_chg_vif_state */ + NRF_WIFI_UMAC_CMD_SET_IFFLAGS, + /** Add a new station @ref nrf_wifi_umac_cmd_add_sta */ + NRF_WIFI_UMAC_CMD_NEW_STATION, + /** Delete station @ref nrf_wifi_umac_cmd_del_sta */ + NRF_WIFI_UMAC_CMD_DEL_STATION, + /** Change station info @ref nrf_wifi_umac_cmd_chg_sta */ + NRF_WIFI_UMAC_CMD_SET_STATION, + /** Get station info @ref nrf_wifi_umac_cmd_get_sta */ + NRF_WIFI_UMAC_CMD_GET_STATION, + /** Start the P2P device @ref nrf_wifi_cmd_start_p2p */ + NRF_WIFI_UMAC_CMD_START_P2P_DEVICE, + /** Stop the P2P device @ref nrf_wifi_umac_cmd_stop_p2p_dev */ + NRF_WIFI_UMAC_CMD_STOP_P2P_DEVICE, + /** Remain awake on the specified channel @ref nrf_wifi_umac_cmd_remain_on_channel */ + NRF_WIFI_UMAC_CMD_REMAIN_ON_CHANNEL, + /** Cancel a pending ROC duration @ref nrf_wifi_umac_cmd_cancel_remain_on_channel */ + NRF_WIFI_UMAC_CMD_CANCEL_REMAIN_ON_CHANNEL, + /** Unused */ + NRF_WIFI_UMAC_CMD_SET_CHANNEL, + /** Unused */ + NRF_WIFI_UMAC_CMD_RADAR_DETECT, + /** Whitelist filter based on frame types @ref nrf_wifi_umac_cmd_mgmt_frame_reg */ + NRF_WIFI_UMAC_CMD_REGISTER_FRAME, + /** Send a management frame @ref nrf_wifi_umac_cmd_mgmt_tx */ + NRF_WIFI_UMAC_CMD_FRAME, + /** Unused */ + NRF_WIFI_UMAC_CMD_JOIN_IBSS, + /** Unused */ + NRF_WIFI_UMAC_CMD_WIN_STA_CONNECT, + /** Power save Enable/Disable @ref nrf_wifi_umac_cmd_set_power_save */ + NRF_WIFI_UMAC_CMD_SET_POWER_SAVE, + /** Unused */ + NRF_WIFI_UMAC_CMD_SET_WOWLAN, + /** Unused */ + NRF_WIFI_UMAC_CMD_SUSPEND, + /** Unused */ + NRF_WIFI_UMAC_CMD_RESUME, + /** QOS map @ref nrf_wifi_umac_cmd_set_qos_map */ + NRF_WIFI_UMAC_CMD_SET_QOS_MAP, + /** Get Channel info @ref nrf_wifi_umac_cmd_get_channel */ + NRF_WIFI_UMAC_CMD_GET_CHANNEL, + /** Get Tx power level @ref nrf_wifi_umac_cmd_get_tx_power */ + NRF_WIFI_UMAC_CMD_GET_TX_POWER, + /** Get interface @ref nrf_wifi_cmd_get_interface */ + NRF_WIFI_UMAC_CMD_GET_INTERFACE, + /** Get Wiphy info @ref nrf_wifi_cmd_get_wiphy */ + NRF_WIFI_UMAC_CMD_GET_WIPHY, + /** Get hardware address @ref nrf_wifi_cmd_get_ifhwaddr */ + NRF_WIFI_UMAC_CMD_GET_IFHWADDR, + /** Set hardware address @ref nrf_wifi_cmd_set_ifhwaddr */ + NRF_WIFI_UMAC_CMD_SET_IFHWADDR, + /** Get regulatory domain @ref nrf_wifi_umac_cmd_get_reg */ + NRF_WIFI_UMAC_CMD_GET_REG, + /** Unused */ + NRF_WIFI_UMAC_CMD_SET_REG, + /** Set regulatory domain @ref nrf_wifi_cmd_req_set_reg */ + NRF_WIFI_UMAC_CMD_REQ_SET_REG, + /** Config UAPSD @ref nrf_wifi_umac_cmd_config_uapsd */ + NRF_WIFI_UMAC_CMD_CONFIG_UAPSD, + /** Config TWT @ref nrf_wifi_umac_cmd_config_twt */ + NRF_WIFI_UMAC_CMD_CONFIG_TWT, + /** Teardown TWT @ref nrf_wifi_umac_cmd_teardown_twt */ + NRF_WIFI_UMAC_CMD_TEARDOWN_TWT, + /** Abort scan @ref nrf_wifi_umac_cmd_abort_scan */ + NRF_WIFI_UMAC_CMD_ABORT_SCAN, + /** Multicast filter @ref nrf_wifi_umac_cmd_mcast_filter */ + NRF_WIFI_UMAC_CMD_MCAST_FILTER, + /** Change macaddress @ref nrf_wifi_umac_cmd_change_macaddr */ + NRF_WIFI_UMAC_CMD_CHANGE_MACADDR, + /** Set powersave timeout @ref nrf_wifi_umac_cmd_set_power_save_timeout */ + NRF_WIFI_UMAC_CMD_SET_POWER_SAVE_TIMEOUT, + /** Get connection information @ref nrf_wifi_umac_cmd_conn_info */ + NRF_WIFI_UMAC_CMD_GET_CONNECTION_INFO, + /** Get power save information @ref nrf_wifi_umac_cmd_get_power_save_info */ + NRF_WIFI_UMAC_CMD_GET_POWER_SAVE_INFO, + /** Set listen interval @ref nrf_wifi_umac_cmd_set_listen_interval */ + NRF_WIFI_UMAC_CMD_SET_LISTEN_INTERVAL, + /** Configure extended power save @ref nrf_wifi_umac_cmd_config_extended_ps */ + NRF_WIFI_UMAC_CMD_CONFIG_EXTENDED_PS +}; + + /** + * @brief The host can receive the following events from the RPU. + * + */ + +enum nrf_wifi_umac_events { + NRF_WIFI_UMAC_EVENT_UNSPECIFIED = 256, + /** Indicate scan started @ref nrf_wifi_umac_event_trigger_scan */ + NRF_WIFI_UMAC_EVENT_TRIGGER_SCAN_START, + /** Unused */ + NRF_WIFI_UMAC_EVENT_SCAN_ABORTED, + /** Indicate scan done @ref nrf_wifi_umac_event_scan_done */ + NRF_WIFI_UMAC_EVENT_SCAN_DONE, + /** Scan result event @ref nrf_wifi_umac_event_new_scan_results */ + NRF_WIFI_UMAC_EVENT_SCAN_RESULT, + /** Authentication status @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_AUTHENTICATE, + /** Association status @ref nrf_wifi_umac_event_mlme*/ + NRF_WIFI_UMAC_EVENT_ASSOCIATE, + /** Unused */ + NRF_WIFI_UMAC_EVENT_CONNECT, + /** Station deauth event @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_DEAUTHENTICATE, + /** Station disassoc event @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_DISASSOCIATE, + /** Station added indication @ref nrf_wifi_umac_event_new_station */ + NRF_WIFI_UMAC_EVENT_NEW_STATION, + /** Station added indication @ref nrf_wifi_umac_event_new_station */ + NRF_WIFI_UMAC_EVENT_DEL_STATION, + /** Station info indication @ref nrf_wifi_umac_event_new_station */ + NRF_WIFI_UMAC_EVENT_GET_STATION, + /** remain on channel event @ref nrf_wifi_event_remain_on_channel */ + NRF_WIFI_UMAC_EVENT_REMAIN_ON_CHANNEL, + /** Unused */ + NRF_WIFI_UMAC_EVENT_CANCEL_REMAIN_ON_CHANNEL, + /** Unused */ + NRF_WIFI_UMAC_EVENT_DISCONNECT, + /** RX management frame @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_FRAME, + /** Cookie mapping for NRF_WIFI_UMAC_CMD_FRAME @ref nrf_wifi_umac_event_cookie_rsp */ + NRF_WIFI_UMAC_EVENT_COOKIE_RESP, + /** TX management frame transmitted @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_FRAME_TX_STATUS, + /** @ref nrf_wifi_umac_event_vif_state */ + NRF_WIFI_UMAC_EVENT_IFFLAGS_STATUS, + /** Send Tx power @ref nrf_wifi_umac_event_get_tx_power */ + NRF_WIFI_UMAC_EVENT_GET_TX_POWER, + /** Send Channel info @ref nrf_wifi_umac_event_get_channel */ + NRF_WIFI_UMAC_EVENT_GET_CHANNEL, + /** @ref nrf_wifi_umac_event_set_interface */ + NRF_WIFI_UMAC_EVENT_SET_INTERFACE, + /** @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_UNPROT_DEAUTHENTICATE, + /** @ref nrf_wifi_umac_event_mlme */ + NRF_WIFI_UMAC_EVENT_UNPROT_DISASSOCIATE, + /** @ref nrf_wifi_interface_info */ + NRF_WIFI_UMAC_EVENT_NEW_INTERFACE, + /** @ref nrf_wifi_event_get_wiphy */ + NRF_WIFI_UMAC_EVENT_NEW_WIPHY, + /** Unused */ + NRF_WIFI_UMAC_EVENT_GET_IFHWADDR, + /** Get regulatory @ref nrf_wifi_reg */ + NRF_WIFI_UMAC_EVENT_GET_REG, + /** Unused */ + NRF_WIFI_UMAC_EVENT_SET_REG, + /** Unused */ + NRF_WIFI_UMAC_EVENT_REQ_SET_REG, + /** Unused */ + NRF_WIFI_UMAC_EVENT_GET_KEY, + /** Unused */ + NRF_WIFI_UMAC_EVENT_BEACON_HINT, + /** Unused */ + NRF_WIFI_UMAC_EVENT_REG_CHANGE, + /** Unused */ + NRF_WIFI_UMAC_EVENT_WIPHY_REG_CHANGE, + /** Display scan result @ref nrf_wifi_umac_event_new_scan_display_results */ + NRF_WIFI_UMAC_EVENT_SCAN_DISPLAY_RESULT, + /** @ref nrf_wifi_umac_event_cmd_status */ + NRF_WIFI_UMAC_EVENT_CMD_STATUS, + /** @ref nrf_wifi_umac_event_new_scan_results */ + NRF_WIFI_UMAC_EVENT_BSS_INFO, + /** Send TWT response information @ref nrf_wifi_umac_cmd_config_twt */ + NRF_WIFI_UMAC_EVENT_CONFIG_TWT, + /** Send TWT teardown information @ref nrf_wifi_umac_cmd_teardown_twt */ + NRF_WIFI_UMAC_EVENT_TEARDOWN_TWT, + /** Send block or unblock state @ref nrf_wifi_umac_event_twt_sleep */ + NRF_WIFI_UMAC_EVENT_TWT_SLEEP, + /** Unused */ + NRF_WIFI_UMAC_EVENT_COALESCING, + /** Unused */ + NRF_WIFI_UMAC_EVENT_MCAST_FILTER, + /** send connection information @ref nrf_wifi_umac_event_conn_info. */ + NRF_WIFI_UMAC_EVENT_GET_CONNECTION_INFO, + /** @ref nrf_wifi_umac_event_power_save_info */ + NRF_WIFI_UMAC_EVENT_GET_POWER_SAVE_INFO +}; + +/** + * @brief Represents the values that can be used to specify the frequency band. + * + */ + +enum nrf_wifi_band { + /** 2.4 GHz ISM band */ + NRF_WIFI_BAND_2GHZ, + /** Around 5 GHz band (4.9 - 5.7 GHz) */ + NRF_WIFI_BAND_5GHZ, + /** Unused */ + NRF_WIFI_BAND_60GHZ, + /** Invalid */ + NRF_WIFI_BAND_INVALID +}; + +/** + * @brief Enable or Disable Management Frame Protection. + * + */ +enum nrf_wifi_mfp { + /** Management frame protection not used */ + NRF_WIFI_MFP_NO, + /** Management frame protection required */ + NRF_WIFI_MFP_REQUIRED, +}; + +/** + * @brief Enumerates the various categories of security keys. + * + */ +enum nrf_wifi_key_type { + /** Group (broadcast/multicast) key */ + NRF_WIFI_KEYTYPE_GROUP, + /** Pairwise (unicast/individual) key */ + NRF_WIFI_KEYTYPE_PAIRWISE, + /** Peer key (DLS) */ + NRF_WIFI_KEYTYPE_PEERKEY, + /** Number of defined key types */ + NUM_NRF_WIFI_KEYTYPES +}; + +/** + * @brief Enumerates the various types of authentication mechanisms. + * + */ +enum nrf_wifi_auth_type { + /** Open System authentication */ + NRF_WIFI_AUTHTYPE_OPEN_SYSTEM, + /** Shared Key authentication (WEP only) */ + NRF_WIFI_AUTHTYPE_SHARED_KEY, + /** Fast BSS Transition (IEEE 802.11r) */ + NRF_WIFI_AUTHTYPE_FT, + /** Network EAP (some Cisco APs and mainly LEAP) */ + NRF_WIFI_AUTHTYPE_NETWORK_EAP, + /** Simultaneous authentication of equals */ + NRF_WIFI_AUTHTYPE_SAE, + /** Internal */ + __NRF_WIFI_AUTHTYPE_NUM, + /** Maximum valid auth algorithm */ + NRF_WIFI_AUTHTYPE_MAX = __NRF_WIFI_AUTHTYPE_NUM, + /** Determine automatically (if necessary by trying multiple times) */ + NRF_WIFI_AUTHTYPE_AUTOMATIC +}; + +/** + * @brief Represents the interface's status concerning this BSS (Basic Service Set). + * + */ +enum nrf_wifi_bss_status { + /** + * Authenticated with this BSS + * Note that this is no longer used since cfg80211 no longer + * keeps track of whether or not authentication was done with + * a given BSS. + */ + NRF_WIFI_BSS_STATUS_AUTHENTICATED, + /** Associated with this BSS */ + NRF_WIFI_BSS_STATUS_ASSOCIATED, + /** Joined to this IBSS */ + NRF_WIFI_BSS_STATUS_IBSS_JOINED, +}; + +/** + * @brief Enumerates the various categories of channels. + * + */ +enum nrf_wifi_channel_type { + /** 20 MHz, non-HT channel */ + NRF_WIFI_CHAN_NO_HT, + /** 20 MHz HT channel */ + NRF_WIFI_CHAN_HT20, + /** HT40 channel, secondary channel below the control channel */ + NRF_WIFI_CHAN_HT40MINUS, + /** HT40 channel, secondary channel above the control channel */ + NRF_WIFI_CHAN_HT40PLUS +}; + +/** + * @brief Enumerates the various channel widths available. + * + */ +enum nrf_wifi_chan_width { + /** 20 MHz, non-HT channel */ + NRF_WIFI_CHAN_WIDTH_20_NOHT, + /** 20 MHz HT channel */ + NRF_WIFI_CHAN_WIDTH_20, + /** 40 MHz channel, the @ref %NRF_WIFI_ATTR_CENTER_FREQ1 must be provided as well */ + NRF_WIFI_CHAN_WIDTH_40, + /** 80 MHz channel, the @ref %NRF_WIFI_ATTR_CENTER_FREQ1 must be provided as well */ + NRF_WIFI_CHAN_WIDTH_80, + /** 80+80 MHz channel, the @ref %NRF_WIFI_ATTR_CENTER_FREQ1 and + * @ref %NRF_WIFI_ATTR_CENTER_FREQ2 must be provided as well + */ + NRF_WIFI_CHAN_WIDTH_80P80, + /** 160 MHz channel, the %NRF_WIFI_ATTR_CENTER_FREQ1 must be provided as well */ + NRF_WIFI_CHAN_WIDTH_160, + /** 5 MHz OFDM channel */ + NRF_WIFI_CHAN_WIDTH_5, + /** 10 MHz OFDM channel */ + NRF_WIFI_CHAN_WIDTH_10, +}; + +/** + * @brief Interface types based on functionality. + * + */ +enum nrf_wifi_iftype { + /** Unspecified type, driver decides */ + NRF_WIFI_IFTYPE_UNSPECIFIED, + /** Not Supported */ + NRF_WIFI_IFTYPE_ADHOC, + /** Managed BSS member */ + NRF_WIFI_IFTYPE_STATION, + /** Access point */ + NRF_WIFI_IFTYPE_AP, + /** Not Supported */ + NRF_WIFI_IFTYPE_AP_VLAN, + /** Not Supported */ + NRF_WIFI_IFTYPE_WDS, + /** Not Supported */ + NRF_WIFI_IFTYPE_MONITOR, + /** Not Supported */ + NRF_WIFI_IFTYPE_MESH_POINT, + /** P2P client */ + NRF_WIFI_IFTYPE_P2P_CLIENT, + /** P2P group owner */ + NRF_WIFI_IFTYPE_P2P_GO, + /** P2P device use the @ref %NRF_WIFI_UMAC_CMD_START_P2P_DEVICE & + * @ref %NRF_WIFI_UMAC_CMD_STOP_P2P_DEVICE commands to create and destroy one + */ + NRF_WIFI_IFTYPE_P2P_DEVICE, + /** Not Supported */ + NRF_WIFI_IFTYPE_OCB, + /** Highest interface type number currently defined */ + NUM_NRF_WIFI_IFTYPES, + /** Number of defined interface types */ + NRF_WIFI_IFTYPE_MAX = NUM_NRF_WIFI_IFTYPES - 1 +}; + +/** + * @brief Powersave state. + * + */ +enum nrf_wifi_ps_state { + /** powersave is disabled */ + NRF_WIFI_PS_DISABLED, + /** powersave is enabled */ + NRF_WIFI_PS_ENABLED, +}; + +/** + * @brief WLAN security types. + * + */ +enum nrf_wifi_security_type { + /** OPEN */ + NRF_WIFI_OPEN, + /** WEP */ + NRF_WIFI_WEP, + /** WPA */ + NRF_WIFI_WPA, + /** WPA2 */ + NRF_WIFI_WPA2, + /** WPA3 */ + NRF_WIFI_WPA3, + /** WAPI */ + NRF_WIFI_WAPI, + /** Enterprise mode */ + NRF_WIFI_EAP, + /** WPA2 sha 256 */ + NRF_WIFI_WPA2_256 +}; + +/** + * @brief Denotes the originator of a regulatory domain request. + * + */ +enum nrf_wifi_reg_initiator { + /** Core queried CRDA for a dynamic world regulatory domain */ + NRF_WIFI_REGDOM_SET_BY_CORE, + /** User asked the wireless core to set the regulatory domain */ + NRF_WIFI_REGDOM_SET_BY_USER, + /** + * A wireless drivers has hinted to the wireless core it thinks + * its knows the regulatory domain we should be in + */ + NRF_WIFI_REGDOM_SET_BY_DRIVER, + /** + * the wireless core has received an + * 802.11 country information element with regulatory information it + * thinks we should consider. cfg80211 only processes the country + * code from the IE, and relies on the regulatory domain information + * structure passed by userspace (CRDA) from our wireless-regdb + * If a channel is enabled but the country code indicates it should + * be disabled we disable the channel and re-enable it upon disassociation + */ + NRF_WIFI_REGDOM_SET_BY_COUNTRY_IE, +}; + +/** + * @brief Specifies the type of regulatory domain. + * + */ +enum nrf_wifi_reg_type { + /** + * the regulatory domain set is one that pertains + * to a specific country. When this is set you can count on the + * ISO / IEC 3166 alpha2 country code being valid. + * + */ + NRF_WIFI_REGDOM_TYPE_COUNTRY, + /** the regulatory set domain is the world regulatory domain */ + NRF_WIFI_REGDOM_TYPE_WORLD, + /** + * the regulatory domain set is a custom + * driver specific world regulatory domain. These do not apply system-wide + * and are only applicable to the individual devices which have requested + * them to be applied. + */ + NRF_WIFI_REGDOM_TYPE_CUSTOM_WORLD, + /** + * the regulatory domain set is the product + * of an intersection between two regulatory domains -- the previously + * set regulatory domain on the system and the last accepted regulatory + * domain request to be processed. + */ + NRF_WIFI_REGDOM_TYPE_INTERSECTION, +}; + +#define NRF_WIFI_MAX_SSID_LEN 32 + +/** + * @brief This structure provides details about the SSID. + * + */ + +struct nrf_wifi_ssid { + /** length of SSID */ + unsigned char nrf_wifi_ssid_len; + /** SSID string */ + unsigned char nrf_wifi_ssid[NRF_WIFI_MAX_SSID_LEN]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_MAX_IE_LEN 400 + +/** + * @brief This structure contains data related to the Information Elements (IEs). + * + */ + +struct nrf_wifi_ie { + /** length of IE */ + unsigned short ie_len; + /** Information element data */ + signed char ie[NRF_WIFI_MAX_IE_LEN]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_MAX_SEQ_LENGTH 256 + +/** + * @brief Transmit key sequence number. + * + */ + +struct nrf_wifi_seq { + /** Length of the seq parameter */ + signed int nrf_wifi_seq_len; + /** Key sequence number data */ + unsigned char nrf_wifi_seq[NRF_WIFI_MAX_SEQ_LENGTH]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_MAX_KEY_LENGTH 256 + +/** + * @brief This structure holds information related to a security key. + * + */ + +struct nrf_wifi_key { + /** Length of the key data */ + unsigned int nrf_wifi_key_len; + /** Key data */ + unsigned char nrf_wifi_key[NRF_WIFI_MAX_KEY_LENGTH]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_MAX_SAE_DATA_LENGTH 256 + +/** + * @brief This structure represents SAE elements in Authentication frame. + * + */ + +struct nrf_wifi_sae { + /** Length of SAE element data */ + signed int sae_data_len; + /** SAE element data */ + unsigned char sae_data[NRF_WIFI_MAX_SAE_DATA_LENGTH]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_MAX_FRAME_LEN 400 + +/** + * @brief This structure defines the frame that is intended for transmission. + * + */ + +struct nrf_wifi_frame { + /** Length of the frame */ + signed int frame_len; + /** frame data */ + signed char frame[NRF_WIFI_MAX_FRAME_LEN]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_INDEX_IDS_WDEV_ID_VALID (1 << 0) +#define NRF_WIFI_INDEX_IDS_IFINDEX_VALID (1 << 1) +#define NRF_WIFI_INDEX_IDS_WIPHY_IDX_VALID (1 << 2) + +/** + * @brief This structure contains details about the interface information. + * + */ + +struct nrf_wifi_index_ids { + /** Indicate which properties below are set */ + unsigned int valid_fields; + /** wdev id */ + signed int ifaceindex; + /** Unused */ + signed int nrf_wifi_wiphy_idx; + /** Unused */ + unsigned long long wdev_id; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_SUPP_RATES_BAND_VALID (1 << 0) +#define NRF_WIFI_MAX_SUPP_RATES 60 + +/** + * @brief This structure provides information about the rate parameters. + * + */ + +struct nrf_wifi_supp_rates { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Frequency band, see &enum nrf_wifi_band */ + signed int band; + /** Number of values in rates parameter */ + signed int nrf_wifi_num_rates; + /** List of supported rates as defined by IEEE 802.11 7.3.2.2 */ + unsigned char rates[NRF_WIFI_MAX_SUPP_RATES]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure contains details about a channel's information. + * + */ +struct nrf_wifi_channel { + /** band this channel belongs to */ + signed int band; + /** center frequency in MHz */ + unsigned int center_frequency; + /** channel flags from see &enum nrf_wifi_channel_flags */ + unsigned int nrf_wifi_flags; + /** maximum antenna gain in dBi */ + signed int nrf_wifi_max_antenna_gain; + /** maximum transmission power (in dBm) */ + signed int nrf_wifi_max_power; + /** maximum regulatory transmission power (in dBm) */ + signed int nrf_wifi_max_reg_power; + /** channel flags at registration time, used by regulatory + * code to support devices with additional restrictions + */ + unsigned int nrf_wifi_orig_flags; + /** internal use */ + signed int nrf_wifi_orig_mag; + /** internal use */ + signed int nrf_wifi_orig_mpwr; + /** hardware-specific value for the channel */ + unsigned short hw_value; + /** helper to regulatory code to indicate when a beacon + * has been found on this channel. Use regulatory_hint_found_beacon() + * to enable this, this is useful only on 5 GHz band. + */ + signed char nrf_wifi_beacon_found; +} __NRF_WIFI_PKD; + + + +#define NRF_WIFI_SCAN_MAX_NUM_SSIDS 2 +#define NRF_WIFI_SCAN_MAX_NUM_FREQUENCIES 64 + +#define NRF_WIFI_SCAN_BAND_2GHZ (1 << 0) +#define NRF_WIFI_SCAN_BAND_5GHZ (1 << 1) +#define NRF_WIFI_SCAN_BAND_6GHZ (1 << 2) + +/** + * @brief This structure provides details about the parameters required for a scan request. + * + */ +struct nrf_wifi_scan_params { + /** If 0x1, RPU force passive scan on all channels */ + unsigned short passive_scan; + /** Number of ssid's in scan_ssids parameter */ + unsigned char num_scan_ssids; + /** Specific SSID's to scan for */ + struct nrf_wifi_ssid scan_ssids[NRF_WIFI_SCAN_MAX_NUM_SSIDS]; + /** used to send probe requests at non CCK rate in 2GHz band */ + unsigned char no_cck; + /** Bitmap of bands to be scanned. Value Zero will scan both 2.4 and 5 GHZ */ + unsigned char bands; + /** Information element(s) data @ref nrf_wifi_ie*/ + struct nrf_wifi_ie ie; + /** MAC address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Max scan duration in active scan. If zero rpu programs 50msec */ + unsigned short dwell_time_active; + /** Max scan duration in passive scan. If zero rpu programs 150msec */ + unsigned short dwell_time_passive; + /** Number of channels to be scanned */ + unsigned short num_scan_channels; + /** specific channels to be scanned */ + unsigned int center_frequency[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_HT_CAPABILITY_VALID (1 << 0) +#define NRF_WIFI_HT_CAPABILITY_MASK_VALID (1 << 1) +#define NRF_WIFI_VHT_CAPABILITY_VALID (1 << 2) +#define NRF_WIFI_VHT_CAPABILITY_MASK_VALID (1 << 3) + +#define NRF_WIFI_CMD_HT_VHT_CAPABILITY_DISABLE_HT (1 << 0) +#define NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE 256 + +/** + * @brief This structure contains specific information about the VHT (Very High Throughput) + * and HT ((High Throughput)) capabilities. + * + */ + +struct nrf_wifi_ht_vht_capabilities { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Indicate which capabilities have been specified */ + unsigned short nrf_wifi_flags; + /** HT Capability information element (from association request when + * used with NRF_WIFI_UMAC_CMD_NEW_STATION). + */ + unsigned char ht_capability[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** Specify which bits of the ht_capability are masked */ + unsigned char ht_capability_mask[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** VHT Capability information element */ + unsigned char vht_capability[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** Specify which bits in vht_capability to which attention should be paid */ + unsigned char vht_capability_mask[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_SIGNAL_TYPE_NONE 1 +#define NRF_WIFI_SIGNAL_TYPE_MBM 2 +#define NRF_WIFI_SIGNAL_TYPE_UNSPEC 3 + +/** + * @brief This structure represents information related to the signal strength. + * + */ + +struct nrf_wifi_signal { + /** MBM or unspecified */ + unsigned int signal_type; + + /** signal */ + union { + /** If MBM signal strength of probe response/beacon + * in mBm (100 * dBm) (s32) + */ + unsigned int mbm_signal; + /** If unspecified signal strength of the probe response/beacon + * in unspecified units, scaled to 0..100 (u8). + */ + unsigned char unspec_signal; + } __NRF_WIFI_PKD signal; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_WPA_VERSION_1 (1 << 0) +#define NRF_WIFI_WPA_VERSION_2 (1 << 1) + +#define NRF_WIFI_CONNECT_COMMON_INFO_MAC_ADDR_VALID (1 << 0) +#define NRF_WIFI_CONNECT_COMMON_INFO_MAC_ADDR_HINT_VALID (1 << 1) +#define NRF_WIFI_CONNECT_COMMON_INFO_FREQ_VALID (1 << 2) +#define NRF_WIFI_CONNECT_COMMON_INFO_FREQ_HINT_VALID (1 << 3) +#define NRF_WIFI_CONNECT_COMMON_INFO_BG_SCAN_PERIOD_VALID (1 << 4) +#define NRF_WIFI_CONNECT_COMMON_INFO_SSID_VALID (1 << 5) +#define NRF_WIFI_CONNECT_COMMON_INFO_WPA_IE_VALID (1 << 6) +#define NRF_WIFI_CONNECT_COMMON_INFO_WPA_VERSIONS_VALID (1 << 7) +#define NRF_WIFI_CONNECT_COMMON_INFO_CIPHER_SUITES_PAIRWISE_VALID (1 << 8) +#define NRF_WIFI_CONNECT_COMMON_INFO_CIPHER_SUITE_GROUP_VALID (1 << 9) +#define NRF_WIFI_CONNECT_COMMON_INFO_AKM_SUITES_VALID (1 << 10) +#define NRF_WIFI_CONNECT_COMMON_INFO_USE_MFP_VALID (1 << 11) +#define NRF_WIFI_CONNECT_COMMON_INFO_CONTROL_PORT_ETHER_TYPE (1 << 12) +#define NRF_WIFI_CONNECT_COMMON_INFO_CONTROL_PORT_NO_ENCRYPT (1 << 13) + +#define NRF_WIFI_MAX_NR_AKM_SUITES 2 + +#define NRF_WIFI_CMD_CONNECT_COMMON_INFO_USE_RRM (1 << 14) +#define NRF_WIFI_CONNECT_COMMON_INFO_PREV_BSSID (1 << 15) + +/** + * @brief This structure contains parameters related to the connection. + * + */ + +struct nrf_wifi_connect_common_info { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Frequency of the selected channel in MHz */ + unsigned int frequency; + /** Frequency of the recommended initial BSS */ + unsigned int freq_hint; + /** Indicates which WPA version(s) */ + unsigned int wpa_versions; + /** Number of pairwise cipher suites */ + signed int num_cipher_suites_pairwise; + /** For crypto settings, indicates which pairwise cipher suites are used */ + unsigned int cipher_suites_pairwise[7]; + /** For crypto settings, indicates which group cipher suite is used */ + unsigned int cipher_suite_group; + /** Number of groupwise cipher suites */ + unsigned int num_akm_suites; + /** Indicate which key management algorithm(s) to use */ + unsigned int akm_suites[NRF_WIFI_MAX_NR_AKM_SUITES]; + /** Whether management frame protection (IEEE 802.11w) is used for the association */ + signed int use_mfp; + /** Flag for indicating whether the current connection + * shall support Radio Resource Measurements (11k) + */ + unsigned int nrf_wifi_flags; + /** Background scan period in seconds or 0 to disable background scan */ + unsigned short bg_scan_period; + /** MAC address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** MAC address recommendation as initial BSS */ + unsigned char mac_addr_hint[NRF_WIFI_ETH_ADDR_LEN]; + /** SSID (binary attribute, 0..32 octets) */ + struct nrf_wifi_ssid ssid; + /** IE's @ref nrf_wifi_ie */ + struct nrf_wifi_ie wpa_ie; + /** VHT Capability information element @ref nrf_wifi_ht_vht_capabilities */ + struct nrf_wifi_ht_vht_capabilities ht_vht_capabilities; + /** A 16-bit value indicating the ethertype that will be used for key negotiation. + * If it is not specified, the value defaults to 0x888E. + */ + unsigned short control_port_ether_type; + /** When included along with control_port_ether_type, indicates that the custom + * ethertype frames used for key negotiation must not be encrypted. + */ + unsigned char control_port_no_encrypt; + /** Indicating whether user space controls IEEE 802.1X port, If set, the RPU will + * assume that the port is unauthorized until authorized by user space. + * Otherwise, port is marked authorized by default in station mode. + */ + signed char control_port; + /** previous BSSID, used to specify a request to reassociate + * within an ESS that is, to use Reassociate Request frame (with the value of + * this attribute in the Current AP address field) instead of Association + * Request frame which is used for the initial association to an ESS. + */ + unsigned char prev_bssid[NRF_WIFI_ETH_ADDR_LEN]; + /** Bss max idle timeout value in sec which will be encapsulated into + * BSS MAX IDLE IE in assoc request frame. + */ + unsigned short maxidle_insec; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_BEACON_DATA_MAX_HEAD_LEN 256 +#define NRF_WIFI_BEACON_DATA_MAX_TAIL_LEN 512 +#define NRF_WIFI_BEACON_DATA_MAX_PROBE_RESP_LEN 400 + +/** + * @brief This structure provides information about beacon and probe data. + * + */ + +struct nrf_wifi_beacon_data { + /** length of head */ + unsigned int head_len; + /** length of tail */ + unsigned int tail_len; + /** length of probe response template (probe_resp) */ + unsigned int probe_resp_len; + /** head portion of beacon (before TIM IE) or %NULL if not changed */ + unsigned char head[NRF_WIFI_BEACON_DATA_MAX_HEAD_LEN]; + /** tail portion of beacon (after TIM IE) or %NULL if not changed */ + unsigned char tail[NRF_WIFI_BEACON_DATA_MAX_TAIL_LEN]; + /** probe response template */ + unsigned char probe_resp[NRF_WIFI_BEACON_DATA_MAX_PROBE_RESP_LEN]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_STA_FLAG_INVALID (1 << 0) +#define NRF_WIFI_STA_FLAG_AUTHORIZED (1 << 1) +#define NRF_WIFI_STA_FLAG_SHORT_PREAMBLE (1 << 2) +#define NRF_WIFI_STA_FLAG_WME (1 << 3) +#define NRF_WIFI_STA_FLAG_MFP (1 << 4) +#define NRF_WIFI_STA_FLAG_AUTHENTICATED (1 << 5) +#define NRF_WIFI_STA_FLAG_TDLS_PEER (1 << 6) +#define NRF_WIFI_STA_FLAG_ASSOCIATED (1 << 7) + +/** + * @brief This structure provides information regarding station flags. + * + */ + +struct nrf_wifi_sta_flag_update { + /** Mask of station flags to set */ + unsigned int nrf_wifi_mask; + /** Values to set them to. NRF_WIFI_STA_FLAG_AUTHORIZED */ + unsigned int nrf_wifi_set; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_RATE_INFO_BITRATE_VALID (1 << 0) +#define NRF_WIFI_RATE_INFO_BITRATE_COMPAT_VALID (1 << 1) +#define NRF_WIFI_RATE_INFO_BITRATE_MCS_VALID (1 << 2) +#define NRF_WIFI_RATE_INFO_BITRATE_VHT_MCS_VALID (1 << 3) +#define NRF_WIFI_RATE_INFO_BITRATE_VHT_NSS_VALID (1 << 4) + +#define NRF_WIFI_RATE_INFO_0_MHZ_WIDTH (1 << 0) +#define NRF_WIFI_RATE_INFO_5_MHZ_WIDTH (1 << 1) +#define NRF_WIFI_RATE_INFO_10_MHZ_WIDTH (1 << 2) +#define NRF_WIFI_RATE_INFO_40_MHZ_WIDTH (1 << 3) +#define NRF_WIFI_RATE_INFO_80_MHZ_WIDTH (1 << 4) +#define NRF_WIFI_RATE_INFO_160_MHZ_WIDTH (1 << 5) +#define NRF_WIFI_RATE_INFO_SHORT_GI (1 << 6) +#define NRF_WIFI_RATE_INFO_80P80_MHZ_WIDTH (1 << 7) + +/** + * @brief This structure contains information about rate parameters. + * + */ + +struct nrf_wifi_rate_info { + /** Valid fields with in this structure */ + unsigned int valid_fields; + /** bitrate */ + unsigned int bitrate; + /** Bitrate compatible */ + unsigned short bitrate_compat; + /** Modulation and Coding Scheme(MCS) */ + unsigned char nrf_wifi_mcs; + /** MCS related to VHT */ + unsigned char vht_mcs; + /** NSS related to VHT */ + unsigned char vht_nss; + /** Rate flags NRF_WIFI_RATE_INFO_0_MHZ_WIDTH */ + unsigned int nrf_wifi_flags; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_BSS_PARAM_FLAGS_CTS_PROT (1<<0) +#define NRF_WIFI_BSS_PARAM_FLAGS_SHORT_PREAMBLE (1<<1) +#define NRF_WIFI_BSS_PARAM_FLAGS_SHORT_SLOT_TIME (1<<2) + +/** + * @brief This structure provides information about the Basic Service Set (BSS) + * parameters for the attached station. + * + */ +struct nrf_wifi_sta_bss_parameters { + /** bitfields of flags NRF_WIFI_BSS_PARAM_FLAGS_CTS_PROT */ + unsigned char nrf_wifi_flags; + /** DTIM period for the BSS */ + unsigned char dtim_period; + /** beacon interval */ + unsigned short beacon_interval; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_STA_INFO_CONNECTED_TIME_VALID (1 << 0) +#define NRF_WIFI_STA_INFO_INACTIVE_TIME_VALID (1 << 1) +#define NRF_WIFI_STA_INFO_RX_BYTES_VALID (1 << 2) +#define NRF_WIFI_STA_INFO_TX_BYTES_VALID (1 << 3) +#define NRF_WIFI_STA_INFO_CHAIN_SIGNAL_VALID (1 << 4) +#define NRF_WIFI_STA_INFO_CHAIN_SIGNAL_AVG_VALID (1 << 5) +#define NRF_WIFI_STA_INFO_TX_BITRATE_VALID (1 << 6) +#define NRF_WIFI_STA_INFO_RX_BITRATE_VALID (1 << 7) +#define NRF_WIFI_STA_INFO_STA_FLAGS_VALID (1 << 8) + +#define NRF_WIFI_STA_INFO_LLID_VALID (1 << 9) +#define NRF_WIFI_STA_INFO_PLID_VALID (1 << 10) +#define NRF_WIFI_STA_INFO_PLINK_STATE_VALID (1 << 11) +#define NRF_WIFI_STA_INFO_SIGNAL_VALID (1 << 12) +#define NRF_WIFI_STA_INFO_SIGNAL_AVG_VALID (1 << 13) +#define NRF_WIFI_STA_INFO_RX_PACKETS_VALID (1 << 14) +#define NRF_WIFI_STA_INFO_TX_PACKETS_VALID (1 << 15) +#define NRF_WIFI_STA_INFO_TX_RETRIES_VALID (1 << 16) +#define NRF_WIFI_STA_INFO_TX_FAILED_VALID (1 << 17) +#define NRF_WIFI_STA_INFO_EXPECTED_THROUGHPUT_VALID (1 << 18) +#define NRF_WIFI_STA_INFO_BEACON_LOSS_COUNT_VALID (1 << 19) +#define NRF_WIFI_STA_INFO_LOCAL_PM_VALID (1 << 20) +#define NRF_WIFI_STA_INFO_PEER_PM_VALID (1 << 21) +#define NRF_WIFI_STA_INFO_NONPEER_PM_VALID (1 << 22) +#define NRF_WIFI_STA_INFO_T_OFFSET_VALID (1 << 23) +#define NRF_WIFI_STA_INFO_RX_DROPPED_MISC_VALID (1 << 24) +#define NRF_WIFI_STA_INFO_RX_BEACON_VALID (1 << 25) +#define NRF_WIFI_STA_INFO_RX_BEACON_SIGNAL_AVG_VALID (1 << 26) +#define NRF_WIFI_STA_INFO_STA_BSS_PARAMS_VALID (1 << 27) +#define NRF_WIFI_IEEE80211_MAX_CHAINS 4 + +/** + * @brief This structure contains information about a Station (STA). + * + */ + +struct nrf_wifi_sta_info { + /** Valid fields with in this structure */ + unsigned int valid_fields; + /** time since the station is last connected */ + unsigned int connected_time; + /** time since last activity, in msec */ + unsigned int inactive_time; + /** total received bytes from this station */ + unsigned int rx_bytes; + /** total transmitted bytes to this station */ + unsigned int tx_bytes; + /** per-chain signal mask value */ + unsigned int chain_signal_mask; + /** per-chain signal strength of last PPDU */ + unsigned char chain_signal[NRF_WIFI_IEEE80211_MAX_CHAINS]; + /** per-chain signal strength average mask value */ + unsigned int chain_signal_avg_mask; + /** per-chain signal strength average */ + unsigned char chain_signal_avg[NRF_WIFI_IEEE80211_MAX_CHAINS]; + /**@ref nrf_wifi_rate_info */ + struct nrf_wifi_rate_info tx_bitrate; + /**@ref nrf_wifi_rate_info */ + struct nrf_wifi_rate_info rx_bitrate; + /** Not used */ + unsigned short llid; + /** Not used */ + unsigned short plid; + /** Not used */ + unsigned char plink_state; + /** signal strength of last received PPDU, in dbm */ + signed int signal; + /** signal strength average, in dbm */ + signed int signal_avg; + /** total received packet from this station */ + unsigned int rx_packets; + /** total transmitted packets to this station */ + unsigned int tx_packets; + /** total retries to this station */ + unsigned int tx_retries; + /** total failed packets to this station */ + unsigned int tx_failed; + /** expected throughput in kbps */ + unsigned int expected_throughput; + /** count of times beacon loss was detected */ + unsigned int beacon_loss_count; + /** Not used */ + unsigned int local_pm; + /** Not used */ + unsigned int peer_pm; + /** Not used */ + unsigned int nonpeer_pm; + /** station flags @ref nrf_wifi_sta_flag_update */ + struct nrf_wifi_sta_flag_update sta_flags; + /** timing offset with respect to this STA */ + unsigned long long t_offset; + /** count of times other(non beacon) loss was detected */ + unsigned long long rx_dropped_misc; + /** count of times beacon */ + unsigned long long rx_beacon; + /** average of beacon signal */ + long long rx_beacon_signal_avg; + /** Station connected BSS params. @ref nrf_wifi_sta_bss_parameters */ + struct nrf_wifi_sta_bss_parameters bss_param; +} __NRF_WIFI_PKD; + +/** + * @brief The command header expected by UMAC to handle requests from the control interface. + * + */ + +struct nrf_wifi_umac_hdr { + /** unused */ + unsigned int portid; + /** unused */ + unsigned int seq; + /** UMAC command/event value see &enum nrf_wifi_umac_commands + * see &enum nrf_wifi_umac_events + */ + unsigned int cmd_evnt; + /** unused */ + signed int rpu_ret_val; + /** Interface information @ref nrf_wifi_index_ids */ + struct nrf_wifi_index_ids ids; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_KEY_VALID (1 << 0) +#define NRF_WIFI_KEY_TYPE_VALID (1 << 1) +#define NRF_WIFI_KEY_IDX_VALID (1 << 2) +#define NRF_WIFI_SEQ_VALID (1 << 3) +#define NRF_WIFI_CIPHER_SUITE_VALID (1 << 4) +#define NRF_WIFI_KEY_INFO_VALID (1 << 5) + +#define NRF_WIFI_KEY_DEFAULT (1 << 0) +#define NRF_WIFI_KEY_DEFAULT_TYPES (1 << 1) +#define NRF_WIFI_KEY_DEFAULT_MGMT (1 << 2) +#define NRF_WIFI_KEY_DEFAULT_TYPE_UNICAST (1 << 3) +#define NRF_WIFI_KEY_DEFAULT_TYPE_MULTICAST (1 << 4) + +/** + * @brief This structure contains information about a security key. + * + */ + +struct nrf_wifi_umac_key_info { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Key cipher suite (as defined by IEEE 802.11 section 7.3.2.25.1) */ + unsigned int cipher_suite; + /** Specify what a key should be set as default as example NRF_WIFI_KEY_DEFAULT_MGMT */ + unsigned short nrf_wifi_flags; + /** Key Type, see &enum nrf_wifi_key_type */ + signed int key_type; + /** Key data @ref nrf_wifi_key */ + struct nrf_wifi_key key; + /** Transmit key sequence number (IV/PN) for TKIP and CCMP keys, + * each six bytes in little endian @ref nrf_wifi_seq + */ + struct nrf_wifi_seq seq; + /** Key ID (0-3) */ + unsigned char key_idx; +} __NRF_WIFI_PKD; + + + +/** + * @brief This enum describes the different types of scan. + * + */ +enum scan_reason { + /** scan for display purpose in user space */ + SCAN_DISPLAY = 0, + /** scan for connection purpose */ + SCAN_CONNECT +}; + +/** + * @brief This structure contains details about scan request information. + * + */ +struct nrf_wifi_umac_scan_info { + /** scan type see &enum scan_reason */ + signed int scan_reason; + /** scan parameters @ref nrf_wifi_scan_params */ + struct nrf_wifi_scan_params scan_params; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command scan request. + * + */ + +struct nrf_wifi_umac_cmd_scan { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_scan_info */ + struct nrf_wifi_umac_scan_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command to abort a scan request. + * + */ + +struct nrf_wifi_umac_cmd_abort_scan { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief TThis structure defines a command to request scan results. + * This command should be executed only if we have received a + * NRF_WIFI_UMAC_EVENT_SCAN_DONE event for a previous scan. + * + */ + +struct nrf_wifi_umac_cmd_get_scan_results { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** scan type see &enum scan_reason */ + signed int scan_reason; +} __NRF_WIFI_PKD; + +/** + * @brief This structure provides details about the "Scan Done" event. + * + */ +struct nrf_wifi_umac_event_scan_done { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** status, 0=Scan successful & 1=Scan aborted */ + signed int status; + /** scan type see &enum scan_reason */ + unsigned int scan_type; +} __NRF_WIFI_PKD; + + +#define MCAST_ADDR_ADD 0 +#define MCAST_ADDR_DEL 1 + +/** + * @brief This structure represents the parameters used to configure the multicast address filter. + * + */ +struct nrf_wifi_umac_mcast_cfg { + /** Add (0) or Delete (1) */ + unsigned int type; + /** multicast address to be added/deleted */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command used to set multicast (mcast) addresses. + * + */ +struct nrf_wifi_umac_cmd_mcast_filter { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_mcast_cfg */ + struct nrf_wifi_umac_mcast_cfg info; +} __NRF_WIFI_PKD; + + +/** + * @brief This structure represents the parameters used to change the MAC address. + * + */ + +struct nrf_wifi_umac_change_macaddr_info { + /** MAC address to be set */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; +/** + * @brief This structure describes command to change MAC address. + * This has to be used only when the interface is down. + * + */ +struct nrf_wifi_umac_cmd_change_macaddr { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_change_macaddr_info */ + struct nrf_wifi_umac_change_macaddr_info macaddr_info; +} __NRF_WIFI_PKD; + + + +#define NRF_WIFI_CMD_AUTHENTICATE_KEY_INFO_VALID (1 << 0) +#define NRF_WIFI_CMD_AUTHENTICATE_BSSID_VALID (1 << 1) +#define NRF_WIFI_CMD_AUTHENTICATE_FREQ_VALID (1 << 2) +#define NRF_WIFI_CMD_AUTHENTICATE_SSID_VALID (1 << 3) +#define NRF_WIFI_CMD_AUTHENTICATE_IE_VALID (1 << 4) +#define NRF_WIFI_CMD_AUTHENTICATE_SAE_VALID (1 << 5) + +#define NRF_WIFI_CMD_AUTHENTICATE_LOCAL_STATE_CHANGE (1 << 0) + +/** + * @brief This structure specifies the parameters to be used when sending an authentication request. + * + */ + +struct nrf_wifi_umac_auth_info { + /** Frequency of the selected channel in MHz */ + unsigned int frequency; + /** Flag attribute to indicate that a command is requesting a local + * authentication/association state change without invoking actual management + * frame exchange. This can be used with NRF_WIFI_UMAC_CMD_AUTHENTICATE + * NRF_WIFI_UMAC_CMD_DEAUTHENTICATE. + */ + unsigned short nrf_wifi_flags; + /** Authentication type. see &enum nrf_wifi_auth_type */ + signed int auth_type; + /** Key information */ + struct nrf_wifi_umac_key_info key_info; + /** SSID (binary attribute, 0..32 octets) */ + struct nrf_wifi_ssid ssid; + /** Information element(s) data */ + struct nrf_wifi_ie ie; + /** SAE elements in Authentication frames. This starts + * with the Authentication transaction sequence number field. + */ + struct nrf_wifi_sae sae; + /** MAC address (various uses) */ + unsigned char nrf_wifi_bssid[NRF_WIFI_ETH_ADDR_LEN]; + /** The following parameters will be used to construct bss database in case of + * cfg80211 offload to host case. + */ + /** scanning width */ + signed int scan_width; + /** Signal strength */ + signed int nrf_wifi_signal; + /** Received elements from beacon or probe response */ + signed int from_beacon; + /** BSS information element data */ + struct nrf_wifi_ie bss_ie; + /** BSS capability */ + unsigned short capability; + /** Beacon interval(ms) */ + unsigned short beacon_interval; + /** Beacon tsf */ + unsigned long long tsf; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command used to send an authentication request. + * + */ + +struct nrf_wifi_umac_cmd_auth { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Information to be passed in the authentication command @ref nrf_wifi_umac_auth_info */ + struct nrf_wifi_umac_auth_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_ASSOCIATE_MAC_ADDR_VALID (1 << 0) + +/** + * @brief This structure specifies the parameters to be used when sending an association request. + * + */ + +struct nrf_wifi_umac_assoc_info { + /** Frequency of the selected channel in MHz */ + unsigned int center_frequency; + /** ssid @ref nrf_wifi_ssid */ + struct nrf_wifi_ssid ssid; + /** MAC address (various uses) */ + unsigned char nrf_wifi_bssid[NRF_WIFI_ETH_ADDR_LEN]; + /** WPA information element data. @ref nrf_wifi_ie */ + struct nrf_wifi_ie wpa_ie; + /** Whether management frame protection (IEEE 802.11w) is used for the association */ + unsigned char use_mfp; + /** Indicating whether user space controls IEEE 802.1X port. If set, the RPU will + * assume that the port is unauthorized until authorized by user space. + * Otherwise, port is marked authorized by default in station mode. + */ + signed char control_port; + /** Previous BSSID used in flag */ + unsigned int prev_bssid_flag; + /** Previous BSSID used in Re-assoc. */ + unsigned char prev_bssid[NRF_WIFI_ETH_ADDR_LEN]; + /** Bss max idle timeout value in sec wich will be encapsulated into + * BSS MAX IDLE IE in assoc request frame. + */ + unsigned short bss_max_idle_time; +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the parameters to be used when sending an association request. + * + */ + +struct nrf_wifi_umac_cmd_assoc { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** @ref nrf_wifi_connect_common_info */ + struct nrf_wifi_connect_common_info connect_common_info; + /** + * Previous BSSID, to be used by in ASSOCIATE commands to specify + * using a reassociate frame. + */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_MLME_MAC_ADDR_VALID (1 << 0) +#define NRF_WIFI_CMD_MLME_LOCAL_STATE_CHANGE (1 << 0) + +/** + * @brief This structure specifies the parameters to be passed while sending a + * deauthentication request (NRF_WIFI_UMAC_CMD_DEAUTHENTICATE). + * + */ + +struct nrf_wifi_umac_disconn_info { + /** Indicates that a command is requesting a local deauthentication/disassociation + * state change without invoking actual management frame exchange. + */ + unsigned short nrf_wifi_flags; + /** Reason code for disassociation or deauthentication */ + unsigned short reason_code; + /** MAC address (various uses) */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure specifies the parameters to be used when sending a disconnect request. + * + */ + +struct nrf_wifi_umac_cmd_disconn { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** @ref nrf_wifi_umac_disconn_info */ + struct nrf_wifi_umac_disconn_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_NEW_INTERFACE_USE_4ADDR_VALID (1 << 0) +#define NRF_WIFI_CMD_NEW_INTERFACE_MAC_ADDR_VALID (1 << 1) +#define NRF_WIFI_CMD_NEW_INTERFACE_IFTYPE_VALID (1 << 2) +#define NRF_WIFI_CMD_NEW_INTERFACE_IFNAME_VALID (1 << 3) + +/** + * @brief This structure contains the information to be passed to the RPU + * to create a new virtual interface using the NRF_WIFI_UMAC_CMD_NEW_INTERFACE command. + * + */ +struct nrf_wifi_umac_add_vif_info { + /** Interface type, see enum nrf_wifi_sys_iftype */ + signed int iftype; + /** Use 4-address frames on a virtual interface */ + signed int nrf_wifi_use_4addr; + /** Unused */ + unsigned int mon_flags; + /** MAC Address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Interface name */ + signed char ifacename[16]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command used to create a new virtual interface + * using the NRF_WIFI_UMAC_CMD_NEW_INTERFACE command. + * + */ + +struct nrf_wifi_umac_cmd_add_vif { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** VIF specific information to be passed to the RPU @ref nrf_wifi_umac_add_vif_info */ + struct nrf_wifi_umac_add_vif_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command used to delete a virtual interface. + * However, this command is not allowed on the default interface. + * + */ + +struct nrf_wifi_umac_cmd_del_vif { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_FRAME_MATCH_MAX_LEN 8 + +/** + * @brief This structure represents the data of management frame that must be matched for + * processing in userspace. + * + */ + +struct nrf_wifi_umac_frame_match { + /** Length of data */ + unsigned int frame_match_len; + /** Data to match */ + unsigned char frame_match[NRF_WIFI_FRAME_MATCH_MAX_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure contains information about the type of management frame + * that should be passed to the driver for processing in userspace. + * + */ + +struct nrf_wifi_umac_mgmt_frame_info { + /** Frame type/subtype */ + unsigned short frame_type; + /** Match information Refer &struct nrf_wifi_umac_frame_match */ + struct nrf_wifi_umac_frame_match frame_match; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command to inform the RPU to register a management frame, + * which must not be filtered by the RPU and should instead be passed to the host for + * userspace processing. + * + */ + +struct nrf_wifi_umac_cmd_mgmt_frame_reg { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** + * Management frame specific information to be passed to the RPU. + * @ref nrf_wifi_umac_mgmt_frame_info + */ + struct nrf_wifi_umac_mgmt_frame_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_KEY_MAC_ADDR_VALID (1 << 0) + +/** + * @brief This structure represents command to add a new key. + * + */ + +struct nrf_wifi_umac_cmd_key { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Key information. @ref nrf_wifi_umac_key_info */ + struct nrf_wifi_umac_key_info key_info; + /** MAC address associated with the key */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines a command that is used to add a new key. + * + */ + +struct nrf_wifi_umac_cmd_set_key { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Key information , @ref nrf_wifi_umac_key_info */ + struct nrf_wifi_umac_key_info key_info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_SET_BSS_CTS_VALID (1 << 0) +#define NRF_WIFI_CMD_SET_BSS_PREAMBLE_VALID (1 << 1) +#define NRF_WIFI_CMD_SET_BSS_SLOT_VALID (1 << 2) +#define NRF_WIFI_CMD_SET_BSS_HT_OPMODE_VALID (1 << 3) +#define NRF_WIFI_CMD_SET_BSS_AP_ISOLATE_VALID (1 << 4) +#define NRF_WIFI_CMD_SET_BSS_P2P_CTWINDOW_VALID (1 << 5) +#define NRF_WIFI_CMD_SET_BSS_P2P_OPPPS_VALID (1 << 6) + +#define NRF_WIFI_BASIC_MAX_SUPP_RATES 32 + +/** + * @brief This structure contains parameters that describe the BSS (Basic Service Set) information. + * + */ + +struct nrf_wifi_umac_bss_info { + /** P2P GO Client Traffic Window, used with + * the START_AP and SET_BSS commands. + */ + unsigned int p2p_go_ctwindow; + /** P2P GO opportunistic PS, used with the + * START_AP and SET_BSS commands. This can have the values 0 or 1; + * if not given in START_AP 0 is assumed, if not given in SET_BSS + * no change is made. + */ + unsigned int p2p_opp_ps; + /** Number of basic rate elements */ + unsigned int num_basic_rates; + /** HT operation mode */ + unsigned short ht_opmode; + /** Whether CTS protection is enabled (0 or 1) */ + unsigned char nrf_wifi_cts; + /** Whether short preamble is enabled (0 or 1) */ + unsigned char preamble; + /** Whether short slot time enabled (0 or 1) */ + unsigned char nrf_wifi_slot; + /** (AP mode) Do not forward traffic between stations connected to this BSS */ + unsigned char ap_isolate; + /** Basic rates, array of basic rates in format defined by IEEE 802.11 7.3.2.2 */ + unsigned char basic_rates[NRF_WIFI_BASIC_MAX_SUPP_RATES]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents a command used to set BSS (Basic Service Set) parameters. + * + */ + +struct nrf_wifi_umac_cmd_set_bss { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** BSS specific information to be passed to the RPU @ref nrf_wifi_umac_bss_info */ + struct nrf_wifi_umac_bss_info bss_info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID (1 << 0) +#define NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID (1 << 1) +#define NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID (1 << 2) +#define NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID (1 << 3) +#define NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID (1 << 4) + +/** + * @brief This structure contains information about frequency parameters. + * + */ + +struct freq_params { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Value in MHz */ + signed int frequency; + /** Width of the channel @see &enu nrf_wifi_chan_width */ + signed int channel_width; + /** Unused */ + signed int center_frequency1; + /** Unused */ + signed int center_frequency2; + /** Type of channel see &enum nrf_wifi_channel_type */ + signed int channel_type; +} __NRF_WIFI_PKD; + +/** + * @brief This structure contains information about transmit queue parameters. + * + */ + +struct nrf_wifi_txq_params { + /** Transmit oppurtunity */ + unsigned short txop; + /** Minimum contention window */ + unsigned short cwmin; + /** Maximum contention window */ + unsigned short cwmax; + /** Arbitration interframe spacing */ + unsigned char aifs; + /** Access category */ + unsigned char ac; + +} __NRF_WIFI_PKD; + +/** + * @brief Types of transmit power settings. + * + */ + +enum nrf_wifi_tx_power_type { + /** Automatically determine transmit power */ + NRF_WIFI_TX_POWER_AUTOMATIC, + /** Limit TX power by the mBm parameter */ + NRF_WIFI_TX_POWER_LIMITED, + /** Fix TX power to the mBm parameter */ + NRF_WIFI_TX_POWER_FIXED, +}; + +#define NRF_WIFI_TX_POWER_SETTING_TYPE_VALID (1 << 0) +#define NRF_WIFI_TX_POWER_SETTING_TX_POWER_LEVEL_VALID (1 << 1) + +/** + * @brief This structure contains the parameters related to the transmit power setting. + * + */ + +struct nrf_wifi_tx_power_setting { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Power value type, see nrf_wifi_tx_power_type */ + signed int type; + /** Transmit power level in signed mBm units */ + signed int tx_power_level; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_SET_WIPHY_FREQ_PARAMS_VALID (1 << 0) +#define NRF_WIFI_CMD_SET_WIPHY_TXQ_PARAMS_VALID (1 << 1) +#define NRF_WIFI_CMD_SET_WIPHY_RTS_THRESHOLD_VALID (1 << 2) +#define NRF_WIFI_CMD_SET_WIPHY_FRAG_THRESHOLD_VALID (1 << 3) +#define NRF_WIFI_CMD_SET_WIPHY_TX_POWER_SETTING_VALID (1 << 4) +#define NRF_WIFI_CMD_SET_WIPHY_ANTENNA_TX_VALID (1 << 5) +#define NRF_WIFI_CMD_SET_WIPHY_ANTENNA_RX_VALID (1 << 6) +#define NRF_WIFI_CMD_SET_WIPHY_RETRY_SHORT_VALID (1 << 7) +#define NRF_WIFI_CMD_SET_WIPHY_RETRY_LONG_VALID (1 << 8) +#define NRF_WIFI_CMD_SET_WIPHY_COVERAGE_CLASS_VALID (1 << 9) +#define NRF_WIFI_CMD_SET_WIPHY_WIPHY_NAME_VALID (1 << 10) + +/** + * @brief This structure contains information about the configuration parameters + * needed to set up and configure the wireless Physical Layer. + * + */ + +struct nrf_wifi_umac_set_wiphy_info { + /** RTS threshold, TX frames with length larger than or equal to this use RTS/CTS handshake + * allowed range: 0..65536, disable with -1. + */ + unsigned int rts_threshold; + /** Fragmentation threshold, maximum length in octets for frames. + * allowed range: 256..8000, disable fragmentation with (u32)-1. + */ + unsigned int frag_threshold; + /** Bitmap of allowed antennas for transmitting. This can be used to mask out + * antennas which are not attached or should not be used for transmitting. + * If an antenna is not selected in this bitmap the hardware is not allowed + * to transmit on this antenna. + */ + unsigned int antenna_tx; + /** Bitmap of allowed antennas for receiving. This can be used to mask out antennas + * which are not attached or should not be used for receiving. If an antenna is + * not selected in this bitmap the hardware should not be configured to receive + * on this antenna. + */ + unsigned int antenna_rx; + /** Frequency information of the a channel see &struct freq_params */ + struct freq_params freq_params; + /** TX queue parameters @ref nrf_wifi_txq_params */ + struct nrf_wifi_txq_params txq_params; + /** Tx power settings @ref nrf_wifi_tx_power_setting @ref nrf_wifi_tx_power_setting */ + struct nrf_wifi_tx_power_setting tx_power_setting; + /** TX retry limit for frames whose length is less than or equal to the RTS threshold + * allowed range: 1..255. + */ + unsigned char retry_short; + /** TX retry limit for frames whose length is greater than the RTS threshold + * allowed range: 1..255. + */ + unsigned char retry_long; + /** Unused */ + unsigned char coverage_class; + /** WIPHY name (used for renaming) */ + signed char wiphy_name[32]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command to set the wireless PHY configuration. + * + */ + +struct nrf_wifi_umac_cmd_set_wiphy { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicates which of the following parameters are valid */ + unsigned int valid_fields; + /** @ref nrf_wifi_umac_set_wiphy_info */ + struct nrf_wifi_umac_set_wiphy_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_DEL_STATION_MAC_ADDR_VALID (1 << 0) +#define NRF_WIFI_CMD_DEL_STATION_MGMT_SUBTYPE_VALID (1 << 1) +#define NRF_WIFI_CMD_DEL_STATION_REASON_CODE_VALID (1 << 2) + +/** + * @brief This structure contains the parameters to delete a station. + * + */ + +struct nrf_wifi_umac_del_sta_info { + /** MAC address of the station */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Management frame subtype */ + unsigned char mgmt_subtype; + /** Reason code for DEAUTHENTICATION and DISASSOCIATION */ + unsigned short reason_code; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command to delete a station. + * + */ + +struct nrf_wifi_umac_cmd_del_sta { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Information regarding the station to be deleted @ref nrf_wifi_umac_del_sta_info */ + struct nrf_wifi_umac_del_sta_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure contains the information required for obtaining station details. + * + */ + +struct nrf_wifi_umac_get_sta_info { + /** MAC address of the station */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command to get station information. + * + */ + +struct nrf_wifi_umac_cmd_get_sta { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Information regarding the station to get @ref nrf_wifi_umac_get_sta_info */ + struct nrf_wifi_umac_get_sta_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EXT_CAPABILITY_MAX_LEN 32 + +/** + * @brief Extended capability information. + */ + +struct nrf_wifi_ext_capability { + /** length */ + unsigned int ext_capability_len; + /** Extended capability info*/ + unsigned char ext_capability[NRF_WIFI_EXT_CAPABILITY_MAX_LEN]; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_SUPPORTED_CHANNELS_MAX_LEN 64 + +/** + * @brief Supported channels. + */ + +struct nrf_wifi_supported_channels { + /** number of channels */ + unsigned int supported_channels_len; + /** channels info */ + unsigned char supported_channels[NRF_WIFI_SUPPORTED_CHANNELS_MAX_LEN]; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_OPER_CLASSES_MAX_LEN 64 + +/** + * @brief Operating classes information. + */ +struct nrf_wifi_supported_oper_classes { + /** length */ + unsigned int supported_oper_classes_len; + /** oper_class info*/ + unsigned char supported_oper_classes[NRF_WIFI_OPER_CLASSES_MAX_LEN]; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_STA_FLAGS2_MAX_LEN 64 + +/** + * @brief Station flags. + */ + +struct nrf_wifi_sta_flags2 { + /** length */ + unsigned int sta_flags2_len; + /** flags */ + unsigned char sta_flags2[NRF_WIFI_STA_FLAGS2_MAX_LEN]; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_SET_STATION_SUPP_RATES_VALID (1 << 0) +#define NRF_WIFI_CMD_SET_STATION_AID_VALID (1 << 1) +#define NRF_WIFI_CMD_SET_STATION_PEER_AID_VALID (1 << 2) +#define NRF_WIFI_CMD_SET_STATION_STA_CAPABILITY_VALID (1 << 3) +#define NRF_WIFI_CMD_SET_STATION_EXT_CAPABILITY_VALID (1 << 4) +#define NRF_WIFI_CMD_SET_STATION_STA_VLAN_VALID (1 << 5) +#define NRF_WIFI_CMD_SET_STATION_HT_CAPABILITY_VALID (1 << 6) +#define NRF_WIFI_CMD_SET_STATION_VHT_CAPABILITY_VALID (1 << 7) +#define NRF_WIFI_CMD_SET_STATION_OPMODE_NOTIF_VALID (1 << 9) +#define NRF_WIFI_CMD_SET_STATION_SUPPORTED_CHANNELS_VALID (1 << 10) +#define NRF_WIFI_CMD_SET_STATION_SUPPORTED_OPER_CLASSES_VALID (1 << 11) +#define NRF_WIFI_CMD_SET_STATION_STA_FLAGS2_VALID (1 << 12) +#define NRF_WIFI_CMD_SET_STATION_STA_WME_UAPSD_QUEUES_VALID (1 << 13) +#define NRF_WIFI_CMD_SET_STATION_STA_WME_MAX_SP_VALID (1 << 14) +#define NRF_WIFI_CMD_SET_STATION_LISTEN_INTERVAL_VALID (1 << 15) + +/** + * @brief This structure represents the information needed to update a station entry + * in the RPU. + * + */ + +struct nrf_wifi_umac_chg_sta_info { + /** Listen interval as defined by IEEE 802.11 7.3.1.6 */ + signed int nrf_wifi_listen_interval; + /** Unused */ + unsigned int sta_vlan; + /** AID or zero for no change */ + unsigned short aid; + /** Unused */ + unsigned short nrf_wifi_peer_aid; + /** Station capability */ + unsigned short sta_capability; + /** Unused */ + unsigned short spare; + /** Supported rates in IEEE 802.11 format @ref nrf_wifi_supp_rates */ + struct nrf_wifi_supp_rates supp_rates; + /** Extended capabilities of the station @ref nrf_wifi_ext_capability */ + struct nrf_wifi_ext_capability ext_capability; + /** Supported channels in IEEE 802.11 format @ref nrf_wifi_supported_channels */ + struct nrf_wifi_supported_channels supported_channels; + /** Supported oper classes in IEEE 802.11 format @ref nrf_wifi_supported_oper_classes */ + struct nrf_wifi_supported_oper_classes supported_oper_classes; + /** station flags mask/set @ref nrf_wifi_sta_flag_update @ref nrf_wifi_sta_flag_update */ + struct nrf_wifi_sta_flag_update sta_flags2; + /** HT capabilities of station */ + unsigned char ht_capability[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** VHT capabilities of station */ + unsigned char vht_capability[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** Station mac address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Information if operating mode field is used */ + unsigned char opmode_notif; + /** Bitmap of queues configured for uapsd. Same format + * as the AC bitmap in the QoS info field. + */ + unsigned char wme_uapsd_queues; + /** Max Service Period. same format as the MAX_SP in the + * QoS info field (but already shifted down). + */ + unsigned char wme_max_sp; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command for updating the parameters of a station entry. + * + */ + +struct nrf_wifi_umac_cmd_chg_sta { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** @ref nrf_wifi_umac_chg_sta_info */ + struct nrf_wifi_umac_chg_sta_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_NEW_STATION_SUPP_RATES_VALID (1 << 0) +#define NRF_WIFI_CMD_NEW_STATION_AID_VALID (1 << 1) +#define NRF_WIFI_CMD_NEW_STATION_PEER_AID_VALID (1 << 2) +#define NRF_WIFI_CMD_NEW_STATION_STA_CAPABILITY_VALID (1 << 3) +#define NRF_WIFI_CMD_NEW_STATION_EXT_CAPABILITY_VALID (1 << 4) +#define NRF_WIFI_CMD_NEW_STATION_STA_VLAN_VALID (1 << 5) +#define NRF_WIFI_CMD_NEW_STATION_HT_CAPABILITY_VALID (1 << 6) +#define NRF_WIFI_CMD_NEW_STATION_VHT_CAPABILITY_VALID (1 << 7) +#define NRF_WIFI_CMD_NEW_STATION_OPMODE_NOTIF_VALID (1 << 9) +#define NRF_WIFI_CMD_NEW_STATION_SUPPORTED_CHANNELS_VALID (1 << 10) +#define NRF_WIFI_CMD_NEW_STATION_SUPPORTED_OPER_CLASSES_VALID (1 << 11) +#define NRF_WIFI_CMD_NEW_STATION_STA_FLAGS2_VALID (1 << 12) +#define NRF_WIFI_CMD_NEW_STATION_STA_WME_UAPSD_QUEUES_VALID (1 << 13) +#define NRF_WIFI_CMD_NEW_STATION_STA_WME_MAX_SP_VALID (1 << 14) +#define NRF_WIFI_CMD_NEW_STATION_LISTEN_INTERVAL_VALID (1 << 15) + +/** + * @brief This structure describes the parameters for adding a new station entry to the RPU. + * + */ + +struct nrf_wifi_umac_add_sta_info { + /** Listen interval as defined by IEEE 802.11 7.3.1.6 */ + signed int nrf_wifi_listen_interval; + /** Unused */ + unsigned int sta_vlan; + /** AID or zero for no change */ + unsigned short aid; + /** Unused */ + unsigned short nrf_wifi_peer_aid; + /** Station capability */ + unsigned short sta_capability; + /** Unused */ + unsigned short spare; + /** Supported rates in IEEE 802.11 format @ref nrf_wifi_supp_rates */ + struct nrf_wifi_supp_rates supp_rates; + /** Extended capabilities of the station @ref nrf_wifi_ext_capability */ + struct nrf_wifi_ext_capability ext_capability; + /** Supported channels in IEEE 802.11 format @ref nrf_wifi_supported_channels */ + struct nrf_wifi_supported_channels supported_channels; + /** Supported oper classes in IEEE 802.11 format @ref nrf_wifi_supported_oper_classes */ + struct nrf_wifi_supported_oper_classes supported_oper_classes; + /** station flags mask/set @ref nrf_wifi_sta_flag_update */ + struct nrf_wifi_sta_flag_update sta_flags2; + /** HT capabilities of station */ + unsigned char ht_capability[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** VHT capabilities of station */ + unsigned char vht_capability[NRF_WIFI_HT_VHT_CAPABILITY_MAX_SIZE]; + /** Station mac address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Information if operating mode field is used */ + unsigned char opmode_notif; + /** Bitmap of queues configured for uapsd. same format + * as the AC bitmap in the QoS info field. + */ + unsigned char wme_uapsd_queues; + /** Max Service Period. same format as the MAX_SP in the + * QoS info field (but already shifted down). + */ + unsigned char wme_max_sp; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command for adding a new station entry. + * + */ + +struct nrf_wifi_umac_cmd_add_sta { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** @ref nrf_wifi_umac_add_sta_info */ + struct nrf_wifi_umac_add_sta_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_BEACON_INFO_BEACON_INTERVAL_VALID (1 << 0) +#define NRF_WIFI_CMD_BEACON_INFO_AUTH_TYPE_VALID (1 << 1) +#define NRF_WIFI_CMD_BEACON_INFO_VERSIONS_VALID (1 << 2) +#define NRF_WIFI_CMD_BEACON_INFO_CIPHER_SUITE_GROUP_VALID (1 << 3) +#define NRF_WIFI_CMD_BEACON_INFO_INACTIVITY_TIMEOUT_VALID (1 << 4) +#define NRF_WIFI_CMD_BEACON_INFO_FREQ_PARAMS_VALID (1 << 5) + +#define NRF_WIFI_CMD_BEACON_INFO_PRIVACY (1 << 0) +#define NRF_WIFI_CMD_BEACON_INFO_CONTROL_PORT_NO_ENCRYPT (1 << 1) +#define NRF_WIFI_CMD_BEACON_INFO_P2P_CTWINDOW_VALID (1 << 6) +#define NRF_WIFI_CMD_BEACON_INFO_P2P_OPPPS_VALID (1 << 7) + +/** + * @brief This structure describes the parameters required to be passed to the RPU when + * initiating a SoftAP (Soft Access Point). + * + */ + +struct nrf_wifi_umac_start_ap_info { + /** Beacon frame interval */ + unsigned short beacon_interval; + /** DTIM count */ + unsigned char dtim_period; + /** Send beacons with wildcard sssid */ + signed int hidden_ssid; + /** Authentication type, see &enum nrf_wifi_auth_type */ + signed int auth_type; + /** Unused */ + signed int smps_mode; + /** Beacon info flags */ + unsigned int nrf_wifi_flags; + /** Beacon frame, @ref nrf_wifi_beacon_data */ + struct nrf_wifi_beacon_data beacon_data; + /** SSID string, @ref nrf_wifi_ssid */ + struct nrf_wifi_ssid ssid; + /** Connect params, @ref nrf_wifi_connect_common_info */ + struct nrf_wifi_connect_common_info connect_common_info; + /** Channel info, see &struct freq_params */ + struct freq_params freq_params; + /** Time to stop ap after inactivity period */ + unsigned short inactivity_timeout; + /** P2P GO Client Traffic Window */ + unsigned char p2p_go_ctwindow; + /** Opportunistic power save allows P2P Group Owner to save power + * when all its associated clients are sleeping. + */ + unsigned char p2p_opp_ps; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command for starting the SoftAP using + * NRF_WIFI_UMAC_CMD_NEW_BEACON and NRF_WIFI_UMAC_CMD_START_AP. + * + */ + +struct nrf_wifi_umac_cmd_start_ap { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Parameters that need to be passed to the RPU when starting a SoftAP. + * @ref nrf_wifi_umac_start_ap_info + */ + struct nrf_wifi_umac_start_ap_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to stop Soft AP operation. + * + */ + +struct nrf_wifi_umac_cmd_stop_ap { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the parameters that must be passed to the RPU when + * configuring Beacon and Probe response data. + * + */ + +struct nrf_wifi_umac_set_beacon_info { + /** Beacon frame, @ref nrf_wifi_beacon_data */ + struct nrf_wifi_beacon_data beacon_data; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command for setting the beacon data using + * NRF_WIFI_UMAC_CMD_SET_BEACON. + * + */ + +struct nrf_wifi_umac_cmd_set_beacon { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_set_beacon_info */ + struct nrf_wifi_umac_set_beacon_info info; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_SET_INTERFACE_IFTYPE_VALID (1 << 0) +#define NRF_WIFI_SET_INTERFACE_USE_4ADDR_VALID (1 << 1) + +/** + * @brief This structure contains the information that needs to be provided to the RPU + * when modifying the attributes of a virtual interface. + * + */ + +struct nrf_wifi_umac_chg_vif_attr_info { + /** Interface type, see &enum nrf_wifi_iftype */ + signed int iftype; + /** Unused */ + signed int nrf_wifi_use_4addr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to change the interface. + * + */ + +struct nrf_wifi_umac_cmd_chg_vif_attr { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Interface attributes to be changed @ref nrf_wifi_umac_chg_vif_attr_info */ + struct nrf_wifi_umac_chg_vif_attr_info info; +} __NRF_WIFI_PKD; + +#define IFACENAMSIZ 16 + +/** + * @brief This structure contains the information that needs to be passed to the RPU + * when changing the interface state, specifically when bringing it up or down + * + */ + +struct nrf_wifi_umac_chg_vif_state_info { + /** Interface state (1 = UP / 0 = DOWN) */ + signed int state; + /** Interface name */ + signed char ifacename[IFACENAMSIZ]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to change the interface state. + * + */ + +struct nrf_wifi_umac_cmd_chg_vif_state { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_chg_vif_state_info */ + struct nrf_wifi_umac_chg_vif_state_info info; +} __NRF_WIFI_PKD; +/** + * @brief This structure defines an event-to-command mapping for NRF_WIFI_UMAC_CMD_SET_IFFLAGS. + * + */ + +struct nrf_wifi_umac_event_vif_state { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Status to command NRF_WIFI_UMAC_CMD_SET_IFFLAGS */ + signed int status; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to start P2P (Peer-to-Peer) mode on an interface. + */ + +struct nrf_wifi_cmd_start_p2p { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command for stopping P2P mode on an interface. + * + */ + +struct nrf_wifi_umac_cmd_stop_p2p_dev { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_FRAME_FREQ_VALID (1 << 0) +#define NRF_WIFI_CMD_FRAME_DURATION_VALID (1 << 1) +#define NRF_WIFI_CMD_SET_FRAME_FREQ_PARAMS_VALID (1 << 2) + +#define NRF_WIFI_CMD_FRAME_OFFCHANNEL_TX_OK (1 << 0) +#define NRF_WIFI_CMD_FRAME_TX_NO_CCK_RATE (1 << 1) +#define NRF_WIFI_CMD_FRAME_DONT_WAIT_FOR_ACK (1 << 2) + +/** + * @brief This structure describes the parameters required to transmit a + * management frame from the host. + * + */ + +struct nrf_wifi_umac_mgmt_tx_info { + /** OFFCHANNEL_TX_OK, NO_CCK_RATE, DONT_WAIT_FOR_ACK */ + unsigned int nrf_wifi_flags; + /** Channel frequency */ + unsigned int frequency; + /** Duration field value */ + unsigned int dur; + /** Management frame to transmit, @ref nrf_wifi_frame */ + struct nrf_wifi_frame frame; + /** Frequency configuration, see &struct freq_params */ + struct freq_params freq_params; + /** Identifier to be used for processing event, + * NRF_WIFI_UMAC_EVENT_FRAME_TX_STATUS. + */ + unsigned long long host_cookie; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to transmit a management frame. + * + */ + +struct nrf_wifi_umac_cmd_mgmt_tx { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Information about the management frame to be transmitted. + * @ref nrf_wifi_umac_mgmt_tx_info + */ + struct nrf_wifi_umac_mgmt_tx_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the information regarding the power save state. + * + */ + +struct nrf_wifi_umac_set_power_save_info { + /** power save is disabled or enabled, see enum nrf_wifi_ps_state */ + signed int ps_state; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command used to enable or disable the power save + * functionality. + * + */ + +struct nrf_wifi_umac_cmd_set_power_save { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Power save setting parameters. + * @ref nrf_wifi_umac_set_power_save_info + */ + struct nrf_wifi_umac_set_power_save_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command to configure power save timeout value. + * + */ + +struct nrf_wifi_umac_cmd_set_power_save_timeout { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Timeout value in milli seconds + * if timeout < 0 RPU will set timeout to 100ms + */ + signed int timeout; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the information of qos_map. + * + */ + +struct nrf_wifi_umac_qos_map_info { + /** length of qos_map info field */ + unsigned int qos_map_info_len; + /** contains qos_map info as received from stack */ + unsigned char qos_map_info[256]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the information related to the Quality of Service (QoS) map. + * + */ + +struct nrf_wifi_umac_cmd_set_qos_map { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** qos map info. @ref nrf_wifi_umac_qos_map_info */ + struct nrf_wifi_umac_qos_map_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to retrieve the transmit power information. + * + */ + +struct nrf_wifi_umac_cmd_get_tx_power { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to obtain the regulatory domain information. + * + */ + +struct nrf_wifi_umac_cmd_get_reg { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to retrieve channel information. + * + */ + +struct nrf_wifi_umac_cmd_get_channel { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_TWT_NEGOTIATION_TYPE_INDIVIDUAL 0 +#define NRF_WIFI_TWT_NEGOTIATION_TYPE_BROADCAST 2 + +/** + * @brief TWT setup commands and events. + * + */ + +enum nrf_wifi_twt_setup_cmd_type { + /** STA requests to join a TWT without specifying a target wake time */ + NRF_WIFI_REQUEST_TWT, + /** STA requests to join a TWT with specifying a target wake time and + * other params, these values can change during negotiation. + */ + NRF_WIFI_SUGGEST_TWT, + /** requests to join a TWT with demanded a target wake time + * and other params. STA rejects if AP not scheduling those params. + */ + NRF_WIFI_DEMAND_TWT, + /** Response to the STA request(suggest/demand), these may be different params */ + NRF_WIFI_GROUPING_TWT, + /** AP accept the STA requested params */ + NRF_WIFI_ACCEPT_TWT, + /** AP may suggest the params, these may be different from STA requested */ + NRF_WIFI_ALTERNATE_TWT, + /** AP may suggest the params, these may be different from STA requested */ + NRF_WIFI_DICTATE_TWT, + /** AP may reject the STA requested params */ + NRF_WIFI_REJECT_TWT, +}; + +#define NRF_WIFI_TWT_FLOW_TYPE_ANNOUNCED 0 +#define NRF_WIFI_TWT_FLOW_TYPE_UNANNOUNCED 1 + +#define NRF_WIFI_TWT_RESP_RECEIVED 0 +#define NRF_WIFI_TWT_RESP_NOT_RECEIVED 1 +#define NRF_WIFI_INVALID_TWT_WAKE_INTERVAL 3 + +/** + * @brief This structure describes the TWT information. + * + */ + +struct nrf_wifi_umac_config_twt_info { + /** TWT flow Id */ + unsigned char twt_flow_id; + /** Negotiation type + * NRF_WIFI_TWT_NEGOTIATION_TYPE_INDIVIDUAL or + * NRF_WIFI_TWT_NEGOTIATION_TYPE_BROADAST + */ + unsigned char neg_type; + /** see &enum nrf_wifi_twt_setup_cmd_type */ + signed int setup_cmd; + /** indicating AP to initiate a trigger frame (ps_poll/Null) before data transfer */ + unsigned char ap_trigger_frame; + /** 1->implicit(same negotiated values to be used), + * 0->AP sends new calculated TWT values for every service period. + */ + unsigned char is_implicit; + /** Whether STA has to send the PS-Poll/Null frame + * indicating that it's in wake period(NRF_WIFI_TWT_FLOW_TYPE_ANNOUNCED) + */ + unsigned char twt_flow_type; + /** wake interval exponent value */ + unsigned char twt_target_wake_interval_exponent; + /** wake interval mantissa value */ + unsigned short twt_target_wake_interval_mantissa; + /** start of the waketime value after successful TWT negotiation */ + unsigned long long target_wake_time; + /** min TWT wake duration */ + unsigned int nominal_min_twt_wake_duration; + /** dialog_token of twt frame */ + unsigned char dialog_token; + /** 0->not received 1->received */ + unsigned char twt_resp_status; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the parameters required for setting up TWT session. + * + */ + +struct nrf_wifi_umac_cmd_config_twt { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** TWT configuration info @ref nrf_wifi_umac_config_twt_info */ + struct nrf_wifi_umac_config_twt_info info; +} __NRF_WIFI_PKD; + +#define INVALID_TIME 1 +#define TRIGGER_NOT_RECEIVED 2 + +/** + * @brief This structure represents the TWT delete information. + * + */ + +struct nrf_wifi_umac_teardown_twt_info { + /** TWT flow Id */ + unsigned char twt_flow_id; + /** reason for teardown */ + unsigned char reason_code; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to delete or remove a TWT session + * + */ + +struct nrf_wifi_umac_cmd_teardown_twt { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_teardown_twt_info */ + struct nrf_wifi_umac_teardown_twt_info info; +} __NRF_WIFI_PKD; + +#define TWT_BLOCK_TX 0 +#define TWT_UNBLOCK_TX 1 +/** + * @brief This structure represents the information related to Tx (transmit) block/unblock. + * + */ +struct twt_sleep_info { + /** value for blocking/unblocking TX + * (TWT_BLOCK_TX or TWT_UNBLOCK_TX) + */ + unsigned int type; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines an event used to indicate to the host whether to block or + * unblock Tx (transmit) packets in TWT communication. + * + */ + +struct nrf_wifi_umac_event_twt_sleep { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref twt_sleep_info */ + struct twt_sleep_info info; +} __NRF_WIFI_PKD; + +#define UAPSD_Q_MIN 0 +#define UAPSD_Q_MAX 15 +/** + * @brief This structure represents the information about UAPSD queues. + * + */ + +struct nrf_wifi_umac_uapsd_info { + /** UAPSD-Q value */ + unsigned int uapsd_queue; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to configure the UAPSD-Q value. + * + */ + +struct nrf_wifi_umac_cmd_config_uapsd { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** @ref nrf_wifi_umac_uapsd_info */ + struct nrf_wifi_umac_uapsd_info info; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the event used to indicate that a scan has started. + * + */ + +struct nrf_wifi_umac_event_trigger_scan { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Scan request control flags (u32). Bit values + * (NRF_WIFI_SCAN_FLAG_LOW_PRIORITY/NRF_WIFI_SCAN_FLAG_RANDOM_ADDR...) + */ + unsigned int nrf_wifi_scan_flags; + /** No.of ssids in scan request */ + unsigned char num_scan_ssid; + /** No.of frequencies in scan request */ + unsigned char num_scan_frequencies; + /** center frequencies */ + unsigned short scan_frequencies[NRF_WIFI_SCAN_MAX_NUM_FREQUENCIES]; + /** @ref nrf_wifi_ssid */ + struct nrf_wifi_ssid scan_ssid[NRF_WIFI_SCAN_MAX_NUM_SSIDS]; + /** @ref nrf_wifi_ie */ + struct nrf_wifi_ie ie; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_MAC_ADDR_VALID (1 << 0) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_IES_TSF_VALID (1 << 1) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_IES_VALID (1 << 2) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BEACON_IES_TSF_VALID (1 << 3) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BEACON_IES_VALID (1 << 4) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BEACON_INTERVAL_VALID (1 << 5) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_SIGNAL_VALID (1 << 6) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_STATUS_VALID (1 << 7) +#define NRF_WIFI_EVENT_NEW_SCAN_RESULTS_BSS_PRESP_DATA (1 << 8) + +#define NRF_WIFI_NEW_SCAN_RESULTS_BSS_PRESP_DATA (1 << 0) + +/** + * @brief This structure serves as a response to the command NRF_WIFI_UMAC_CMD_GET_SCAN_RESULTS. + * It contains scan results for each entry. RPU sends multiple events of this type for every + * scan entry, and when umac_hdr->seq == 0, it indicates the last scan entry. + * + */ + +struct nrf_wifi_umac_event_new_scan_results { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Unused */ + unsigned int generation; + /** Frequency in MHz */ + unsigned int frequency; + /** Channel width of the control channel */ + unsigned int chan_width; + /** Age of this BSS entry in ms */ + unsigned int seen_ms_ago; + /** Unused */ + unsigned int nrf_wifi_flags; + /** Status, if this BSS is "used" */ + signed int status; + /** TSF of the received probe response/beacon (u64) */ + unsigned long long ies_tsf; + /** TSF of the last received beacon + * (not present if no beacon frame has been received yet). + */ + unsigned long long beacon_ies_tsf; + /** Beacon interval of BSS */ + unsigned short beacon_interval; + /** Capability field */ + unsigned short capability; + /** Signal strength, @ref nrf_wifi_signal */ + struct nrf_wifi_signal signal; + /** BSSID of the BSS (6 octets) */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Indicates length of IE's present at the starting of ies[0] */ + unsigned int ies_len; + /** Indicates length of beacon_ies present after ies+ies_len */ + unsigned int beacon_ies_len; + /** contains raw information elements from the probe response/beacon. + * If beacon_ies are not present then the IEs here are from a Probe Response + * frame; otherwise they are from a Beacon frame. + */ + unsigned char ies[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_802_11A (1 << 0) +#define NRF_WIFI_802_11B (1 << 1) +#define NRF_WIFI_802_11G (1 << 2) +#define NRF_WIFI_802_11N (1 << 3) +#define NRF_WIFI_802_11AC (1 << 4) +#define NRF_WIFI_802_11AX (1 << 5) + +#define NRF_WIFI_MFP_REQUIRED (1 << 0) +#define NRF_WIFI_MFP_CAPABLE (1 << 1) +/** + * @brief This structure represents the response for NRF_WIFI_UMAC_CMD_GET_SCAN_RESULTS. + * It contains the displayed scan result. + * + */ + +struct umac_display_results { + /** Network SSID @ref nrf_wifi_ssid */ + struct nrf_wifi_ssid ssid; + /** BSSID of the BSS (6 octets) */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Network band of operation, refer &enum nrf_wifi_band */ + signed int nwk_band; + /** Network channel number */ + unsigned int nwk_channel; + /** Protocol type (NRF_WIFI_802_11A) */ + unsigned char protocol_flags; + /** Network security mode, refer &enum nrf_wifi_security_type */ + signed int security_type; + /** Beacon interval of the BSS */ + unsigned short beacon_interval; + /** Capability field */ + unsigned short capability; + /** Signal strength. Refer &struct nrf_wifi_signal */ + struct nrf_wifi_signal signal; + /** TWT support */ + unsigned char twt_support; + /** management frame protection NRF_WIFI_MFP_REQUIRED/NRF_WIFI_MFP_CAPABLE */ + unsigned char mfp_flag; + /** reserved */ + unsigned char reserved3; + /** reserved */ + unsigned char reserved4; +} __NRF_WIFI_PKD; + +#define DISPLAY_BSS_TOHOST_PEREVNT 8 + +/** + * @brief This structure serves as a response to the command NRF_WIFI_UMAC_CMD_GET_SCAN_RESULTS + * of display scan type. It contains a maximum of DISPLAY_BSS_TOHOST_PEREVENT scan results + * in each event. When umac_hdr->seq == 0, it indicates the last scan event. + * + */ + +struct nrf_wifi_umac_event_new_scan_display_results { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Number of scan results in the current event */ + unsigned char event_bss_count; + /** Display scan results info @ref umac_display_results */ + struct umac_display_results display_results[DISPLAY_BSS_TOHOST_PEREVNT]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EVENT_MLME_FRAME_VALID (1 << 0) +#define NRF_WIFI_EVENT_MLME_MAC_ADDR_VALID (1 << 1) +#define NRF_WIFI_EVENT_MLME_FREQ_VALID (1 << 2) +#define NRF_WIFI_EVENT_MLME_COOKIE_VALID (1 << 3) +#define NRF_WIFI_EVENT_MLME_RX_SIGNAL_DBM_VALID (1 << 4) +#define NRF_WIFI_EVENT_MLME_WME_UAPSD_QUEUES_VALID (1 << 5) +#define NRF_WIFI_EVENT_MLME_RXMGMT_FLAGS_VALID (1 << 6) +#define NRF_WIFI_EVENT_MLME_IE_VALID (1 << 7) + +#define NRF_WIFI_EVENT_MLME_TIMED_OUT (1 << 0) +#define NRF_WIFI_EVENT_MLME_ACK (1 << 1) + +/** + * @brief This structure represent different responses received from the access point during + * various stages of the connection process like Authentication Response and Association Response. + * + */ + +struct nrf_wifi_umac_event_mlme { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Frequency of the channel in MHz */ + unsigned int frequency; + /** Signal strength in dBm */ + unsigned int rx_signal_dbm; + /** Indicate whether the frame was acked or timed out */ + unsigned int nrf_wifi_flags; + /** cookie identifier */ + unsigned long long cookie; + /** Frame data, including frame header and body @ref nrf_wifi_frame */ + struct nrf_wifi_frame frame; + /** BSSID of the BSS */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** Bitmap of uapsd queues */ + unsigned char wme_uapsd_queues; + /** Request(AUTH/ASSOC) ie length */ + unsigned int req_ie_len; + /** ie's */ + unsigned char req_ie[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_SEND_STATION_ASSOC_REQ_IES_VALID (1 << 0) + +/** + * @brief This structure represents an event that is generated when a station is added or removed. + * + */ + +struct nrf_wifi_umac_event_new_station { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate if assoc_req ies is valid */ + unsigned int valid_fields; + /** set to 1: STA supports QoS/WME */ + unsigned char wme; + /** Set to 1 if STA is Legacy(a/b/g) */ + unsigned char is_sta_legacy; + /** Station mac address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** generation number */ + unsigned int generation; + /** Station information @ref nrf_wifi_sta_info */ + struct nrf_wifi_sta_info sta_info; + /** @ref nrf_wifi_ie */ + struct nrf_wifi_ie assoc_req_ies; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_COOKIE_RSP_COOKIE_VALID (1 << 0) +#define NRF_WIFI_CMD_COOKIE_RSP_MAC_ADDR_VALID (1 << 1) + +/** + * @brief This structure specifies the cookie response event, which is used to receive an + * RPU cookie associated with the host cookie passed during NRF_WIFI_UMAC_CMD_FRAME. + * + */ + +struct nrf_wifi_umac_event_cookie_rsp { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate if assoc_req ies is valid */ + unsigned int valid_fields; + /** Identifier passed during NRF_WIFI_UMAC_CMD_FRAME */ + unsigned long long host_cookie; + /** Cookie used to indicate TX done in NRF_WIFI_UMAC_EVENT_FRAME_TX_STATUS */ + unsigned long long cookie; + /** Mac address */ + unsigned char mac_addr[NRF_WIFI_ETH_ADDR_LEN]; + +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the event that corresponds to the command + * NRF_WIFI_UMAC_CMD_GET_TX_POWER. It is used to retrieve the transmit power + * information from the device + * + */ + +struct nrf_wifi_umac_event_get_tx_power { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Tx power in dbm */ + signed int txpwr_level; + +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the response to the command NRF_WIFI_UMAC_CMD_SET_INTERFACE. + * It contains the necessary information indicating the result or status of the interface + * configuration operation after the command has been executed. + * + */ + +struct nrf_wifi_umac_event_set_interface { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** return value */ + signed int return_value; +} __NRF_WIFI_PKD; + +/** + * @brief channel flags. + * + * Channel flags set by the regulatory control code. + * + */ + +enum nrf_wifi_channel_flags { + /** This channel is disabled */ + CHAN_DISABLED = 1<<0, + /** do not initiate radiation, this includes sending probe requests or beaconing */ + CHAN_NO_IR = 1<<1, + /** Radar detection is required on this channel hole at 1<<2 */ + CHAN_RADAR = 1<<3, + /** extension channel above this channel is not permitted */ + CHAN_NO_HT40PLUS = 1<<4, + /** extension channel below this channel is not permitted */ + CHAN_NO_HT40MINUS = 1<<5, + /** OFDM is not allowed on this channel */ + CHAN_NO_OFDM = 1<<6, + /** If the driver supports 80 MHz on the band, + * this flag indicates that an 80 MHz channel cannot use this + * channel as the control or any of the secondary channels. + * This may be due to the driver or due to regulatory bandwidth + * restrictions. + */ + CHAN_NO_80MHZ = 1<<7, + /** If the driver supports 160 MHz on the band, + * this flag indicates that an 160 MHz channel cannot use this + * channel as the control or any of the secondary channels. + * This may be due to the driver or due to regulatory bandwidth + * restrictions. + */ + CHAN_NO_160MHZ = 1<<8, + /** @ref NL80211_FREQUENCY_ATTR_INDOOR_ONLY */ + CHAN_INDOOR_ONLY = 1<<9, + /** @ref NL80211_FREQUENCY_ATTR_GO_CONCURRENT */ + CHAN_GO_CONCURRENT = 1<<10, + /** 20 MHz bandwidth is not permitted on this channel */ + CHAN_NO_20MHZ = 1<<11, + /** 10 MHz bandwidth is not permitted on this channel */ + CHAN_NO_10MHZ = 1<<12, +}; + +/** + * @brief channel definition. + * + */ + +struct nrf_wifi_chan_definition { + /** Frequency of the selected channel in MHz */ + struct nrf_wifi_channel chan; + /** channel width */ + signed int width; + /** center frequency of first segment */ + unsigned int center_frequency1; + /** center frequency of second segment (only with 80+80 MHz) */ + unsigned int center_frequency2; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents channel information and serves as the event for the + * command NRF_WIFI_UMAC_CMD_GET_CHANNEL. + * + */ +struct nrf_wifi_umac_event_get_channel { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Channel information.@ref nrf_wifi_chan_definition */ + struct nrf_wifi_chan_definition chan_def; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command used to retrieve connection information. + * + */ +struct nrf_wifi_umac_cmd_conn_info { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +enum link_mode { + NRF_WIFI_MODE_11B = 1, + NRF_WIFI_MODE_11A, + NRF_WIFI_MODE_11G, + NRF_WIFI_MODE_11N, + NRF_WIFI_MODE_11AC, + NRF_WIFI_MODE_11AX +}; + +/** + * @brief This structure represents the information related to the connection of a station. + * + */ + +struct nrf_wifi_umac_event_conn_info { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Beacon interval */ + unsigned short beacon_interval; + /** DTIM interval */ + unsigned char dtim_interval; + /** Station association state */ + unsigned char associated; + /** TWT supported or not */ + unsigned char twt_capable; + /** Refer &enum link_mode */ + unsigned char linkmode; +} __NRF_WIFI_PKD; + + +/** + * @brief This structure defines the command used to retrieve power save information. + * + */ +struct nrf_wifi_umac_cmd_get_power_save_info { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to set the listen interval period. + * It determines how frequently a device wakes up to check for any pending data or traffic + * from the access point. By setting the listen interval, devices can adjust their power-saving + * behavior to balance power efficiency and responsiveness to incoming data. + * + */ +struct nrf_wifi_umac_cmd_set_listen_interval { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** listen interval */ + unsigned short listen_interval; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command used to enable or disable extended power save mode. + * When enabled, the RPU wakes up based on the listen interval, allowing the device to spend more + * time in a lower power state. When disabled, the RPU wakes up based on the DTIM period, which + * may require more frequent wake-ups but can provide better responsiveness for receiving + * multicast/broadcast traffic. + * + */ +struct nrf_wifi_umac_cmd_config_extended_ps { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** 1=enable 0=disable */ + unsigned char enable_extended_ps; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_MAX_TWT_FLOWS 8 +#define NRF_WIFI_PS_MODE_LEGACY 0 +#define NRF_WIFI_PS_MODE_WMM 1 + +/** + * @brief Given that most APs typically use a DTIM value of 3, + * we anticipate a minimum listen interval of 3 beacon intervals. + * + */ +#define NRF_WIFI_LISTEN_INTERVAL_MIN 3 + +/** + * @brief This structure represents an event that provides information about the RPU power save + * mode. It contains details regarding the current power save mode and its settings. + * + */ +struct nrf_wifi_umac_event_power_save_info { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Power save mode. NRF_WIFI_PS_MODE_LEGACY/NRF_WIFI_PS_MODE_WMM */ + unsigned char ps_mode; + /** Power save enable flag */ + unsigned char enabled; + /** Extended power save ON(1)/OFF(0) */ + unsigned char extended_ps; + /** Is TWT responder */ + unsigned char twt_responder; + /** Power save timed out value */ + unsigned int ps_timeout; + /** Listen interval value */ + unsigned short listen_interval; + /** Number TWT flows */ + unsigned char num_twt_flows; + /** TWT info of each flow @ref nrf_wifi_umac_config_twt_info */ + struct nrf_wifi_umac_config_twt_info twt_flow_info[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EVENT_TRIGGER_SCAN_IE_VALID (1 << 0) +#define NRF_WIFI_EVENT_TRIGGER_SCAN_SCAN_FLAGS_VALID (1 << 1) +/** + * @brief This structure contains information relevant to the "Remain on Channel" operation. + * It is used to specify the details related to the duration and channel on which a device + * needs to stay without regular data transmission or reception. + * + */ + +struct remain_on_channel_info { + /** Amount of time to remain on specified channel */ + unsigned int dur; + /** Frequency configuration, see &struct freq_params */ + struct freq_params nrf_wifi_freq_params; + /** Identifier to be used for processing NRF_WIFI_UMAC_EVENT_COOKIE_RESP event */ + unsigned long long host_cookie; + /** Unused */ + unsigned long long cookie; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_ROC_FREQ_PARAMS_VALID (1 << 0) +#define NRF_WIFI_CMD_ROC_DURATION_VALID (1 << 1) +/** + * @brief This structure represents the command used to keep the device awake on the specified + * channel for a designated period. The command initiates the "Remain on Channel" operation. + * + */ + +struct nrf_wifi_umac_cmd_remain_on_channel { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Information about channel parameters.@ref remain_on_channel_info */ + struct remain_on_channel_info info; + +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_CANCEL_ROC_COOKIE_VALID (1 << 0) +/** + * @brief This structure represents the command to cancel "Remain on Channel" operation. + * + */ +struct nrf_wifi_umac_cmd_cancel_remain_on_channel { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** cookie to identify remain on channel */ + unsigned long long cookie; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EVENT_ROC_FREQ_VALID (1 << 0) +#define NRF_WIFI_EVENT_ROC_COOKIE_VALID (1 << 1) +#define NRF_WIFI_EVENT_ROC_DURATION_VALID (1 << 2) +#define NRF_WIFI_EVENT_ROC_CH_TYPE_VALID (1 << 3) +/** + * @brief This structure represents the response to command "Remain on Channel". + * + */ + +struct nrf_wifi_event_remain_on_channel { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Frequency of the channel */ + unsigned int frequency; + /** duration that can be requested with the remain-on-channel operation(ms) */ + unsigned int dur; + /** see &enum nrf_wifi_channel_type */ + unsigned int ch_type; + /** cookie to identify remain on channel */ + unsigned long long cookie; +} __NRF_WIFI_PKD; + +/** + * @brief This structure defines the command used to retrieve interface information. + * + */ +struct nrf_wifi_cmd_get_interface { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_INTERFACE_INFO_CHAN_DEF_VALID (1 << 0) +#define NRF_WIFI_INTERFACE_INFO_SSID_VALID (1 << 1) +#define NRF_WIFI_INTERFACE_INFO_IFNAME_VALID (1 << 2) + +/** + * @brief This structure represents an event that contains information about a network interface. + * + */ + +struct nrf_wifi_interface_info { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Interface type, see &enum nrf_wifi_iftype */ + signed int nrf_wifi_iftype; + /** Interface name */ + signed char ifacename[IFACENAMSIZ]; + /** Mac address */ + unsigned char nrf_wifi_eth_addr[NRF_WIFI_ETH_ADDR_LEN]; + /** @ref nrf_wifi_chan_definition */ + struct nrf_wifi_chan_definition chan_def; + /** @ref nrf_wifi_ssid */ + struct nrf_wifi_ssid ssid; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_HT_MCS_MASK_LEN 10 +#define NRF_WIFI_HT_MCS_RES_LEN 3 + +/** + * @brief MCS information. + * + */ +struct nrf_wifi_event_mcs_info { + /** Highest supported RX rate */ + unsigned short nrf_wifi_rx_highest; + /** RX mask */ + unsigned char nrf_wifi_rx_mask[NRF_WIFI_HT_MCS_MASK_LEN]; + /** TX parameters */ + unsigned char nrf_wifi_tx_params; + /** reserved */ + unsigned char nrf_wifi_reserved[NRF_WIFI_HT_MCS_RES_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents HT capability parameters. + * + */ +struct nrf_wifi_event_sta_ht_cap { + /** 1 indicates HT Supported */ + signed int nrf_wifi_ht_supported; + /** HT capabilities, as in the HT information IE */ + unsigned short nrf_wifi_cap; + /** MCS information. @ref nrf_wifi_event_mcs_info */ + struct nrf_wifi_event_mcs_info mcs; + /** A-MPDU factor, as in 11n */ + unsigned char nrf_wifi_ampdu_factor; + /** A-MPDU density, as in 11n */ + unsigned char nrf_wifi_ampdu_density; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_IR (1 << 0) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_IBSS (1 << 1) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_RADAR (1 << 2) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_MINUS (1 << 3) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_HT40_PLUS (1 << 4) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_80MHZ (1 << 5) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_160MHZ (1 << 6) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_INDOOR_ONLY (1 << 7) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_GO_CONCURRENT (1 << 8) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_20MHZ (1 << 9) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_10MHZ (1 << 10) +#define NRF_WIFI_CHAN_FLAG_FREQUENCY_DISABLED (1 << 11) + +#define NRF_WIFI_CHAN_DFS_VALID (1 << 12) +#define NRF_WIFI_CHAN_DFS_CAC_TIME_VALID (1 << 13) + +/** + * @brief This structure represents channel parameters. + */ +struct nrf_wifi_event_channel { + /** channel flags NRF_WIFI_CHAN_FLAG_FREQUENCY_ATTR_NO_IBSS */ + unsigned short nrf_wifi_flags; + /** maximum transmission power (in dBm) */ + signed int nrf_wifi_max_power; + /** DFS state time */ + unsigned int nrf_wifi_time; + /** DFS CAC time in ms */ + unsigned int dfs_cac_msec; + /** Channel parameters are valid or not 1=valid */ + signed char ch_valid; + /** Channel center frequency */ + unsigned short center_frequency; + /** Current dfs state */ + signed char dfs_state; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EVENT_GET_WIPHY_FLAG_RATE_SHORT_PREAMBLE (1 << 0) +/** + * @brief This structure represents rate information. + */ +struct nrf_wifi_event_rate { + /** NRF_WIFI_EVENT_GET_WIPHY_FLAG_RATE_SHORT_PREAMBLE */ + unsigned short nrf_wifi_flags; + /** Bitrate in units of 100 kbps */ + unsigned short nrf_wifi_bitrate; +} __NRF_WIFI_PKD; +/** + * @brief VHT MCS information. + * + */ + +struct nrf_wifi_event_vht_mcs_info { + /** RX MCS map 2 bits for each stream, total 8 streams */ + unsigned short rx_mcs_map; + /** Indicates highest long GI VHT PPDU data rate + * STA can receive. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest RX data rate supported. + */ + unsigned short rx_highest; + /** TX MCS map 2 bits for each stream, total 8 streams */ + unsigned short tx_mcs_map; + /** Indicates highest long GI VHT PPDU data rate + * STA can transmit. Rate expressed in units of 1 Mbps. + * If this field is 0 this value should not be used to + * consider the highest TX data rate supported. + */ + unsigned short tx_highest; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents VHT capability parameters. + * + */ +struct nrf_wifi_event_sta_vht_cap { + /** 1 indicates VHT Supported */ + signed char nrf_wifi_vht_supported; + /** VHT capability info */ + unsigned int nrf_wifi_cap; + /** Refer @ref nrf_wifi_event_vht_mcs_info */ + struct nrf_wifi_event_vht_mcs_info vht_mcs; +} __NRF_WIFI_PKD; + +/** + * @brief Frequency band information. + * + */ +struct nrf_wifi_event_supported_band { + /** No.of channels */ + unsigned short nrf_wifi_n_channels; + /** No.of bitrates */ + unsigned short nrf_wifi_n_bitrates; + /** Array of channels the hardware can operate in this band */ + struct nrf_wifi_event_channel channels[29]; + /** Array of bitrates the hardware can operate with in this band */ + struct nrf_wifi_event_rate bitrates[13]; + /** HT capabilities in this band */ + struct nrf_wifi_event_sta_ht_cap ht_cap; + /** VHT capabilities in this band */ + struct nrf_wifi_event_sta_vht_cap vht_cap; + /** the band this structure represents */ + signed char band; +} __NRF_WIFI_PKD; + +/** + * @brief Interface limits. + * + */ +struct nrf_wifi_event_iface_limit { + /** max interface limits */ + unsigned short nrf_wifi_max; + /** types */ + unsigned short nrf_wifi_types; +} __NRF_WIFI_PKD; + + +#define NRF_WIFI_EVENT_GET_WIPHY_VALID_RADAR_DETECT_WIDTHS (1 << 0) +#define NRF_WIFI_EVENT_GET_WIPHY_VALID_RADAR_DETECT_REGIONS (1 << 1) +#define NRF_WIFI_EVENT_GET_WIPHY_VALID_ (1 << 2) +/** + * @brief This structure defines an event that represents interface combinations. + * + */ +struct nrf_wifi_event_iface_combination { + /** channels count */ + unsigned int nrf_wifi_num_different_channels; + /** Unused */ + signed int beacon_int_infra_match; + /** @ref nrf_wifi_event_iface_limit */ + struct nrf_wifi_event_iface_limit limits[2]; + /** Max interfaces */ + unsigned short nrf_wifi_max_interfaces; + /** Not used */ + unsigned char nrf_wifi_radar_detect_widths; + /** Not used */ + unsigned char nrf_wifi_n_limits; + /** Not used */ + unsigned char nrf_wifi_radar_detect_regions; + /** Not used */ + unsigned char comb_valid; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_EVENT_GET_WIPHY_IBSS_RSN (1 << 0) +#define NRF_WIFI_EVENT_GET_WIPHY_MESH_AUTH (1 << 1) +#define NRF_WIFI_EVENT_GET_WIPHY_AP_UAPSD (1 << 2) +#define NRF_WIFI_EVENT_GET_WIPHY_SUPPORTS_FW_ROAM (1 << 3) +#define NRF_WIFI_EVENT_GET_WIPHY_SUPPORTS_TDLS (1 << 4) +#define NRF_WIFI_EVENT_GET_WIPHY_TDLS_EXTERNAL_SETUP (1 << 5) +#define NRF_WIFI_EVENT_GET_WIPHY_CONTROL_PORT_ETHERTYPE (1 << 6) +#define NRF_WIFI_EVENT_GET_WIPHY_OFFCHANNEL_TX_OK (1 << 7) + +#define NRF_WIFI_GET_WIPHY_VALID_PROBE_RESP_OFFLOAD (1 << 0) +#define NRF_WIFI_GET_WIPHY_VALID_TX_ANT (1 << 1) +#define NRF_WIFI_GET_WIPHY_VALID_RX_ANT (1 << 2) +#define NRF_WIFI_GET_WIPHY_VALID_MAX_NUM_SCAN_SSIDS (1 << 3) +#define NRF_WIFI_GET_WIPHY_VALID_NUM_SCHED_SCAN_SSIDS (1 << 4) +#define NRF_WIFI_GET_WIPHY_VALID_MAX_MATCH_SETS (1 << 5) +#define NRF_WIFI_GET_WIPHY_VALID_MAC_ACL_MAX (1 << 6) +#define NRF_WIFI_GET_WIPHY_VALID_HAVE_AP_SME (1 << 7) +#define NRF_WIFI_GET_WIPHY_VALID_EXTENDED_CAPABILITIES (1 << 8) +#define NRF_WIFI_GET_WIPHY_VALID_MAX_AP_ASSOC_STA (1 << 9) +#define NRF_WIFI_GET_WIPHY_VALID_WIPHY_NAME (1 << 10) +#define NRF_WIFI_GET_WIPHY_VALID_EXTENDED_FEATURES (1 << 11) + +#define NRF_WIFI_EVENT_GET_WIPHY_MAX_CIPHER_COUNT 30 + +#define NRF_WIFI_INDEX_IDS_WIPHY_NAME 32 +#define NRF_WIFI_EVENT_GET_WIPHY_NUM_BANDS 2 + +#define EXTENDED_FEATURE_LEN 60 +#define DIV_ROUND_UP_NL(n, d) (((n) + (d)-1) / (d)) + +/** + * @brief This structure represents wiphy parameters. + * + */ +struct nrf_wifi_event_get_wiphy { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Unused */ + unsigned int nrf_wifi_frag_threshold; + /** RTS threshold value */ + unsigned int nrf_wifi_rts_threshold; + /** Unused */ + unsigned int nrf_wifi_available_antennas_tx; + /** Unused */ + unsigned int nrf_wifi_available_antennas_rx; + /** Unused */ + unsigned int nrf_wifi_probe_resp_offload; + /** Unused */ + unsigned int tx_ant; + /** Unused */ + unsigned int rx_ant; + /** Unused */ + unsigned int split_start2_flags; + /** Maximum ROC duration */ + unsigned int max_remain_on_channel_duration; + /** Unused */ + unsigned int ap_sme_capa; + /** Unused */ + unsigned int features; + /** Unused */ + unsigned int max_acl_mac_addresses; + /** maximum number of associated stations supported in AP mode */ + unsigned int max_ap_assoc_sta; + /** supported cipher suites */ + unsigned int cipher_suites[NRF_WIFI_EVENT_GET_WIPHY_MAX_CIPHER_COUNT]; + /** wiphy flags NRF_WIFI_EVENT_GET_WIPHY_AP_UAPSD */ + unsigned int get_wiphy_flags; + /** valid parameters NRF_WIFI_GET_WIPHY_VALID_WIPHY_NAME */ + unsigned int params_valid; + /** Maximum scan IE length */ + unsigned short int max_scan_ie_len; + /** Unused */ + unsigned short int max_sched_scan_ie_len; + /** bit mask of interface value of see &enum nrf_wifi_iftype */ + unsigned short int interface_modes; + /** Unused */ + struct nrf_wifi_event_iface_combination iface_com[6]; + /** Unused */ + signed char supp_commands[40]; + /** Retry limit for short frames */ + unsigned char retry_short; + /** Retry limit for long frames */ + unsigned char retry_long; + /** Unused */ + unsigned char coverage_class; + /** Maximum ssids supported in scan */ + unsigned char max_scan_ssids; + /** Unused */ + unsigned char max_sched_scan_ssids; + /** Unused */ + unsigned char max_match_sets; + /** Unused */ + unsigned char n_cipher_suites; + /** Unused */ + unsigned char max_num_pmkids; + /** length of the extended capabilities */ + unsigned char extended_capabilities_len; + /** Extended capabilities */ + unsigned char extended_capabilities[10]; + /** Extended capabilities mask */ + unsigned char extended_capabilities_mask[10]; + /** Unused */ + unsigned char ext_features[DIV_ROUND_UP_NL(EXTENDED_FEATURE_LEN, 8)]; + /** Unused */ + unsigned char ext_features_len; + /** Unused */ + signed char num_iface_com; + /** Wiphy name */ + signed char wiphy_name[NRF_WIFI_INDEX_IDS_WIPHY_NAME]; + /** Supported bands info. @ref nrf_wifi_event_supported_band */ + struct nrf_wifi_event_supported_band sband[NRF_WIFI_EVENT_GET_WIPHY_NUM_BANDS]; +} __NRF_WIFI_PKD; +/** + * @brief This structure represents the command used to retrieve Wireless PHY (wiphy) information. + * + */ +struct nrf_wifi_cmd_get_wiphy { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command to get hardware address. + * + */ +struct nrf_wifi_cmd_get_ifhwaddr { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Interface name */ + signed char ifacename[IFACENAMSIZ]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the command used to retrieve the hardware address or + * MAC address of the device. + * + */ +struct nrf_wifi_cmd_set_ifhwaddr { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Interface name */ + signed char ifacename[IFACENAMSIZ]; + /** Hardware address to be set */ + unsigned char nrf_wifi_hwaddr[NRF_WIFI_ETH_ADDR_LEN]; +} __NRF_WIFI_PKD; + +#define REG_RULE_FLAGS_VALID (1 << 0) +#define FREQ_RANGE_START_VALID (1 << 1) +#define FREQ_RANGE_END_VALID (1 << 2) +#define FREQ_RANGE_MAX_BW_VALID (1 << 3) +#define POWER_RULE_MAX_EIRP_VALID (1 << 4) + +#define NRF_WIFI_RULE_FLAGS_NO_OFDM (1<<0) +#define NRF_WIFI_RULE_FLAGS_NO_CCK (1<<1) +#define NRF_WIFI_RULE_FLAGS_NO_INDOOR (1<<2) +#define NRF_WIFI_RULE_FLAGS_NO_OUTDOOR (1<<3) +#define NRF_WIFI_RULE_FLAGS_DFS (1<<4) +#define NRF_WIFI_RULE_FLAGS_PTP_ONLY (1<<5) +#define NRF_WIFI_RULE_FLAGS_PTMP_ONLY (1<<6) +#define NRF_WIFI_RULE_FLAGS_NO_IR (1<<7) +#define NRF_WIFI_RULE_FLAGS_IBSS (1<<8) +#define NRF_WIFI_RULE_FLAGS_AUTO_BW (1<<11) +#define NRF_WIFI_RULE_FLAGS_IR_CONCURRENT (1<<12) +#define NRF_WIFI_RULE_FLAGS_NO_HT40MINUS (1<<13) +#define NRF_WIFI_RULE_FLAGS_NO_HT40PLUS (1<<14) +#define NRF_WIFI_RULE_FLAGS_NO_80MHZ (1<<15) +#define NRF_WIFI_RULE_FLAGS_NO_160MHZ (1<<16) + +/** + * @brief This structure represents the information related to the regulatory domain + * of a wireless device. The regulatory domain defines the specific rules and regulations + * that govern the usage of radio frequencies in a particular geographical region. + * + */ + +struct nrf_wifi_reg_rules { + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** NRF_WIFI_RULE_FLAGS_NO_CCK and NRF_WIFI_RULE_FLAGS_NO_INDOOR */ + unsigned int rule_flags; + /** starting frequencry for the regulatory rule in KHz */ + unsigned int freq_range_start; + /** ending frequency for the regulatory rule in KHz */ + unsigned int freq_range_end; + /** maximum allowed bandwidth for this frequency range */ + unsigned int freq_range_max_bw; + /** maximum allowed EIRP mBm (100 * dBm) */ + unsigned int pwr_max_eirp; + +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents channels information like maximum power, + * center frequency, channel supported and active or passive scan. + * + */ +struct nrf_wifi_get_reg_chn_info { + /** center frequency in MHz */ + unsigned int center_frequency; + /** maximum transmission power (in dBm) */ + unsigned int max_power; + /** Particular channel is supported or not */ + char supported; + /** Particular channel is supports passive scanning or not */ + char passive_channel; + /** Particular channel is dfs or not */ + char dfs; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_SET_REG_ALPHA2_VALID (1 << 0) +#define NRF_WIFI_CMD_SET_REG_RULES_VALID (1 << 1) +#define NRF_WIFI_CMD_SET_REG_DFS_REGION_VALID (1 << 2) + +#define MAX_NUM_REG_RULES 32 + +/** + * @brief This structure represents an event that contains regulatory domain information. + * + */ + +struct nrf_wifi_reg { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Country code */ + unsigned char nrf_wifi_alpha2[NRF_WIFI_COUNTRY_CODE_LEN]; + /** Number of channel list information */ + unsigned int num_channels; + /** channels list information */ + struct nrf_wifi_get_reg_chn_info chn_info[0]; +} __NRF_WIFI_PKD; + +#define NRF_WIFI_CMD_REQ_SET_REG_ALPHA2_VALID (1 << 0) +#define NRF_WIFI_CMD_REQ_SET_REG_USER_REG_HINT_TYPE_VALID (1 << 1) +#define NRF_WIFI_CMD_REQ_SET_REG_USER_REG_FORCE (1 << 2) +/** + * @brief This structure represents the command used to set the regulatory domain + * for a wireless device. It allows configuring the device to adhere to the rules + * and regulations specific to the geographical region in which it is operating. + * + */ +struct nrf_wifi_cmd_req_set_reg { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Indicate which of the following parameters are valid */ + unsigned int valid_fields; + /** Type of regulatory hint passed from userspace */ + unsigned int nrf_wifi_user_reg_hint_type; + /** Country code */ + unsigned char nrf_wifi_alpha2[NRF_WIFI_COUNTRY_CODE_LEN]; +} __NRF_WIFI_PKD; + +/** + * @brief This structure represents the status code for a command. It is used to indicate + * the outcome or result of executing a specific command. The status code provides valuable + * information about the success, failure, or any errors encountered during the execution + * of the command, helping to understand the current state of the device. + * + */ +struct nrf_wifi_umac_event_cmd_status { + /** Header @ref nrf_wifi_umac_hdr */ + struct nrf_wifi_umac_hdr umac_hdr; + /** Command id. see &enum nrf_wifi_umac_commands */ + unsigned int cmd_id; + /** Status codes */ + unsigned int cmd_status; +} __NRF_WIFI_PKD; + +#endif /* __HOST_RPU_UMAC_IF_H */ diff --git a/nrf_wifi/fw_if/umac_if/inc/fw/lmac_if_common.h b/nrf_wifi/fw_if/umac_if/inc/fw/lmac_if_common.h new file mode 100644 index 0000000000..3d1e8dba44 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fw/lmac_if_common.h @@ -0,0 +1,217 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Common structures and definitions. + */ + +#ifndef __LMAC_IF_COMMON__ +#define __LMAC_IF_COMMON__ + +#include "rpu_if.h" +#include "phy_rf_params.h" +#include "pack_def.h" + +#define RPU_MEM_LMAC_BOOT_SIG 0xB7000D50 +#define RPU_MEM_LMAC_VER 0xB7000D54 + +#define RPU_MEM_LMAC_PATCH_BIN 0x80044000 +#define RPU_MEM_LMAC_PATCH_BIMG 0x8004B000 + +#define NRF_WIFI_LMAC_VER(ver) ((ver & 0xFF000000) >> 24) +#define NRF_WIFI_LMAC_VER_MAJ(ver) ((ver & 0x00FF0000) >> 16) +#define NRF_WIFI_LMAC_VER_MIN(ver) ((ver & 0x0000FF00) >> 8) +#define NRF_WIFI_LMAC_VER_EXTRA(ver) (ver & 0x000000FF) + +#define NRF_WIFI_LMAC_BOOT_SIG 0x5A5A5A5A +#define NRF_WIFI_LMAC_ROM_PATCH_OFFSET (RPU_MEM_LMAC_PATCH_BIMG - RPU_ADDR_LMAC_CORE_RET_START) +#define NRF_WIFI_LMAC_BOOT_EXCP_VECT_0 0x3c1a8000 +#define NRF_WIFI_LMAC_BOOT_EXCP_VECT_1 0x275a0000 +#define NRF_WIFI_LMAC_BOOT_EXCP_VECT_2 0x03400008 +#define NRF_WIFI_LMAC_BOOT_EXCP_VECT_3 0x00000000 + +#define NRF_WIFI_LMAC_MAX_RX_BUFS 256 + +#define HW_SLEEP_ENABLE 2 +#define SW_SLEEP_ENABLE 1 +#define SLEEP_DISABLE 0 +#define HW_DELAY 7300 +#define SW_DELAY 5000 +#define BCN_TIMEOUT 40000 +#define CALIB_SLEEP_CLOCK_ENABLE 1 + +#define ACTIVE_SCAN_DURATION 50 +#define PASSIVE_SCAN_DURATION 130 +#define WORKING_CH_SCAN_DURATION 50 +#define CHNL_PROBE_CNT 2 + +#define PKT_TYPE_MPDU 0 +#define PKT_TYPE_MSDU_WITH_MAC 1 +#define PKT_TYPE_MSDU 2 + +#define NRF_WIFI_RPU_PWR_STATUS_SUCCESS 0 +#define NRF_WIFI_RPU_PWR_STATUS_FAIL -1 + +/** + * struct lmac_prod_stats : used to get the production mode stats + **/ + +/* Events */ +#define MAX_RSSI_SAMPLES 10 +struct lmac_prod_stats { + /*Structure that holds all the debug information in LMAC*/ + unsigned int reset_cmd_cnt; + unsigned int reset_complete_event_cnt; + unsigned int unable_gen_event; + unsigned int ch_prog_cmd_cnt; + unsigned int channel_prog_done; + unsigned int tx_pkt_cnt; + unsigned int tx_pkt_done_cnt; + unsigned int scan_pkt_cnt; + unsigned int internal_pkt_cnt; + unsigned int internal_pkt_done_cnt; + unsigned int ack_resp_cnt; + unsigned int tx_timeout; + unsigned int deagg_isr; + unsigned int deagg_inptr_desc_empty; + unsigned int deagg_circular_buffer_full; + unsigned int lmac_rxisr_cnt; + unsigned int rx_decryptcnt; + unsigned int process_decrypt_fail; + unsigned int prepa_rx_event_fail; + unsigned int rx_core_pool_full_cnt; + unsigned int rx_mpdu_crc_success_cnt; + unsigned int rx_mpdu_crc_fail_cnt; + unsigned int rx_ofdm_crc_success_cnt; + unsigned int rx_ofdm_crc_fail_cnt; + unsigned int rxDSSSCrcSuccessCnt; + unsigned int rxDSSSCrcFailCnt; + unsigned int rx_crypto_start_cnt; + unsigned int rx_crypto_done_cnt; + unsigned int rx_event_buf_full; + unsigned int rx_extram_buf_full; + unsigned int scan_req; + unsigned int scan_complete; + unsigned int scan_abort_req; + unsigned int scan_abort_complete; + unsigned int internal_buf_pool_null; +}; + +/** + * struct phy_prod_stats : used to get the production mode stats + **/ +struct phy_prod_stats { + unsigned int ofdm_crc32_pass_cnt; + unsigned int ofdm_crc32_fail_cnt; + unsigned int dsss_crc32_pass_cnt; + unsigned int dsss_crc32_fail_cnt; + char averageRSSI; +}; + +union rpu_stats { + struct lmac_prod_stats lmac_stats; + struct phy_prod_stats phy_stats; +}; + +struct hpqm_queue { + unsigned int pop_addr; + unsigned int push_addr; + unsigned int id_num; + unsigned int status_addr; + unsigned int status_mask; +} __NRF_WIFI_PKD; + +struct INT_HPQ { + unsigned int id; + /* The head and tail values are relative + * to the start of the + * HWQM register block. + */ + unsigned int head; + unsigned int tail; +} __NRF_WIFI_PKD; + +/** + * @brief LMAC firmware config params + * + */ +struct lmac_fw_config_params { + /** lmac firmware boot status. LMAC will set to 0x5a5a5a5a after completing boot process */ + unsigned int boot_status; + /** LMAC version */ + unsigned int version; + /** Address to resubmit Rx buffers */ + unsigned int lmac_rx_buffer_addr; + /** Maximum Rx descriptors */ + unsigned int lmac_rx_max_desc_cnt; + /** size of each descriptor size */ + unsigned int lmac_rx_desc_size; + /** rpu config name. this is a string */ + unsigned char rpu_config_name[16]; + /** rpu config number */ + unsigned char rpu_config_number[8]; + /** numRX */ + unsigned int numRX; + /** numTX */ + unsigned int numTX; +#define FREQ_2_4_GHZ 1 +#define FREQ_5_GHZ 2 + /** supported bands */ + unsigned int bands; + /** system frequency */ + unsigned int sys_frequency_in_mhz; + /** queue which contains Free GRAM pointers for commands */ + struct hpqm_queue FreeCmdPtrQ; + /** Command pointer queue. Host should pick pointer from FreeCmdPtrQ, populate + * command into that address and submit back to this queue for RPU + */ + struct hpqm_queue cmdPtrQ; + /** queue which contains Free GRAM pointers for events */ + struct hpqm_queue eventPtrQ; + /** Event pointer queue. Host should pick pointer from FreeCmdPtrQ, populate + * command into that address and submit back to this queue for RPU + */ + struct hpqm_queue freeEventPtrQ; + /** Rx buffer queue */ + struct hpqm_queue SKBGramPtrQ_1; + /** Rx buffer queue */ + struct hpqm_queue SKBGramPtrQ_2; + /** Rx buffer queue */ + struct hpqm_queue SKBGramPtrQ_3; + /** lmac register address to enable ISR to Host */ + unsigned int HP_lmac_to_host_isr_en; + /** Address to Clear host ISR */ + unsigned int HP_lmac_to_host_isr_clear; + /** Address to set ISR to lmac Clear host ISR */ + unsigned int HP_set_lmac_isr; + +#define NUM_32_QUEUES 4 + /** Hardware queues */ + struct INT_HPQ hpq32[NUM_32_QUEUES]; + +} __NRF_WIFI_PKD; + +#define MAX_NUM_OF_RX_QUEUES 3 + +struct rx_buf_pool_params { + /** buffer size */ + unsigned short buf_sz; + /** number of buffers */ + unsigned short num_bufs; +} __NRF_WIFI_PKD; + +struct temp_vbat_config { + unsigned int temp_based_calib_en; + unsigned int temp_calib_bitmap; + unsigned int vbat_calibp_bitmap; + unsigned int temp_vbat_mon_period; + int vth_very_low; + int vth_low; + int vth_hi; + int temp_threshold; + int vbat_threshold; +} __NRF_WIFI_PKD; +#endif diff --git a/nrf_wifi/fw_if/umac_if/inc/fw/rpu_fw_patches.h b/nrf_wifi/fw_if/umac_if/inc/fw/rpu_fw_patches.h new file mode 100644 index 0000000000..b0961581a1 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/fw/rpu_fw_patches.h @@ -0,0 +1,9728 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Common structures and definations. + */ +#ifdef CONFIG_NRF700X_RADIO_TEST +const unsigned char __aligned(4) nrf_wifi_umac_patch_pri_bimg[] = { + 0xba, 0xda, 0xba, 0xab, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x93, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xa6, 0x70, 0x00, 0x00, 0x04, 0xd4, 0xc6, 0x6a, 0x9c, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x13, 0x5b, 0x04, 0xd4, 0x32, 0x66, 0xa8, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0xb5, 0x62, 0x04, 0xd4, 0xc8, 0x75, 0xf8, 0x24, 0x10, 0x80, + 0x01, 0x00, 0xbb, 0x85, 0x04, 0xd4, 0x4e, 0x76, 0x26, 0x21, 0x10, 0x80, + 0x01, 0x00, 0x33, 0x27, 0x04, 0xd4, 0x8e, 0x62, 0xac, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x2f, 0x66, 0x04, 0xd4, 0x92, 0x76, 0x54, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x78, 0x49, 0x04, 0xd4, 0x32, 0x62, 0x68, 0x24, 0x10, 0x80, + 0x01, 0x00, 0xd1, 0xb9, 0x04, 0xd4, 0x8e, 0x65, 0x00, 0x23, 0x10, 0x80, + 0x01, 0x00, 0xf1, 0x3f, 0x04, 0xd4, 0x0a, 0x62, 0x22, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0xd4, 0xed, 0x04, 0xd4, 0x4c, 0x6a, 0x7e, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x96, 0x37, 0x04, 0xd4, 0x32, 0x6a, 0x78, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x6a, 0x94, 0x04, 0xd4, 0xda, 0x73, 0xa2, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x88, 0xc4, 0x04, 0xd4, 0x58, 0x61, 0xd6, 0x1c, 0x10, 0x80, + 0x01, 0x00, 0x5b, 0x08, 0x04, 0xd4, 0x70, 0x63, 0xb8, 0x22, 0x10, 0x80, + 0x01, 0x00, 0xf7, 0x11, 0x04, 0xd4, 0x0a, 0x76, 0x58, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x63, 0xf5, 0x04, 0xd4, 0x9e, 0x63, 0x82, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x51, 0x56, 0x04, 0xd4, 0x7e, 0x6a, 0xc6, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x02, 0x08, 0x04, 0xd4, 0xe2, 0x75, 0x78, 0x23, 0x10, 0x80, + 0x01, 0x00, 0x5b, 0xdc, 0x04, 0xd4, 0xe0, 0x75, 0x4c, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0x15, 0xfd, 0x04, 0xd4, 0xe0, 0x6a, 0x14, 0x21, 0x10, 0x80, + 0x01, 0x00, 0x17, 0xfe, 0x04, 0xd4, 0x3e, 0x75, 0x34, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x7f, 0x57, 0x04, 0xd4, 0xa0, 0x60, 0xc4, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x3b, 0xd6, 0x04, 0xd4, 0xdc, 0x74, 0xe2, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x00, 0x5e, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0xba, 0x3e +}; + +const unsigned char __aligned(4) nrf_wifi_umac_patch_sec_bin[] = { + 0x49, 0x00, 0xfc, 0x00, 0xa3, 0x41, 0xcc, 0xcc, 0x63, 0x50, 0xcd, 0xcc, + 0x62, 0x00, 0x3c, 0x9b, 0x02, 0x46, 0x9f, 0x45, 0x2b, 0x25, 0x00, 0x0c, + 0xa9, 0x00, 0xfc, 0x00, 0xa6, 0x41, 0xcc, 0xcc, 0xc6, 0x50, 0xcd, 0xcc, + 0xc5, 0x00, 0x3c, 0x9b, 0x04, 0x31, 0x01, 0x00, 0x05, 0x46, 0xdb, 0x26, + 0xca, 0x06, 0x49, 0x00, 0xfc, 0x00, 0xc2, 0x00, 0x3c, 0x9b, 0x02, 0x46, + 0x2b, 0x25, 0xab, 0x05, 0x03, 0x40, 0x10, 0x00, 0x68, 0x00, 0x50, 0x3b, + 0xe7, 0x40, 0xf3, 0xff, 0xa8, 0x06, 0x49, 0x00, 0xfc, 0x00, 0xc2, 0x00, + 0x3c, 0x9b, 0x02, 0x46, 0x2b, 0x25, 0xab, 0x05, 0x43, 0x40, 0xf4, 0xff, + 0x68, 0x00, 0x50, 0x3b, 0x68, 0x00, 0x50, 0x1b, 0xf2, 0xad, 0xa8, 0x06, + 0xbf, 0x45, 0x00, 0x0c, 0xa4, 0x0c, 0xb9, 0x41, 0x01, 0x80, 0xa4, 0x41, + 0x09, 0x80, 0x22, 0xef, 0x39, 0x33, 0xbd, 0xa4, 0x99, 0x45, 0x84, 0x30, + 0xe8, 0x01, 0x00, 0x0c, 0xf5, 0x4f, 0xa5, 0x41, 0x06, 0x80, 0xa5, 0x30, + 0x2c, 0xae, 0x58, 0x09, 0x44, 0x45, 0xb0, 0x41, 0x09, 0x80, 0x22, 0x27, + 0x2c, 0x07, 0x6a, 0x27, 0xa2, 0x41, 0x01, 0x80, 0x90, 0x30, 0x90, 0xfb, + 0x42, 0x30, 0xbd, 0xa4, 0xe2, 0x45, 0x68, 0x6f, 0xa3, 0x41, 0x59, 0x00, + 0x50, 0x30, 0x90, 0xfb, 0x83, 0x30, 0xf8, 0x08, 0x63, 0x50, 0x58, 0xf3, + 0x62, 0xf8, 0xb4, 0x02, 0x60, 0x50, 0x40, 0x9c, 0x62, 0xf8, 0xb8, 0x02, + 0x60, 0x30, 0x8c, 0x0a, 0x62, 0xf8, 0xc0, 0x02, 0x60, 0x30, 0x88, 0x08, + 0x82, 0xf8, 0xb0, 0x02, 0x02, 0xf8, 0xbc, 0x02, 0x62, 0xf8, 0x04, 0x03, + 0x04, 0x45, 0x06, 0x47, 0x5c, 0xfc, 0x28, 0x82, 0xa3, 0x41, 0x02, 0x01, + 0x63, 0x30, 0x63, 0x08, 0x62, 0x60, 0x07, 0x80, 0x62, 0x60, 0x04, 0x90, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x90, 0xfb, 0xa3, 0x41, 0x13, 0x80, + 0x43, 0xf8, 0x8c, 0x1e, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x78, 0xfb, + 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x79, 0xfb, 0xa2, 0x41, 0x09, 0x80, + 0xb9, 0x41, 0x09, 0x80, 0x02, 0x18, 0x7a, 0xfb, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0x18, 0x7b, 0xfb, 0x39, 0x33, 0x89, 0xc0, 0xa2, 0x41, 0x09, 0x80, + 0x99, 0x45, 0x02, 0xf8, 0x88, 0xfb, 0x00, 0x0c, 0xb9, 0x41, 0x09, 0x80, + 0x39, 0x33, 0xe9, 0xc0, 0xb9, 0x45, 0x00, 0x0c, 0xe9, 0x4f, 0xfd, 0x22, + 0x10, 0xd0, 0x44, 0x62, 0x17, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x24, 0x0e, + 0x44, 0x62, 0x14, 0x10, 0xa0, 0x30, 0xd0, 0x00, 0x42, 0x30, 0x51, 0x1e, + 0x52, 0x32, 0x18, 0x00, 0xe2, 0x45, 0x92, 0x0c, 0x02, 0x94, 0x65, 0x00, + 0x02, 0x0e, 0x02, 0x60, 0x0b, 0x80, 0x02, 0x60, 0x08, 0x90, 0x42, 0x62, + 0x03, 0x80, 0x42, 0x62, 0x00, 0x90, 0x01, 0xed, 0x50, 0x60, 0x07, 0x80, + 0x50, 0x60, 0x04, 0x90, 0x04, 0xed, 0x50, 0x60, 0x0f, 0x80, 0x50, 0x60, + 0x0c, 0x90, 0x51, 0x60, 0x17, 0x00, 0x91, 0x32, 0x18, 0x00, 0xb3, 0x41, + 0x01, 0x80, 0x51, 0x60, 0x14, 0x10, 0xb4, 0x0c, 0x0c, 0x6e, 0x26, 0x6d, + 0x50, 0x60, 0x13, 0x80, 0x50, 0x60, 0x10, 0x90, 0xd1, 0x60, 0x17, 0x00, + 0x73, 0x32, 0xbd, 0xa4, 0xb5, 0x41, 0x09, 0x80, 0xd3, 0x45, 0xd1, 0x60, + 0x14, 0x10, 0x51, 0x60, 0x17, 0x00, 0x75, 0xfc, 0xa0, 0xfe, 0x51, 0x60, + 0x14, 0x10, 0xb1, 0x2d, 0x50, 0x60, 0x17, 0x80, 0xa7, 0x8d, 0x50, 0x60, + 0x14, 0x90, 0xb6, 0x41, 0x09, 0x80, 0xd6, 0x32, 0x34, 0x00, 0xc0, 0x30, + 0x8f, 0x01, 0xa0, 0x0c, 0x96, 0x0c, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0x51, 0xa8, 0xe2, 0x45, 0x00, 0x0c, 0xd1, 0x60, 0x17, 0x00, 0xb4, 0x0c, + 0x96, 0x0c, 0xd3, 0x45, 0xd1, 0x60, 0x14, 0x10, 0x55, 0xfc, 0xa0, 0xfe, + 0xb2, 0x0c, 0x20, 0x6d, 0x55, 0xf8, 0xa0, 0xfe, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x4f, 0x23, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0xfd, 0x22, + 0x10, 0x50, 0x0c, 0x47, 0xb6, 0x41, 0x09, 0x80, 0xd6, 0x32, 0xa4, 0xfe, + 0x96, 0x0c, 0xc0, 0x30, 0x8f, 0x01, 0xdb, 0xcf, 0xa0, 0x0c, 0xf3, 0xcf, + 0x7f, 0xed, 0x00, 0x0c, 0xf1, 0x4f, 0x64, 0x45, 0x44, 0x62, 0x0b, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x04, 0x0e, 0x44, 0x62, 0x08, 0x10, 0xa0, 0x30, + 0xd0, 0x00, 0x42, 0x30, 0x51, 0x1e, 0x52, 0x32, 0x18, 0x00, 0xe2, 0x45, + 0x92, 0x0c, 0xd0, 0x60, 0x0b, 0x00, 0x22, 0x0e, 0x2c, 0x6e, 0xd0, 0x60, + 0x08, 0x10, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xbd, 0xa4, 0xe2, 0x45, + 0x86, 0x6e, 0x50, 0x60, 0x0b, 0x00, 0xd2, 0x86, 0x50, 0x60, 0x08, 0x10, + 0x51, 0x60, 0x17, 0x80, 0x51, 0x60, 0x14, 0x90, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xf5, 0x22, 0xe2, 0x45, 0x1b, 0xef, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x3f, 0x1e, 0xe2, 0x45, 0x91, 0x0c, 0x40, 0x0c, 0x24, 0x45, + 0x08, 0x47, 0x00, 0x0c, 0xe5, 0x4f, 0x79, 0x45, 0x44, 0x14, 0x79, 0x00, + 0x14, 0x8d, 0x04, 0x0e, 0x84, 0xfc, 0x74, 0x00, 0x06, 0x8e, 0x01, 0xed, + 0xc0, 0x69, 0x43, 0x94, 0x81, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x10, 0xf8, + 0x74, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xd1, 0x1c, 0xe2, 0x45, + 0x90, 0x0c, 0x39, 0x45, 0x0e, 0x47, 0x30, 0x22, 0x6c, 0x10, 0xd0, 0xed, + 0x52, 0x34, 0x00, 0x00, 0x42, 0xd0, 0xfc, 0x00, 0x62, 0x94, 0x62, 0x00, + 0x60, 0x30, 0x80, 0x00, 0x62, 0x94, 0x5e, 0x00, 0x81, 0xed, 0x64, 0xfe, + 0x74, 0x00, 0x53, 0xfc, 0x00, 0x00, 0x62, 0x94, 0x68, 0x00, 0x89, 0x6e, + 0x2e, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x88, 0x03, 0x62, 0x60, + 0x23, 0x00, 0xd3, 0x14, 0x52, 0x00, 0xb3, 0x30, 0x53, 0x00, 0x62, 0x60, + 0x20, 0x10, 0xe6, 0x05, 0x62, 0x60, 0x23, 0x80, 0x62, 0x60, 0x20, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xbf, 0x22, 0xe2, 0x45, 0x86, 0x0c, + 0x52, 0x34, 0x00, 0x00, 0x88, 0xed, 0x42, 0xd0, 0x0c, 0x00, 0x62, 0x94, + 0xc4, 0xff, 0x20, 0x02, 0x0c, 0xd8, 0xa2, 0x41, 0x00, 0x80, 0x51, 0xb4, + 0xbe, 0xff, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x31, 0x14, 0xc2, 0x45, + 0x90, 0xfc, 0x6c, 0x00, 0xb8, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0x73, 0xfc, + 0x38, 0x00, 0x42, 0x30, 0x88, 0x03, 0xc2, 0x60, 0x23, 0x00, 0x83, 0x60, + 0x17, 0x00, 0xa3, 0x30, 0x39, 0x00, 0xc2, 0x60, 0x20, 0x10, 0x83, 0x60, + 0x14, 0x10, 0x4c, 0x06, 0x82, 0x60, 0x23, 0x80, 0x82, 0x60, 0x20, 0x90, + 0x83, 0x60, 0x17, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xbf, 0x22, + 0x83, 0x60, 0x14, 0x10, 0xe2, 0x45, 0x4d, 0x2e, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x3f, 0x1e, 0xc2, 0x45, 0x93, 0xfc, 0x38, 0x00, 0xc6, 0xcf, + 0x52, 0x34, 0x00, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x88, 0x86, 0x42, 0x30, + 0xe9, 0x1c, 0xe2, 0x45, 0x01, 0xef, 0xbc, 0xcf, 0x52, 0x34, 0x00, 0x00, + 0x42, 0x30, 0x31, 0x14, 0xe2, 0x45, 0x00, 0x0c, 0x7e, 0xcf, 0x10, 0xf8, + 0x74, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x88, 0x03, 0x62, 0x60, + 0x23, 0x00, 0xf3, 0xfc, 0x04, 0x00, 0xd3, 0x34, 0x16, 0x00, 0x62, 0x60, + 0x20, 0x10, 0x01, 0xee, 0xb0, 0x6d, 0x62, 0x60, 0x23, 0x80, 0x62, 0x60, + 0x20, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xbf, 0x22, 0xe4, 0xc8, + 0xc2, 0x45, 0xdd, 0x38, 0x14, 0x00, 0x98, 0xcf, 0x52, 0x34, 0x00, 0x00, + 0xbf, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xb9, 0x41, 0x02, 0x80, + 0x39, 0x33, 0x45, 0xc7, 0x99, 0x45, 0x82, 0xfc, 0x44, 0x9a, 0x00, 0x0c, + 0x01, 0xed, 0x44, 0xb4, 0x16, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xac, 0x9b, 0x62, 0x14, 0x17, 0x00, 0x83, 0x94, 0x0b, 0x00, + 0x00, 0x0c, 0x82, 0x18, 0x16, 0x00, 0x82, 0x18, 0x17, 0x00, 0x82, 0xf8, + 0x2c, 0x01, 0x82, 0xf8, 0x30, 0x01, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, + 0x40, 0x0c, 0x9f, 0x45, 0x7f, 0xed, 0x00, 0x0c, 0xf1, 0x4f, 0x55, 0x45, + 0x4f, 0x68, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x0b, 0x1f, 0x8c, 0x6c, + 0xe2, 0x45, 0x91, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x88, 0x86, 0x42, 0x30, + 0x71, 0x22, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x40, 0x16, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x70, 0xfc, 0x0c, 0x0b, 0x42, 0x30, 0xdd, 0x22, 0x50, 0xf8, + 0x90, 0x00, 0x01, 0xed, 0x09, 0xe9, 0x03, 0xf8, 0x88, 0x01, 0x00, 0x0e, + 0xa3, 0x41, 0x10, 0x80, 0x63, 0x30, 0x1d, 0x1f, 0xe3, 0x45, 0x91, 0x0c, + 0x50, 0x0c, 0x15, 0x45, 0x08, 0x47, 0xf6, 0xcf, 0x00, 0x32, 0xed, 0xff, + 0x44, 0xfc, 0x0c, 0x0b, 0x9f, 0x45, 0xa2, 0xf8, 0x88, 0x01, 0x00, 0x0c, + 0xc9, 0x4f, 0xa2, 0x41, 0x01, 0x80, 0xfb, 0xcb, 0x09, 0x6e, 0x58, 0xef, + 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, 0xa0, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0x30, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x34, 0xfb, + 0xa5, 0x41, 0x09, 0x80, 0x3c, 0xef, 0x4a, 0xc8, 0xa2, 0x41, 0x01, 0x80, + 0xa5, 0x30, 0x38, 0xfb, 0x17, 0x6e, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0x7d, 0xf8, 0x24, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x20, 0xef, 0xd8, 0xee, + 0x42, 0x30, 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0xfb, 0x4b, 0x1c, 0x47, + 0xa3, 0x41, 0x32, 0x00, 0xa2, 0x41, 0x01, 0xa5, 0xc3, 0x30, 0x00, 0x32, + 0xc2, 0xf8, 0x04, 0x3c, 0xa7, 0x41, 0x09, 0x80, 0xc7, 0xfc, 0xd8, 0x9b, + 0x60, 0x27, 0xc2, 0xf8, 0x04, 0x3c, 0xc7, 0xfc, 0xd8, 0x9b, 0xe6, 0x40, + 0xc8, 0x00, 0x39, 0x4f, 0x7d, 0x22, 0x80, 0xd1, 0x24, 0x0e, 0x61, 0x6a, + 0xe3, 0x30, 0x00, 0x33, 0x05, 0x0e, 0x40, 0x27, 0xa3, 0x30, 0x00, 0x34, + 0xe2, 0xf8, 0x04, 0x3c, 0xc2, 0xf8, 0x04, 0x3c, 0xa2, 0xf8, 0x04, 0x3c, + 0xa4, 0xfc, 0x0c, 0x0b, 0xc3, 0x30, 0x00, 0x35, 0x63, 0x30, 0x00, 0x36, + 0xd0, 0x26, 0xa2, 0xf8, 0x04, 0x3c, 0xc2, 0xf8, 0x04, 0x3c, 0x84, 0xfc, + 0x0c, 0x0b, 0xb2, 0x41, 0x09, 0x80, 0xc0, 0x30, 0x6c, 0x01, 0x84, 0xfc, + 0xe0, 0x00, 0xa0, 0x0c, 0x40, 0x26, 0x82, 0xf8, 0x04, 0x3c, 0x62, 0xf8, + 0x04, 0x3c, 0x72, 0xfc, 0xac, 0x9b, 0x09, 0x6e, 0x63, 0xfc, 0xe0, 0x00, + 0xb0, 0x25, 0x62, 0xf8, 0x04, 0x3c, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0x51, 0xa8, 0xe2, 0x45, 0x00, 0x0c, 0x11, 0x94, 0x7a, 0x00, 0x29, 0xca, + 0xb0, 0x41, 0x01, 0x80, 0x10, 0x32, 0xbd, 0xa4, 0xa2, 0x41, 0x09, 0x80, + 0x22, 0xfd, 0x58, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xfd, 0x5c, 0x9a, + 0xa2, 0x41, 0x09, 0x80, 0xe2, 0xfc, 0x60, 0x9a, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0x64, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x54, 0x9a, + 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, 0x74, 0x9a, 0x9d, 0x30, + 0x0c, 0x01, 0x7d, 0xf8, 0x08, 0x01, 0x3d, 0xf9, 0xfc, 0x00, 0x1d, 0xf9, + 0x00, 0x01, 0xfd, 0xf8, 0x04, 0x01, 0xd0, 0x45, 0x5d, 0xf8, 0xf8, 0x00, + 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, 0x78, 0x9a, 0xd0, 0x45, + 0x9d, 0x30, 0x10, 0x01, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, + 0x7c, 0x9a, 0xd0, 0x45, 0x9d, 0x30, 0x14, 0x01, 0xa5, 0x41, 0x09, 0x80, + 0xb2, 0x41, 0x09, 0x80, 0x24, 0xef, 0xa5, 0x30, 0x80, 0x9a, 0xd0, 0x45, + 0x9d, 0x30, 0x18, 0x01, 0xb2, 0x30, 0x5c, 0xbf, 0x9d, 0x30, 0x3c, 0x01, + 0x3c, 0xef, 0xd0, 0x45, 0x52, 0x32, 0x5c, 0xbf, 0x72, 0xfc, 0x3c, 0x00, + 0xa2, 0x41, 0xfa, 0x50, 0x42, 0x30, 0xfa, 0x50, 0x01, 0xee, 0x53, 0x44, + 0x43, 0x00, 0x18, 0x20, 0x97, 0x8c, 0x9d, 0xf8, 0x78, 0x01, 0xa2, 0x41, + 0x21, 0x00, 0x42, 0x30, 0x00, 0x21, 0xa3, 0x41, 0x01, 0xa5, 0x43, 0xf8, + 0x04, 0x3c, 0xa2, 0x41, 0x10, 0x80, 0xc0, 0x0c, 0xa0, 0x30, 0x6c, 0x01, + 0x42, 0x30, 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0x7d, 0x22, 0x80, 0x51, + 0x9f, 0x45, 0xc9, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc9, 0xc4, + 0xe2, 0x45, 0x00, 0x0c, 0x42, 0x40, 0xe3, 0xff, 0x7f, 0xed, 0xf2, 0xcf, + 0x00, 0x0c, 0xb2, 0xfc, 0xac, 0x9b, 0x1d, 0xfa, 0xf0, 0x00, 0xb0, 0x41, + 0x01, 0x80, 0x45, 0xfc, 0xe0, 0x00, 0xc0, 0x30, 0xc8, 0x00, 0x15, 0x6e, + 0x10, 0x32, 0xbd, 0xa4, 0xdc, 0x6e, 0xd0, 0x45, 0x5d, 0xf8, 0xf4, 0x00, + 0x7b, 0xcf, 0xa2, 0x41, 0x09, 0x80, 0x7c, 0xfc, 0xd4, 0x81, 0x7f, 0xed, + 0xb0, 0x6d, 0x9f, 0x45, 0x7c, 0xf8, 0xd4, 0x81, 0xe9, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, 0xeb, 0xcb, 0x81, 0xed, 0xa2, 0xfc, + 0x38, 0x02, 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, + 0x09, 0xc8, 0x64, 0x94, 0x15, 0x00, 0xdf, 0x6a, 0x42, 0xfc, 0x84, 0x01, + 0x83, 0xed, 0x62, 0x94, 0x05, 0x00, 0x40, 0x00, 0x8c, 0x10, 0x02, 0xad, + 0x01, 0xed, 0x49, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x13, 0xef, 0x98, 0xee, + 0x42, 0x30, 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0xeb, 0x4b, 0x0c, 0x47, + 0x65, 0xfc, 0x0c, 0x0b, 0x63, 0xfc, 0x88, 0x01, 0xe7, 0xcf, 0x62, 0xf8, + 0x88, 0x01, 0x00, 0x0c, 0xe1, 0x4f, 0x7b, 0x45, 0x04, 0x62, 0x0b, 0x00, + 0xa3, 0x41, 0xdc, 0x00, 0xa2, 0x41, 0x01, 0xa5, 0x04, 0x62, 0x08, 0x10, + 0x63, 0x50, 0x00, 0xba, 0x62, 0xf8, 0x04, 0x3c, 0x0f, 0x2c, 0xa3, 0x41, + 0x52, 0x00, 0x63, 0x30, 0x00, 0x52, 0x00, 0x27, 0xc2, 0xf8, 0x04, 0x3c, + 0xa5, 0x41, 0x09, 0x80, 0x62, 0xf8, 0x04, 0x3c, 0x65, 0xfc, 0xd8, 0x9b, + 0xb0, 0x25, 0x62, 0xf8, 0x04, 0x3c, 0x45, 0xfe, 0xd8, 0x9b, 0x12, 0x94, + 0x3e, 0x00, 0x24, 0x0e, 0x72, 0xfe, 0x04, 0x00, 0xa2, 0x41, 0x01, 0x80, + 0xa4, 0x41, 0x09, 0x80, 0xc0, 0x30, 0xc4, 0x0c, 0x84, 0x30, 0x68, 0xee, + 0x42, 0x30, 0xbd, 0xa4, 0xe2, 0x45, 0xb3, 0x0c, 0x50, 0xb0, 0x15, 0x00, + 0x23, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x54, 0xed, 0x02, 0x02, + 0x18, 0x81, 0xb0, 0x45, 0x51, 0x60, 0x17, 0x00, 0x51, 0x60, 0x14, 0x10, + 0x02, 0x94, 0x5a, 0x01, 0x42, 0xb0, 0x03, 0x00, 0x15, 0x8d, 0xa2, 0x41, + 0x10, 0x80, 0x73, 0x14, 0x94, 0x00, 0x01, 0xed, 0x43, 0xb4, 0x0e, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x93, 0xfc, 0x74, 0x0b, 0xa2, 0x41, 0x10, 0x80, + 0xc0, 0x0c, 0x42, 0x30, 0x5d, 0x18, 0xc2, 0x45, 0xb3, 0x30, 0x90, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x31, 0x14, 0xe2, 0x45, 0x91, 0x0c, + 0x40, 0x0c, 0x3b, 0x45, 0x10, 0x47, 0x5c, 0xfc, 0xd4, 0x81, 0x3b, 0x45, + 0x20, 0x6d, 0x5c, 0xf8, 0xd4, 0x81, 0x40, 0x0c, 0x10, 0x47, 0x7c, 0x14, + 0xf0, 0x81, 0x01, 0xed, 0x43, 0xb4, 0x07, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xdd, 0x1c, 0xc2, 0x45, 0x1c, 0x18, 0xf0, 0x81, 0x91, 0x60, + 0x17, 0x00, 0xb2, 0xfc, 0x04, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xd7, 0x22, 0xc2, 0x45, 0x91, 0x60, 0x14, 0x10, 0xb0, 0x41, 0x09, 0x80, + 0xa2, 0x41, 0x05, 0x80, 0xff, 0xee, 0x42, 0x30, 0xf1, 0x4b, 0xc2, 0x45, + 0x90, 0x30, 0xc4, 0x9b, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xb0, 0x9b, + 0xa3, 0x69, 0x03, 0xb4, 0x3d, 0x01, 0xbe, 0x6d, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0xf9, 0x4b, 0xc2, 0x45, 0x90, 0x30, 0xc4, 0x9b, 0xc0, 0xcf, + 0xa2, 0x41, 0x10, 0x80, 0xd2, 0xfc, 0x04, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0xb1, 0x0c, 0x42, 0x30, 0x6b, 0x22, 0xe2, 0x45, 0x08, 0xee, 0xb4, 0xcf, + 0xa2, 0x41, 0x10, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x4d, 0xc1, + 0xe2, 0x45, 0x91, 0x0c, 0xab, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0x51, 0x60, + 0x17, 0x00, 0x81, 0xed, 0x51, 0x60, 0x14, 0x10, 0x62, 0x94, 0xf6, 0x00, + 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xc7, 0x1d, 0xe2, 0x45, + 0x91, 0x0c, 0x9a, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x6b, 0x25, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x94, 0xbd, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x4d, 0x25, 0xe2, 0x45, 0x01, 0xee, + 0x89, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0xa5, 0x41, 0x00, 0x00, 0xa2, 0x41, + 0x03, 0x80, 0xa5, 0x30, 0x00, 0x00, 0x42, 0x30, 0xe1, 0x5b, 0xe2, 0x45, + 0x01, 0xee, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xbb, 0x1d, 0xe2, 0x45, + 0x91, 0x0c, 0x76, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0xb2, 0xfc, 0x04, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe3, 0x22, 0xe2, 0x45, 0x91, 0x0c, + 0x70, 0xcf, 0x40, 0x0c, 0x53, 0xfc, 0x0c, 0x0b, 0x42, 0x14, 0xe4, 0x00, + 0x02, 0xb4, 0x88, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x73, 0xfc, 0x10, 0x0b, + 0x91, 0x0c, 0x43, 0xfc, 0x88, 0x00, 0x20, 0x6d, 0x43, 0xf8, 0x88, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x01, 0x23, 0xc2, 0x45, 0xb2, 0xfc, + 0x04, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xb0, 0x9b, 0xa1, 0x69, + 0xb0, 0x6d, 0x50, 0xcf, 0xa1, 0xe9, 0x51, 0x60, 0x1b, 0x00, 0x83, 0xed, + 0x51, 0x60, 0x18, 0x10, 0x62, 0xb4, 0x44, 0xff, 0xa2, 0x41, 0x10, 0x80, + 0x32, 0xfd, 0x04, 0x00, 0x60, 0x0c, 0x40, 0x31, 0x01, 0x00, 0x09, 0xfd, + 0x14, 0x00, 0x60, 0x31, 0x02, 0x00, 0x43, 0x01, 0x10, 0x10, 0x02, 0x01, + 0x50, 0x12, 0x34, 0x8d, 0x43, 0x30, 0xd2, 0x02, 0x24, 0x25, 0x49, 0x00, + 0x50, 0x11, 0x21, 0x6a, 0xb1, 0x14, 0x1c, 0x00, 0x51, 0x14, 0x1d, 0x00, + 0xc4, 0x15, 0x49, 0x01, 0xc4, 0x14, 0x48, 0x01, 0xa4, 0x15, 0x4a, 0x01, + 0x91, 0x15, 0x1e, 0x00, 0xe4, 0x14, 0x4b, 0x01, 0xf1, 0x15, 0x1f, 0x00, + 0x6e, 0x44, 0xc2, 0x01, 0x10, 0x13, 0xc4, 0x14, 0x4c, 0x01, 0xd1, 0x15, + 0x20, 0x00, 0xd5, 0x44, 0xac, 0x01, 0x10, 0x63, 0xa4, 0x14, 0x4d, 0x01, + 0xb1, 0x15, 0x21, 0x00, 0x82, 0x01, 0x90, 0x12, 0xe7, 0x01, 0x10, 0x3b, + 0xd7, 0x44, 0xc6, 0x01, 0x10, 0x33, 0xd6, 0x44, 0xa5, 0x01, 0x10, 0x2b, + 0xd5, 0x44, 0x2d, 0x2d, 0x02, 0x94, 0x91, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0xb0, 0x6d, 0x63, 0x95, 0xfb, 0xfe, 0x43, 0x01, 0x10, 0x10, 0xc5, 0xcf, + 0x02, 0x01, 0x50, 0x12, 0x92, 0xfc, 0x04, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x00, 0x85, 0x42, 0x30, 0xef, 0x22, 0xe2, 0x45, 0xb1, 0x0c, 0xee, 0xce, + 0xa2, 0x41, 0x10, 0x80, 0x01, 0xed, 0xe8, 0xce, 0x53, 0x18, 0xaa, 0x0c, + 0xd2, 0xfc, 0x04, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x82, 0x84, 0x42, 0x30, + 0x89, 0x22, 0xe2, 0x45, 0x02, 0xee, 0xde, 0xce, 0xa2, 0x41, 0x10, 0x80, + 0xb2, 0xfc, 0x04, 0x00, 0x42, 0x30, 0x95, 0xd6, 0xe2, 0x45, 0x91, 0x0c, + 0x84, 0xcf, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x60, 0xbe, 0xa1, 0x69, 0xb0, 0x6d, 0xa1, 0xe9, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x4d, 0x25, 0xe2, 0x45, 0x80, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0xb0, 0x9b, 0xa3, 0x69, 0xbe, 0x6d, 0xbd, 0xce, 0xa3, 0xe9, + 0x53, 0x14, 0x94, 0x00, 0x02, 0xb4, 0xb8, 0xfe, 0x01, 0xed, 0x93, 0xfc, + 0x74, 0x0b, 0x53, 0x18, 0x94, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x69, 0x18, 0xe2, 0x45, 0x00, 0x0c, 0xae, 0xce, 0xa2, 0x41, 0x10, 0x80, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xc1, 0xc8, 0xe2, 0x45, 0x91, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, 0x42, 0xfc, 0x84, 0x01, + 0x02, 0xb4, 0xfd, 0xfe, 0x13, 0xef, 0xa2, 0x41, 0x10, 0x80, 0x98, 0xee, + 0x09, 0x6e, 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, + 0x42, 0x30, 0xf5, 0x22, 0xc2, 0x45, 0x1d, 0xf8, 0x24, 0x00, 0x8e, 0xce, + 0xa2, 0x41, 0x10, 0x80, 0xa4, 0x41, 0x09, 0x80, 0xa3, 0xe9, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0xcd, 0x5e, 0xc2, 0x45, 0x84, 0x30, 0xd0, 0x9b, + 0x02, 0x94, 0xb8, 0xfe, 0xa3, 0x41, 0x13, 0x80, 0x63, 0xfc, 0x1c, 0x63, + 0x00, 0x84, 0xe3, 0x45, 0x82, 0x0c, 0x73, 0xfc, 0x10, 0x0b, 0x43, 0xfc, + 0x78, 0x00, 0x20, 0x6d, 0xab, 0xce, 0x43, 0xf8, 0x78, 0x00, 0x42, 0x30, + 0xff, 0x15, 0xe2, 0x45, 0x00, 0x0c, 0x6c, 0xce, 0xa2, 0x41, 0x10, 0x80, + 0xd1, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x9c, 0xbd, 0x9d, 0x22, + 0x4c, 0xd0, 0x62, 0x60, 0x57, 0x00, 0x62, 0x60, 0x54, 0x10, 0x10, 0xc8, + 0x1d, 0x18, 0x44, 0x00, 0xb0, 0x6d, 0x62, 0x60, 0x57, 0x80, 0x62, 0x60, + 0x54, 0x90, 0x04, 0x62, 0x49, 0x00, 0x04, 0x62, 0x46, 0x10, 0x50, 0xb0, + 0x0c, 0x00, 0x04, 0xad, 0x25, 0x0e, 0x9d, 0x22, 0x4c, 0x50, 0x18, 0x47, + 0x64, 0x14, 0x14, 0x00, 0x51, 0xfc, 0x0c, 0x0b, 0xa4, 0x0c, 0xa1, 0x6f, + 0x62, 0xf8, 0x88, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x23, 0x6f, 0x42, 0x30, + 0x0d, 0x23, 0xe2, 0x45, 0x91, 0x0c, 0x28, 0xad, 0xbd, 0x14, 0x44, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x32, 0x89, 0x22, 0x50, 0x48, 0x00, 0x0e, + 0x50, 0x00, 0x90, 0x10, 0x21, 0x2d, 0x0b, 0xad, 0x60, 0x32, 0x02, 0x00, + 0x00, 0x6c, 0x70, 0x96, 0xdc, 0xff, 0x50, 0x48, 0x50, 0x00, 0x90, 0x10, + 0x21, 0x2d, 0xe2, 0x40, 0xf7, 0xff, 0x02, 0x85, 0x8d, 0x6e, 0x01, 0xee, + 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xca, + 0x0c, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, 0xd2, 0x45, 0x1d, 0x38, 0x3c, 0x00, + 0xe8, 0xcf, 0x00, 0x6c, 0xa2, 0x41, 0x04, 0x80, 0x08, 0x85, 0x91, 0x0c, + 0x42, 0x30, 0xe1, 0x06, 0xc2, 0x45, 0x1d, 0xf8, 0x10, 0x00, 0xd2, 0xcf, + 0xa2, 0x41, 0x10, 0x80, 0xf5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, + 0x58, 0xbf, 0x44, 0x45, 0xb0, 0x41, 0x09, 0x80, 0x10, 0x32, 0x9c, 0x93, + 0x44, 0x30, 0x20, 0x01, 0x90, 0xf8, 0x94, 0x06, 0x27, 0x8d, 0x50, 0xf8, + 0x98, 0x06, 0x44, 0x30, 0x60, 0x02, 0x50, 0xf8, 0x9c, 0x06, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0x59, 0x5e, 0xc2, 0x45, 0x84, 0x30, 0x3c, 0x08, + 0xa6, 0x6d, 0x70, 0xf8, 0xa0, 0x06, 0x50, 0xf8, 0xa4, 0x06, 0x82, 0xfc, + 0x2c, 0x01, 0x70, 0xfc, 0x9c, 0x06, 0x90, 0xf8, 0xa8, 0x06, 0x63, 0xfc, + 0x20, 0x04, 0x82, 0xfc, 0x0c, 0x02, 0x40, 0x0c, 0x63, 0x30, 0x1e, 0x00, + 0xc6, 0x05, 0x70, 0xf8, 0xac, 0x06, 0x92, 0xed, 0x70, 0xf8, 0xb0, 0x06, + 0x04, 0x45, 0x06, 0x47, 0x5c, 0xfc, 0xe4, 0x81, 0x20, 0x6d, 0xd7, 0xcf, + 0x5c, 0xf8, 0xe4, 0x81, 0xb9, 0x41, 0x10, 0x80, 0x39, 0x33, 0x47, 0x22, + 0x99, 0x45, 0xa0, 0x0c, 0xed, 0x4f, 0x66, 0x45, 0x44, 0x60, 0x0b, 0x00, + 0x83, 0xed, 0x44, 0x60, 0x08, 0x10, 0x62, 0x94, 0x3b, 0x01, 0x04, 0x0e, + 0x82, 0xed, 0x7c, 0xf8, 0xf4, 0x81, 0x5c, 0xf8, 0xf8, 0x81, 0xa5, 0x41, + 0x09, 0x80, 0xa2, 0x41, 0x04, 0x80, 0xa5, 0x30, 0xa8, 0xed, 0x06, 0xef, + 0x42, 0x30, 0x31, 0x26, 0xe2, 0x45, 0x09, 0x6e, 0xbc, 0xfc, 0x28, 0x82, + 0x45, 0x60, 0x87, 0x00, 0x45, 0x60, 0x84, 0x10, 0x2e, 0x6d, 0x42, 0xb0, + 0xfe, 0xff, 0x02, 0xb4, 0x15, 0x01, 0xb1, 0x41, 0x01, 0x80, 0x31, 0x32, + 0xbd, 0xa4, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xa1, 0xc6, 0xe2, 0x45, + 0x09, 0x6e, 0xf0, 0x14, 0x31, 0x00, 0xd0, 0x14, 0x32, 0x00, 0xb0, 0x14, + 0x33, 0x00, 0x90, 0x14, 0x34, 0x00, 0x70, 0x14, 0x36, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0x68, 0x9a, 0xa1, 0x8b, 0x22, 0x8b, 0xa3, 0x8a, + 0x24, 0x8a, 0xa6, 0x89, 0x70, 0x60, 0x3a, 0x00, 0x70, 0x60, 0x37, 0x10, + 0x62, 0x60, 0x0a, 0x80, 0x62, 0x60, 0x07, 0x90, 0x50, 0x60, 0x0f, 0x00, + 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, 0x0c, 0x10, 0x43, 0xf8, 0x54, 0x9a, + 0x50, 0x60, 0x13, 0x00, 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, 0x10, 0x10, + 0x43, 0xf8, 0x58, 0x9a, 0x50, 0x60, 0x17, 0x00, 0xa3, 0x41, 0x09, 0x80, + 0x50, 0x60, 0x14, 0x10, 0x43, 0xf8, 0x5c, 0x9a, 0x50, 0x60, 0x1b, 0x00, + 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, 0x18, 0x10, 0x43, 0xf8, 0x60, 0x9a, + 0x50, 0x60, 0x1f, 0x00, 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, 0x1c, 0x10, + 0x43, 0xf8, 0x64, 0x9a, 0x50, 0x60, 0x65, 0x00, 0xa3, 0x41, 0x09, 0x80, + 0x50, 0x60, 0x62, 0x10, 0x43, 0xf8, 0x88, 0xfb, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x05, 0x25, 0xc2, 0x45, 0xb2, 0x41, 0x09, 0x80, 0x52, 0xfc, + 0xac, 0x9b, 0xa3, 0x41, 0x01, 0xa5, 0xa4, 0x41, 0x09, 0x80, 0x02, 0xf8, + 0xe8, 0x00, 0x50, 0x60, 0x23, 0x00, 0x04, 0xef, 0xb0, 0x30, 0x24, 0x00, + 0x50, 0x60, 0x20, 0x10, 0x84, 0x30, 0x74, 0x9a, 0x20, 0x25, 0x43, 0xf8, + 0x04, 0x3c, 0x50, 0x60, 0x23, 0x00, 0x72, 0xfc, 0xac, 0x9b, 0x50, 0x60, + 0x20, 0x10, 0xd1, 0x45, 0x43, 0xf8, 0xe0, 0x00, 0xa4, 0x41, 0x09, 0x80, + 0x04, 0xef, 0xb0, 0x30, 0x28, 0x00, 0xd1, 0x45, 0x84, 0x30, 0x78, 0x9a, + 0xa4, 0x41, 0x09, 0x80, 0x04, 0xef, 0xb0, 0x30, 0x2c, 0x00, 0xd1, 0x45, + 0x84, 0x30, 0x7c, 0x9a, 0xa4, 0x41, 0x09, 0x80, 0xb0, 0x30, 0x3b, 0x00, + 0x24, 0xef, 0xd1, 0x45, 0x84, 0x30, 0x80, 0x9a, 0xb2, 0xfc, 0xac, 0x9b, + 0x45, 0xfc, 0x38, 0x02, 0xaf, 0x69, 0x43, 0x30, 0x40, 0x0a, 0x63, 0x30, + 0xd0, 0x0a, 0x20, 0xe9, 0x21, 0xe9, 0x24, 0xa8, 0x26, 0x6d, 0x43, 0xb4, + 0xfa, 0xff, 0x00, 0x0c, 0x01, 0xed, 0x45, 0x18, 0xe4, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0xbf, 0x1c, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x90, 0x30, 0x60, 0x00, 0x42, 0x30, 0x47, 0x22, 0xe2, 0x45, + 0xa0, 0x0c, 0x30, 0x16, 0x66, 0x00, 0x30, 0x17, 0x67, 0x00, 0x10, 0x17, + 0x68, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xf0, 0x15, 0x69, 0x00, 0x22, 0x1a, + 0x78, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xd0, 0x15, 0x6a, 0x00, 0x22, 0x1b, + 0x79, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xb0, 0x15, 0x6b, 0x00, 0x02, 0x1b, + 0x7a, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x90, 0x15, 0x6c, 0x00, 0xe2, 0x19, + 0x7b, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x70, 0x15, 0x6d, 0x00, 0xc2, 0x19, + 0x7c, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x50, 0x15, 0x6e, 0x00, 0xa2, 0x19, + 0x7d, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x30, 0x15, 0x6f, 0x00, 0x82, 0x19, + 0x7e, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x10, 0x15, 0x70, 0x00, 0x62, 0x19, + 0x7f, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xf0, 0x14, 0x71, 0x00, 0x42, 0x19, + 0x80, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xd0, 0x14, 0x72, 0x00, 0x22, 0x19, + 0x81, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xb0, 0x14, 0x73, 0x00, 0x02, 0x19, + 0x82, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x90, 0x14, 0x74, 0x00, 0xe2, 0x18, + 0x83, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x70, 0x14, 0x75, 0x00, 0xc2, 0x18, + 0x84, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x18, 0x85, 0xfb, 0xa2, 0x41, + 0x09, 0x80, 0x82, 0x18, 0x86, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x18, + 0x87, 0xfb, 0x40, 0x0c, 0x26, 0x45, 0x0a, 0x47, 0x06, 0xef, 0xa5, 0x30, + 0x84, 0x00, 0x31, 0x32, 0xbd, 0xa4, 0xf1, 0x45, 0x09, 0x6e, 0xe9, 0xce, + 0xa2, 0x41, 0x04, 0x80, 0x01, 0xed, 0x5c, 0xf8, 0xf4, 0x81, 0xc7, 0xce, + 0x5c, 0xf8, 0xf8, 0x81, 0xa4, 0x41, 0x09, 0x80, 0xd0, 0x2f, 0x20, 0xaf, + 0x44, 0xfc, 0xac, 0x9b, 0xc2, 0x14, 0x16, 0x00, 0x62, 0xfc, 0x1c, 0x01, + 0x7f, 0xed, 0x45, 0x94, 0x1f, 0x00, 0x00, 0x0c, 0x9f, 0x8f, 0x01, 0xed, + 0x36, 0x2d, 0x37, 0xad, 0xa5, 0xd0, 0x7f, 0x00, 0x38, 0x2d, 0x35, 0xad, + 0x46, 0x70, 0x01, 0x00, 0x3c, 0x2d, 0x2f, 0xad, 0xb0, 0x2d, 0xbd, 0x8d, + 0x40, 0x0c, 0x45, 0x90, 0x03, 0x00, 0xa6, 0x70, 0x01, 0x00, 0x9f, 0x45, + 0xa0, 0x00, 0x18, 0x10, 0xc2, 0x14, 0x18, 0x01, 0x62, 0xfc, 0x04, 0x01, + 0x7f, 0xed, 0x45, 0xb4, 0xe3, 0xff, 0x00, 0x0c, 0x9f, 0x45, 0x01, 0xed, + 0x84, 0xfc, 0xac, 0x9b, 0x84, 0xfc, 0xf0, 0x00, 0x44, 0x94, 0x26, 0x00, + 0x5e, 0x6d, 0x45, 0x30, 0xfa, 0xff, 0x82, 0xb0, 0x1f, 0x00, 0x17, 0x8e, + 0x30, 0xee, 0xa4, 0x41, 0x04, 0x40, 0x84, 0x30, 0x49, 0x10, 0x82, 0x00, + 0x50, 0x20, 0x84, 0x00, 0x2c, 0x00, 0x10, 0x8e, 0x01, 0xed, 0xb6, 0x2d, + 0x9f, 0x45, 0x60, 0x00, 0x18, 0x10, 0x46, 0x70, 0x01, 0x00, 0xa5, 0x90, + 0x08, 0x00, 0x40, 0x00, 0x18, 0x28, 0x9f, 0x45, 0x45, 0x0c, 0x85, 0x94, + 0xf2, 0xff, 0x01, 0xed, 0xa5, 0x70, 0x36, 0x00, 0xee, 0xcf, 0x45, 0xb0, + 0x01, 0x00, 0xbf, 0x45, 0x42, 0xb0, 0x02, 0x00, 0x68, 0xad, 0x01, 0xed, + 0x37, 0xed, 0x45, 0x94, 0xe4, 0xff, 0x01, 0xed, 0x0b, 0xed, 0x45, 0xb4, + 0xd0, 0xff, 0x01, 0xed, 0xdf, 0xcf, 0xb6, 0x2d, 0xf5, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, 0x44, 0x45, 0x42, 0xfc, 0x38, 0x02, + 0x2f, 0x68, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xad, 0x22, 0xc2, 0x45, + 0x10, 0x18, 0xae, 0x0c, 0xa2, 0x40, 0x08, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xd1, 0x25, 0xe2, 0x45, 0x90, 0x0c, 0x42, 0x00, 0x80, 0xf8, + 0x04, 0x45, 0x06, 0x47, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x30, 0xa4, 0x9a, + 0x82, 0x18, 0xa4, 0x9a, 0xb1, 0x8a, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, + 0xf1, 0x4f, 0x55, 0x45, 0xb1, 0x41, 0x09, 0x80, 0x51, 0xfc, 0xac, 0x9b, + 0x81, 0xed, 0xc2, 0x14, 0xe4, 0x00, 0x66, 0xb4, 0x75, 0x00, 0x04, 0x0e, + 0xa2, 0x69, 0x7f, 0xee, 0x83, 0x94, 0x58, 0x00, 0xc5, 0x0c, 0x60, 0x30, + 0x80, 0xff, 0x70, 0x18, 0x54, 0x00, 0xa2, 0x69, 0x80, 0x30, 0x80, 0xff, + 0xb0, 0x14, 0x58, 0x00, 0xdc, 0x44, 0x70, 0x18, 0x54, 0x00, 0x62, 0x14, + 0x16, 0x00, 0x70, 0x18, 0x64, 0x00, 0x62, 0xfc, 0x28, 0x01, 0x70, 0x18, + 0x69, 0x00, 0x62, 0xfc, 0x24, 0x01, 0x70, 0x18, 0x68, 0x00, 0x22, 0x6a, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xb3, 0x25, 0xe2, 0x45, 0x00, 0x0c, + 0x51, 0xfc, 0xac, 0x9b, 0x81, 0xed, 0x70, 0x18, 0x47, 0x00, 0x70, 0x18, + 0x50, 0x00, 0x82, 0xfc, 0x1c, 0x01, 0xa3, 0x41, 0x09, 0x80, 0xc3, 0x30, + 0xa4, 0x9a, 0x90, 0x18, 0x58, 0x00, 0xa2, 0xfc, 0x20, 0x01, 0x83, 0x14, + 0xa4, 0x9a, 0x61, 0x09, 0xa3, 0x41, 0x09, 0x80, 0x63, 0x14, 0x8e, 0xfb, + 0x90, 0x18, 0x5c, 0x00, 0x50, 0x18, 0x60, 0x00, 0xb0, 0x18, 0x4c, 0x00, + 0x01, 0xee, 0x10, 0x60, 0x46, 0x80, 0x10, 0x60, 0x43, 0x90, 0x83, 0xb4, + 0x11, 0x00, 0x40, 0x0c, 0xa4, 0x41, 0x09, 0x80, 0xa4, 0x14, 0x8c, 0xfb, + 0xa4, 0x41, 0x09, 0x80, 0x84, 0x14, 0x8d, 0xfb, 0x70, 0x60, 0x46, 0x80, + 0x70, 0x60, 0x43, 0x90, 0x90, 0x18, 0x68, 0x00, 0xb0, 0x18, 0x69, 0x00, + 0x15, 0x45, 0x08, 0x47, 0x21, 0x6a, 0x64, 0x94, 0x18, 0x00, 0x37, 0xee, + 0x10, 0x18, 0x54, 0x00, 0xa1, 0x69, 0x83, 0x94, 0x0b, 0x00, 0xb2, 0x25, + 0x70, 0x18, 0x54, 0x00, 0x81, 0xed, 0x70, 0x18, 0x64, 0x00, 0x10, 0x18, + 0x68, 0x00, 0xb9, 0xcf, 0x10, 0x18, 0x69, 0x00, 0x8b, 0xed, 0xf6, 0xcf, + 0x70, 0x18, 0x54, 0x00, 0xe5, 0xcf, 0x40, 0x30, 0xb0, 0xff, 0x7c, 0xfc, + 0xd4, 0x81, 0x40, 0x30, 0xa6, 0xff, 0xb0, 0x6d, 0xdd, 0xcf, 0x7c, 0xf8, + 0xd4, 0x81, 0x00, 0x0c, 0xe5, 0x4f, 0x3d, 0x23, 0x10, 0xd0, 0x25, 0x0e, + 0x71, 0x02, 0x00, 0x08, 0x33, 0x02, 0x50, 0xb1, 0x44, 0x0e, 0xd6, 0x02, + 0x00, 0x10, 0x84, 0x32, 0xb8, 0x00, 0xa2, 0x41, 0x05, 0x80, 0xd2, 0x02, + 0x50, 0xa9, 0xff, 0xee, 0x42, 0x30, 0xf1, 0x4b, 0xe2, 0x45, 0x94, 0x0c, + 0xf5, 0xfe, 0x40, 0x0a, 0xd6, 0x32, 0x40, 0x0a, 0xd2, 0x02, 0x50, 0xb1, + 0xf6, 0x96, 0xc9, 0x00, 0xa2, 0x41, 0x05, 0x80, 0x17, 0x94, 0xc5, 0x00, + 0xa0, 0x30, 0xd0, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x51, 0x1e, + 0xc2, 0x45, 0x80, 0x30, 0x12, 0x01, 0x02, 0x94, 0xc1, 0x00, 0x02, 0x0e, + 0x40, 0x30, 0x06, 0x01, 0x84, 0xed, 0xd0, 0x33, 0x0c, 0x00, 0x01, 0xe9, + 0xd0, 0xfb, 0x08, 0x00, 0x70, 0x60, 0x17, 0x80, 0x70, 0x60, 0x14, 0x90, + 0x50, 0x60, 0x0f, 0x80, 0x50, 0x60, 0x0c, 0x90, 0x10, 0x18, 0x20, 0x00, + 0x10, 0x18, 0x21, 0x00, 0x10, 0x18, 0x4a, 0x00, 0x30, 0x62, 0x25, 0x80, + 0x30, 0x62, 0x22, 0x90, 0x75, 0x34, 0x48, 0x0a, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0x74, 0xfb, 0x70, 0x60, 0x29, 0x80, 0x70, 0x60, 0x26, 0x90, + 0xb5, 0x41, 0x09, 0x80, 0x10, 0x18, 0x76, 0x00, 0x50, 0x60, 0x4e, 0x80, + 0x50, 0x60, 0x4b, 0x90, 0x55, 0xfc, 0xac, 0x9b, 0x42, 0xfc, 0x1c, 0x01, + 0x28, 0x2d, 0x02, 0xb4, 0x74, 0x00, 0x01, 0xed, 0xb7, 0xfc, 0x70, 0x00, + 0xa2, 0x41, 0x01, 0x80, 0x1a, 0xef, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0x90, 0x30, 0x7e, 0x00, 0x1a, 0xed, 0x50, 0x60, 0x7b, 0x80, 0x50, 0x60, + 0x78, 0x90, 0xa2, 0x41, 0x09, 0x80, 0xb2, 0x0c, 0x42, 0x30, 0x15, 0xd0, + 0xe2, 0x45, 0x9e, 0x0c, 0x33, 0x02, 0x50, 0x11, 0x24, 0x25, 0x52, 0x00, + 0x50, 0x11, 0x82, 0xfc, 0x40, 0x0a, 0x96, 0x94, 0x28, 0x00, 0xc0, 0x6a, + 0x10, 0x61, 0x29, 0x00, 0x60, 0x0c, 0x05, 0xcc, 0x10, 0x61, 0x26, 0x10, + 0x20, 0xad, 0x85, 0x0c, 0xa6, 0x0c, 0xc4, 0x34, 0x48, 0x00, 0x36, 0x6d, + 0x22, 0x25, 0x20, 0x05, 0xe1, 0x27, 0xc2, 0x18, 0x12, 0x00, 0xe2, 0x18, + 0x13, 0x00, 0x84, 0xfc, 0x70, 0x00, 0x43, 0x30, 0x28, 0x00, 0x24, 0x25, + 0x20, 0x05, 0x84, 0x00, 0x2c, 0xc0, 0x82, 0x60, 0x15, 0x80, 0x82, 0x60, + 0x12, 0x90, 0xb0, 0x6d, 0x10, 0x18, 0x7c, 0x00, 0x68, 0x00, 0x90, 0x13, + 0xb6, 0xb4, 0xe0, 0xff, 0x50, 0x6b, 0xa2, 0x41, 0x13, 0x80, 0x42, 0xfc, + 0x1c, 0x63, 0x33, 0x02, 0x50, 0x89, 0x94, 0x24, 0x00, 0x84, 0x90, 0x0c, + 0xc2, 0x45, 0x32, 0x02, 0x50, 0x89, 0x51, 0x34, 0x48, 0x0a, 0x81, 0xed, + 0x62, 0x94, 0x1e, 0x00, 0x42, 0xb0, 0x02, 0x00, 0x0e, 0xad, 0x75, 0xfc, + 0xac, 0x9b, 0x92, 0xfc, 0x10, 0x0b, 0x44, 0xfc, 0x80, 0x00, 0x20, 0x6d, + 0x44, 0xf8, 0x80, 0x00, 0x43, 0xfc, 0x10, 0x02, 0x20, 0x6d, 0x43, 0xf8, + 0x10, 0x02, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xf9, 0x4b, 0xe2, 0x45, + 0x94, 0x0c, 0x40, 0x0c, 0x3d, 0x23, 0x10, 0x50, 0x0e, 0x47, 0x8c, 0xcf, + 0x50, 0x18, 0x76, 0x00, 0x92, 0xfc, 0x10, 0x0b, 0x75, 0xfc, 0xac, 0x9b, + 0x44, 0xfc, 0x7c, 0x00, 0x20, 0x6d, 0x44, 0xf8, 0x7c, 0x00, 0x43, 0xfc, + 0x0c, 0x02, 0x20, 0x6d, 0xe6, 0xcf, 0x43, 0xf8, 0x0c, 0x02, 0x42, 0x30, + 0xf9, 0x4b, 0xe2, 0x45, 0x94, 0x0c, 0xe6, 0xcf, 0x40, 0x30, 0xf6, 0xff, + 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xf9, 0x4b, 0xe2, 0x45, 0x94, 0x0c, + 0xdd, 0xcf, 0x40, 0x30, 0xf4, 0xff, 0x00, 0x0c, 0xdd, 0x4f, 0xbd, 0x22, + 0x30, 0xd0, 0xb4, 0x41, 0x09, 0x80, 0x54, 0xfc, 0xac, 0x9b, 0x64, 0x0e, + 0x45, 0x0e, 0x42, 0xfc, 0x38, 0x02, 0xff, 0xef, 0xc0, 0x0c, 0xaf, 0x68, + 0xa2, 0x41, 0x04, 0x80, 0xa0, 0xee, 0x80, 0x0c, 0x42, 0x30, 0x11, 0xb0, + 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0x09, 0xc8, + 0x0a, 0xc8, 0xc2, 0x45, 0x1d, 0x38, 0x2c, 0x00, 0x02, 0x94, 0x7d, 0x00, + 0x02, 0x0e, 0x72, 0x30, 0x00, 0x10, 0x7f, 0xed, 0x50, 0xfa, 0x64, 0x00, + 0x70, 0xf8, 0x68, 0x00, 0x50, 0xfa, 0x6c, 0x00, 0x50, 0xfa, 0x70, 0x00, + 0x5d, 0x18, 0x19, 0x00, 0x5d, 0x18, 0x18, 0x00, 0x5d, 0x18, 0x17, 0x00, + 0x5d, 0x18, 0x16, 0x00, 0x5d, 0x18, 0x15, 0x00, 0x5d, 0x18, 0x14, 0x00, + 0x14, 0x09, 0xc8, 0xed, 0xb2, 0x41, 0x10, 0x80, 0x5d, 0x18, 0x1a, 0x00, + 0x15, 0x09, 0x90, 0x0c, 0x9a, 0xee, 0x5d, 0x18, 0x1b, 0x00, 0x16, 0x09, + 0x52, 0x32, 0xb5, 0x23, 0x5d, 0x18, 0x1c, 0x00, 0x17, 0x09, 0x5d, 0x18, + 0x1d, 0x00, 0x18, 0x09, 0x5d, 0x18, 0x1e, 0x00, 0x19, 0x09, 0x7d, 0x18, + 0x20, 0x00, 0x5d, 0x18, 0x1f, 0x00, 0x0e, 0xed, 0x5d, 0x18, 0x21, 0x00, + 0x1d, 0xed, 0x5d, 0x18, 0x22, 0x00, 0x23, 0xed, 0x5d, 0x18, 0x23, 0x00, + 0x1f, 0xed, 0x5d, 0x18, 0x24, 0x00, 0x34, 0xed, 0x5d, 0x18, 0x25, 0x00, + 0x40, 0x30, 0x88, 0x00, 0xd2, 0x45, 0x5d, 0x38, 0x10, 0x00, 0x82, 0x0c, + 0xa2, 0x41, 0x01, 0x80, 0x1a, 0xef, 0x42, 0x30, 0xbd, 0xa4, 0xe2, 0x45, + 0x89, 0x6e, 0x54, 0xfc, 0xac, 0x9b, 0x90, 0x0c, 0xd2, 0x45, 0xa2, 0xfc, + 0x78, 0x01, 0x74, 0xfc, 0xac, 0x9b, 0x82, 0x0c, 0x40, 0x30, 0xa0, 0x0f, + 0x63, 0xfc, 0x78, 0x01, 0xc3, 0x90, 0xa1, 0x0f, 0xc3, 0x00, 0x18, 0x10, + 0xc2, 0x0c, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x51, 0xa8, 0xc2, 0x45, + 0xa0, 0x30, 0xab, 0x00, 0x93, 0x00, 0x00, 0x08, 0x64, 0x02, 0x50, 0x21, + 0x44, 0x26, 0x84, 0x30, 0x40, 0x0a, 0xa2, 0x41, 0x10, 0x80, 0xb0, 0x0c, + 0x42, 0x30, 0xcd, 0x23, 0xe2, 0x45, 0x42, 0x06, 0xa2, 0x41, 0x09, 0x80, + 0xe2, 0x86, 0x42, 0x30, 0x2d, 0xd1, 0xe2, 0x45, 0x00, 0x0c, 0x40, 0x0c, + 0xbd, 0x22, 0x30, 0x50, 0x12, 0x47, 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, 0x82, 0xee, 0x62, 0xfc, + 0xe8, 0x00, 0xa3, 0x94, 0x05, 0x00, 0x60, 0x00, 0x90, 0x13, 0x9f, 0x45, + 0x40, 0x00, 0xd0, 0x11, 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0xe5, 0xcb, + 0x42, 0x30, 0xc5, 0xf8, 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0x40, 0x0c, + 0x06, 0x47, 0x00, 0x0c, 0xa5, 0x41, 0x09, 0x80, 0x65, 0xfc, 0xac, 0x9b, + 0x40, 0x0c, 0x63, 0xfc, 0x28, 0x02, 0x64, 0x60, 0x05, 0x80, 0x64, 0x60, + 0x02, 0x90, 0x65, 0xfc, 0xac, 0x9b, 0xc3, 0xfc, 0x2c, 0x02, 0xc4, 0x60, + 0x09, 0x80, 0xc4, 0x60, 0x06, 0x90, 0xc3, 0xfc, 0x30, 0x02, 0xc4, 0x60, + 0x0d, 0x80, 0xc4, 0x60, 0x0a, 0x90, 0xc3, 0xfc, 0x34, 0x02, 0xc4, 0x60, + 0x11, 0x80, 0xc4, 0x60, 0x0e, 0x90, 0x63, 0xfc, 0x6c, 0x01, 0xc0, 0x89, + 0x65, 0xfc, 0xac, 0x9b, 0x63, 0xfc, 0x88, 0x01, 0x9f, 0x45, 0xc1, 0x89, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0xac, 0x9b, 0x40, 0x0c, 0x63, 0xfc, + 0x88, 0x01, 0x9f, 0x45, 0xc1, 0x89, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0xa0, 0x30, 0xd0, 0x00, 0x42, 0x30, 0x51, 0x1e, 0x44, 0x45, + 0xe2, 0x45, 0x26, 0xee, 0x3b, 0x8d, 0x02, 0x0e, 0x02, 0x60, 0x0b, 0x80, + 0x02, 0x60, 0x08, 0x90, 0x26, 0xed, 0x50, 0x60, 0x03, 0x80, 0x50, 0x60, + 0x00, 0x90, 0x01, 0xed, 0x50, 0x60, 0x07, 0x80, 0x50, 0x60, 0x04, 0x90, + 0x02, 0xed, 0x50, 0x60, 0x0f, 0x80, 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, + 0x0c, 0x90, 0x63, 0xfc, 0xac, 0x9b, 0x1a, 0xed, 0x50, 0x60, 0x13, 0x80, + 0x50, 0x60, 0x10, 0x90, 0x63, 0xfc, 0x84, 0x01, 0x43, 0x30, 0xfe, 0xff, + 0x42, 0xb0, 0x02, 0x00, 0x0d, 0xad, 0x04, 0xed, 0x43, 0x94, 0x06, 0x00, + 0xa2, 0x41, 0x02, 0x80, 0x8f, 0xad, 0x7f, 0xed, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0xd9, 0xf9, 0xe2, 0x45, 0x0a, 0x6e, 0xa2, 0x41, 0x10, 0x80, + 0xa6, 0xee, 0x42, 0x30, 0x4f, 0x23, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, + 0x04, 0x45, 0x06, 0x47, 0xfd, 0xcf, 0x7f, 0xed, 0xf5, 0x4f, 0xe5, 0xcb, + 0x44, 0x60, 0x0b, 0x00, 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0xac, 0x9b, + 0x44, 0x60, 0x08, 0x10, 0x43, 0xf8, 0x84, 0x01, 0x44, 0x60, 0x0f, 0x00, + 0x44, 0x60, 0x0c, 0x10, 0x82, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xb9, 0x22, 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0x40, 0x0c, 0x06, 0x47, + 0xf5, 0x4f, 0x9c, 0xfc, 0x28, 0x82, 0xa2, 0x41, 0x01, 0x80, 0xe5, 0xcb, + 0xc0, 0x30, 0x88, 0x13, 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, 0xa0, 0x0c, + 0xe5, 0x4b, 0x40, 0x0c, 0x06, 0x47, 0x00, 0x0c, 0xe1, 0x4f, 0xdd, 0x22, + 0x24, 0xd0, 0xc5, 0xfc, 0x10, 0x0b, 0x64, 0x60, 0x49, 0x00, 0x64, 0x0e, + 0x46, 0xfc, 0x88, 0x00, 0x64, 0x60, 0x46, 0x10, 0xa0, 0x0e, 0x20, 0x6d, + 0x46, 0xf8, 0x88, 0x00, 0x23, 0x0e, 0x45, 0xfc, 0x0c, 0x0b, 0xb2, 0x25, + 0x84, 0x14, 0x14, 0x00, 0x96, 0x05, 0xb4, 0x25, 0x65, 0x00, 0x50, 0xa1, + 0x82, 0xf8, 0x88, 0x01, 0x54, 0xfc, 0x40, 0x0a, 0x63, 0x30, 0x40, 0x0a, + 0xba, 0x04, 0x51, 0x94, 0x1f, 0x00, 0x20, 0x68, 0xb2, 0x41, 0x10, 0x80, + 0x03, 0xcc, 0x52, 0x32, 0x41, 0x13, 0x03, 0x0e, 0x74, 0x34, 0x48, 0x0a, + 0x82, 0x0c, 0xa2, 0x4e, 0xbe, 0x6d, 0x74, 0x38, 0x48, 0x0a, 0xa1, 0x69, + 0xa0, 0x6b, 0x21, 0xe8, 0x20, 0xe8, 0xf1, 0xe9, 0xb0, 0xeb, 0x02, 0xf8, + 0x70, 0x00, 0x02, 0xf8, 0x6c, 0x00, 0xd2, 0x45, 0x02, 0xf8, 0x64, 0x00, + 0x50, 0x0c, 0x11, 0xb6, 0xe8, 0xff, 0x80, 0x69, 0xb3, 0x02, 0x50, 0x99, + 0x53, 0x14, 0x15, 0x00, 0x9c, 0xfc, 0x24, 0x82, 0xd5, 0x0c, 0x5d, 0x18, + 0x18, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x8d, 0x6f, 0xa0, 0x0c, 0x84, 0x30, + 0xb8, 0x00, 0x04, 0xc8, 0x42, 0x30, 0xef, 0x1c, 0xc2, 0x45, 0x1d, 0xf8, + 0x14, 0x00, 0xdd, 0x22, 0x24, 0x50, 0x10, 0x47, 0xe9, 0x4f, 0xfd, 0x22, + 0x10, 0xd0, 0xc5, 0xfc, 0x10, 0x0b, 0x24, 0x0e, 0xb5, 0x41, 0x09, 0x80, + 0x46, 0xfc, 0x88, 0x00, 0x84, 0x60, 0x49, 0x00, 0x75, 0xfc, 0xac, 0x9b, + 0x20, 0x6d, 0x91, 0x60, 0x46, 0x10, 0x46, 0xf8, 0x88, 0x00, 0x43, 0xfc, + 0x18, 0x02, 0x7f, 0xef, 0x20, 0x6d, 0x43, 0xf8, 0x18, 0x02, 0x45, 0xfc, + 0x0c, 0x0b, 0xf1, 0x14, 0x14, 0x00, 0xe2, 0xf8, 0x88, 0x01, 0x43, 0xfc, + 0x74, 0x01, 0xc2, 0x94, 0x53, 0x00, 0x00, 0x0c, 0xc2, 0x40, 0x4d, 0x00, + 0x00, 0x0c, 0x02, 0xb4, 0x47, 0x00, 0x44, 0x02, 0x00, 0x08, 0x92, 0x00, + 0x50, 0x21, 0x44, 0x26, 0x85, 0x00, 0x50, 0xb1, 0x56, 0xfc, 0x40, 0x0a, + 0x84, 0x30, 0x40, 0x0a, 0x85, 0x00, 0x50, 0x91, 0x65, 0x0e, 0x52, 0x94, + 0x20, 0x00, 0x20, 0x68, 0xb4, 0x41, 0x10, 0x80, 0x03, 0xcc, 0x94, 0x32, + 0x41, 0x13, 0x03, 0x0e, 0x76, 0x34, 0x48, 0x0a, 0x82, 0x0c, 0xbe, 0x6d, + 0x76, 0x38, 0x48, 0x0a, 0xa1, 0x69, 0xa0, 0x6a, 0x21, 0xe8, 0x20, 0xe8, + 0xd1, 0xe9, 0xb0, 0xea, 0x02, 0xf8, 0x70, 0x00, 0x02, 0xf8, 0x6c, 0x00, + 0x02, 0xf8, 0x68, 0x00, 0xd4, 0x45, 0x02, 0xf8, 0x64, 0x00, 0x50, 0x0c, + 0x12, 0xb6, 0xe7, 0xff, 0x80, 0x69, 0xb1, 0x60, 0x49, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x37, 0x14, 0xb1, 0x60, 0x46, 0x10, 0x01, 0xef, + 0xe2, 0x45, 0x93, 0x0c, 0x55, 0xfc, 0xac, 0x9b, 0x62, 0xfc, 0x0c, 0x02, + 0x42, 0xfc, 0x18, 0x02, 0x43, 0x94, 0x18, 0x00, 0xa2, 0x41, 0x09, 0x80, + 0x13, 0xf8, 0x24, 0x00, 0xfd, 0x22, 0x10, 0x50, 0x0c, 0x47, 0x2e, 0x6d, + 0x43, 0xf8, 0x74, 0x01, 0x51, 0x60, 0x49, 0x00, 0xb9, 0x41, 0x09, 0x80, + 0x85, 0x0c, 0x51, 0x60, 0x46, 0x10, 0x39, 0x33, 0x2d, 0xd1, 0xfd, 0x22, + 0x10, 0x50, 0xa2, 0x0c, 0x99, 0x45, 0x19, 0x4c, 0xa2, 0x14, 0x64, 0xee, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xc1, 0x1d, 0xe2, 0x45, 0x01, 0xee, + 0x73, 0xfc, 0x10, 0x0b, 0x55, 0xfc, 0xac, 0x9b, 0x03, 0xf8, 0x7c, 0x00, + 0x02, 0xf8, 0x0c, 0x02, 0x73, 0xfc, 0x10, 0x0b, 0x03, 0xf8, 0x88, 0x00, + 0x02, 0xf8, 0x18, 0x02, 0xd5, 0xcf, 0x13, 0xf8, 0x24, 0x00, 0x00, 0x0c, + 0x13, 0xae, 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, 0xac, 0x9b, 0x64, 0xfc, + 0x1c, 0x01, 0xa3, 0xd0, 0x22, 0x00, 0x89, 0x8e, 0x40, 0x0c, 0x40, 0x30, + 0xdd, 0xff, 0x9a, 0x44, 0x64, 0xf8, 0x1c, 0x01, 0x9f, 0x45, 0x01, 0xed, + 0x7f, 0xed, 0xbf, 0x45, 0x01, 0xed, 0x44, 0x94, 0x17, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x02, 0xed, 0x44, 0xb4, 0xf6, 0xff, 0x00, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0x82, 0xfc, 0xac, 0x9b, 0x64, 0xfc, 0x1c, 0x01, 0xba, 0x2e, + 0xee, 0xae, 0x40, 0x0c, 0x60, 0x00, 0x4c, 0x08, 0x63, 0x50, 0x20, 0x00, + 0x01, 0xed, 0x9f, 0x45, 0x64, 0xf8, 0x1c, 0x01, 0x82, 0xfc, 0xac, 0x9b, + 0x64, 0xfc, 0x1c, 0x01, 0xb2, 0x2e, 0xdf, 0xae, 0x40, 0x0c, 0x60, 0x00, + 0x4c, 0x29, 0x63, 0x50, 0x02, 0x00, 0x01, 0xed, 0x9f, 0x45, 0x64, 0xf8, + 0x1c, 0x01, 0x00, 0x0c, 0x13, 0xae, 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, + 0xac, 0x9b, 0x64, 0xfc, 0x1c, 0x01, 0xa3, 0xd0, 0xd8, 0x00, 0x89, 0x8e, + 0x40, 0x0c, 0x40, 0x30, 0x27, 0xff, 0x9a, 0x44, 0x64, 0xf8, 0x1c, 0x01, + 0x9f, 0x45, 0x01, 0xed, 0x7f, 0xed, 0xbf, 0x45, 0x01, 0xed, 0x44, 0x94, + 0x24, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xed, 0x44, 0x94, 0x3f, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x44, 0x30, 0xfd, 0xff, 0x42, 0xd0, 0xfd, 0x00, + 0x28, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x04, 0xed, 0x44, 0xb4, 0xea, 0xff, + 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, 0xac, 0x9b, 0x64, 0xfc, + 0x1c, 0x01, 0xb0, 0x2e, 0xe2, 0xae, 0x40, 0x0c, 0x40, 0x30, 0xa7, 0xff, + 0x9a, 0x44, 0x63, 0x50, 0x80, 0x00, 0x01, 0xed, 0x9f, 0x45, 0x64, 0xf8, + 0x1c, 0x01, 0x82, 0xfc, 0xac, 0x9b, 0x64, 0xfc, 0x1c, 0x01, 0xb6, 0x2e, + 0xd2, 0xae, 0x40, 0x0c, 0x40, 0x30, 0x2f, 0xff, 0x9a, 0x44, 0x63, 0x50, + 0x08, 0x00, 0x01, 0xed, 0x9f, 0x45, 0x64, 0xf8, 0x1c, 0x01, 0x82, 0xfc, + 0xac, 0x9b, 0x64, 0xfc, 0x1c, 0x01, 0xbc, 0x2e, 0xc2, 0xae, 0x40, 0x0c, + 0x40, 0x30, 0x67, 0xff, 0x9a, 0x44, 0x63, 0x50, 0x40, 0x00, 0x01, 0xed, + 0x9f, 0x45, 0x64, 0xf8, 0x1c, 0x01, 0x82, 0xfc, 0xac, 0x9b, 0x64, 0xfc, + 0x1c, 0x01, 0xb8, 0x2e, 0x05, 0xb4, 0xb1, 0xff, 0x40, 0x0c, 0x40, 0x30, + 0x37, 0xff, 0x9a, 0x44, 0x63, 0x50, 0x10, 0x00, 0x01, 0xed, 0x9f, 0x45, + 0x64, 0xf8, 0x1c, 0x01, 0x0f, 0xae, 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, + 0xac, 0x9b, 0x64, 0xfc, 0x1c, 0x01, 0xb4, 0x2e, 0x8c, 0x8e, 0x40, 0x0c, + 0x60, 0x00, 0x8c, 0x10, 0x01, 0xed, 0x9f, 0x45, 0x64, 0xf8, 0x1c, 0x01, + 0x01, 0xed, 0x44, 0x94, 0x03, 0x00, 0x00, 0x0c, 0x7f, 0xed, 0xbf, 0x45, + 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, 0xac, 0x9b, 0x64, 0xfc, 0x1c, 0x01, + 0xb4, 0x2e, 0xf7, 0xae, 0x40, 0x0c, 0x63, 0x50, 0x04, 0x00, 0x01, 0xed, + 0x9f, 0x45, 0x64, 0xf8, 0x1c, 0x01, 0x00, 0x0c, 0xe4, 0x40, 0x15, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0xac, 0x9b, 0x43, 0x14, 0x17, 0x00, + 0x82, 0x00, 0x90, 0x13, 0xa2, 0x40, 0x0b, 0x00, 0x43, 0x14, 0x16, 0x00, + 0x82, 0x94, 0x05, 0x00, 0x00, 0x0c, 0x01, 0xed, 0x9f, 0x45, 0x83, 0x18, + 0x16, 0x00, 0x9f, 0x45, 0x40, 0x0c, 0x9f, 0x45, 0x7f, 0xed, 0x00, 0x0c, + 0x13, 0xae, 0x01, 0xed, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0xac, 0x9b, + 0x43, 0xfc, 0x20, 0x01, 0x25, 0xad, 0x83, 0xfc, 0x1c, 0x01, 0xc1, 0x2e, + 0xa0, 0x8e, 0x40, 0x0c, 0x80, 0x00, 0x0c, 0x00, 0x01, 0xed, 0x9f, 0x45, + 0x83, 0xf8, 0x1c, 0x01, 0x44, 0x94, 0x20, 0x00, 0x02, 0xed, 0x44, 0x94, + 0x39, 0x00, 0x03, 0xed, 0x44, 0xb4, 0x11, 0x00, 0x7f, 0xed, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0xfc, 0xac, 0x9b, 0x43, 0xfc, 0x1c, 0x01, 0x21, 0x2e, + 0xe4, 0x40, 0x24, 0x00, 0x83, 0xfc, 0x20, 0x01, 0x04, 0x8e, 0x40, 0x0c, + 0x9f, 0x45, 0x03, 0xf8, 0x20, 0x01, 0xbf, 0x45, 0x80, 0x00, 0x0c, 0x00, + 0x01, 0xed, 0x83, 0xf8, 0x1c, 0x01, 0x9f, 0x45, 0x03, 0xf8, 0x20, 0x01, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0xac, 0x9b, 0x43, 0xfc, 0x20, 0x01, + 0x82, 0x94, 0x25, 0x00, 0x00, 0x0c, 0xa3, 0xfc, 0x1c, 0x01, 0x83, 0xf8, + 0x20, 0x01, 0x01, 0xed, 0x85, 0x0c, 0x80, 0x00, 0x0c, 0x00, 0x9f, 0x45, + 0x83, 0xf8, 0x1c, 0x01, 0x42, 0x50, 0x01, 0x00, 0x43, 0xf8, 0x1c, 0x01, + 0x03, 0xf8, 0x20, 0x01, 0x9f, 0x45, 0x01, 0xed, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0xac, 0x9b, 0x43, 0xfc, 0x1c, 0x01, 0x21, 0x2e, 0xe4, 0x40, + 0xcb, 0xff, 0x40, 0x00, 0x0c, 0x00, 0x43, 0xf8, 0x1c, 0x01, 0x03, 0xf8, + 0x20, 0x01, 0x9f, 0x45, 0x01, 0xed, 0xa7, 0xcf, 0x83, 0xfc, 0x1c, 0x01, + 0x44, 0xb0, 0x02, 0x00, 0xe2, 0x40, 0x0f, 0x00, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xac, 0x9b, 0x62, 0xfc, 0x24, 0x01, 0x83, 0x94, 0x05, 0x00, + 0x00, 0x0c, 0x82, 0xf8, 0x24, 0x01, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, + 0x40, 0x0c, 0x9f, 0x45, 0x7f, 0xed, 0x00, 0x0c, 0x44, 0xb0, 0x02, 0x00, + 0xe2, 0x40, 0x0f, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, + 0x62, 0xfc, 0x28, 0x01, 0x83, 0x94, 0x05, 0x00, 0x00, 0x0c, 0x82, 0xf8, + 0x28, 0x01, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, 0x40, 0x0c, 0x9f, 0x45, + 0x7f, 0xed, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x04, 0x40, 0x22, 0x00, + 0x22, 0xfd, 0xac, 0x9b, 0x49, 0xfc, 0x08, 0x00, 0x82, 0x94, 0x1a, 0x00, + 0x60, 0x0c, 0xf5, 0x4f, 0xe5, 0xcb, 0x49, 0xfc, 0x38, 0x02, 0x04, 0x0d, + 0xa4, 0x50, 0x80, 0x00, 0x2f, 0x6a, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xf9, 0xce, 0xe2, 0x45, 0xc0, 0x0c, 0x07, 0x8d, 0x60, 0x0c, 0x7f, 0xed, + 0x81, 0xed, 0x49, 0xf8, 0x04, 0x00, 0x09, 0xf9, 0x08, 0x00, 0xe5, 0x4b, + 0x43, 0x0c, 0x06, 0x47, 0x9f, 0x45, 0x43, 0x0c, 0xfd, 0xcf, 0xff, 0xed, + 0xa2, 0x41, 0x09, 0x80, 0x22, 0xfd, 0xac, 0x9b, 0x04, 0x0d, 0x49, 0xfc, + 0x38, 0x02, 0x08, 0x40, 0x15, 0x00, 0x2f, 0x6a, 0xf5, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0xc0, 0x0c, 0x42, 0x30, 0xf9, 0xce, 0xe5, 0xcb, 0xe2, 0x45, + 0xa8, 0x0c, 0x07, 0x8d, 0x60, 0x0c, 0x7f, 0xed, 0x81, 0xed, 0x09, 0xf9, + 0x04, 0x00, 0x49, 0xf8, 0x08, 0x00, 0xe5, 0x4b, 0x43, 0x0c, 0x06, 0x47, + 0xff, 0xed, 0x9f, 0x45, 0x43, 0x0c, 0x00, 0x0c, 0x05, 0x8f, 0xb9, 0x41, + 0x09, 0x80, 0x39, 0x33, 0xc9, 0xda, 0xb9, 0x45, 0xb9, 0x41, 0x09, 0x80, + 0x39, 0x33, 0x19, 0xdb, 0x99, 0x45, 0x85, 0x0c, 0x44, 0xb0, 0x02, 0x00, + 0xe2, 0x40, 0x10, 0x00, 0x10, 0xae, 0x40, 0x0c, 0xa3, 0x41, 0x09, 0x80, + 0x63, 0xfc, 0xac, 0x9b, 0x01, 0xee, 0xa3, 0xfc, 0x7c, 0x01, 0x85, 0x94, + 0x06, 0x00, 0x00, 0x0c, 0x01, 0xed, 0x9f, 0x45, 0x83, 0xf8, 0x7c, 0x01, + 0x7f, 0xed, 0xbf, 0x45, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, + 0x62, 0xfc, 0x74, 0x01, 0x83, 0x94, 0x05, 0x00, 0x00, 0x0c, 0x82, 0xf8, + 0x74, 0x01, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, 0x62, 0xfc, 0x78, 0x01, + 0x83, 0x94, 0x05, 0x00, 0x00, 0x0c, 0x82, 0xf8, 0x78, 0x01, 0x9f, 0x45, + 0x01, 0xed, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0xac, 0x9b, 0x01, 0xed, 0x83, 0xf8, 0x64, 0x01, 0x9f, 0x45, + 0x03, 0xf8, 0x88, 0x01, 0xf5, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x44, 0x45, + 0xa0, 0x30, 0xd0, 0x00, 0x04, 0x0e, 0x42, 0x30, 0x51, 0x1e, 0xe2, 0x45, + 0x18, 0xee, 0x26, 0x8d, 0x98, 0xed, 0x02, 0x60, 0x0b, 0x80, 0x02, 0x60, + 0x08, 0x90, 0x62, 0x60, 0x03, 0x80, 0x62, 0x60, 0x00, 0x90, 0x81, 0xed, + 0x62, 0x60, 0x07, 0x80, 0x62, 0x60, 0x04, 0x90, 0x87, 0xed, 0x62, 0x60, + 0x0f, 0x80, 0x62, 0x60, 0x0c, 0x90, 0x8c, 0xed, 0x62, 0x60, 0x13, 0x80, + 0x62, 0x60, 0x10, 0x90, 0x02, 0x62, 0x17, 0x80, 0x02, 0x62, 0x14, 0x90, + 0x82, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x4f, 0x23, 0xe2, 0x45, + 0x98, 0xee, 0x40, 0x0c, 0x04, 0x45, 0x06, 0x47, 0xfd, 0xcf, 0x7f, 0xed, + 0xed, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x98, 0xbf, 0xa2, 0x41, + 0xfa, 0x50, 0x42, 0x30, 0xfa, 0x50, 0x57, 0x45, 0x43, 0x94, 0x4d, 0x00, + 0x00, 0x0c, 0xc4, 0x0a, 0x5e, 0x6d, 0x42, 0xb0, 0x02, 0x00, 0xa2, 0x40, + 0x57, 0x00, 0x04, 0x62, 0x03, 0x00, 0xb2, 0xae, 0x04, 0x62, 0x00, 0x10, + 0x20, 0x0d, 0x40, 0x0d, 0x00, 0x85, 0x00, 0x0d, 0x60, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0xac, 0x9b, 0x30, 0xb2, 0x0f, 0x00, 0x31, 0x72, + 0x01, 0x00, 0x42, 0xf9, 0xf8, 0x00, 0x62, 0xf8, 0xfc, 0x00, 0x02, 0xf9, + 0x00, 0x01, 0x22, 0xf9, 0x44, 0x01, 0xc2, 0x20, 0x48, 0x91, 0x02, 0xfa, + 0x80, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x98, 0x86, 0x42, 0x30, 0xbd, 0x15, + 0xe2, 0x45, 0x00, 0x0c, 0xa8, 0x86, 0xa2, 0x41, 0x10, 0x80, 0x00, 0x85, + 0x42, 0x30, 0x8f, 0x22, 0xc2, 0x45, 0x3d, 0xfa, 0x10, 0x00, 0x01, 0xed, + 0x17, 0x45, 0x0a, 0x47, 0x04, 0x62, 0x03, 0x00, 0x04, 0x62, 0x00, 0x10, + 0x01, 0xed, 0x45, 0xb4, 0x47, 0x00, 0x20, 0x0d, 0x64, 0x60, 0x08, 0x00, + 0x40, 0x31, 0x01, 0x00, 0x64, 0x60, 0x05, 0x10, 0x00, 0x85, 0x1b, 0x44, + 0x03, 0xb1, 0x01, 0x00, 0xc6, 0xcf, 0x60, 0x00, 0x90, 0x1b, 0x44, 0x60, + 0x03, 0x00, 0x44, 0x60, 0x00, 0x10, 0x42, 0xb0, 0x0f, 0x00, 0x02, 0xb4, + 0xac, 0xff, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xf5, 0xdb, 0xe2, 0x45, + 0x02, 0xee, 0xda, 0xcf, 0x40, 0x30, 0xfe, 0xff, 0x64, 0x60, 0x08, 0x00, + 0x64, 0x60, 0x05, 0x10, 0x30, 0x6f, 0xc0, 0x00, 0x4c, 0x08, 0x50, 0xaf, + 0x7f, 0xed, 0x02, 0xef, 0xc5, 0xb4, 0xce, 0xff, 0x00, 0x0c, 0xc4, 0x60, + 0x0c, 0x00, 0xc4, 0x60, 0x09, 0x10, 0xe0, 0x6e, 0xa0, 0x00, 0x4c, 0x08, + 0xa5, 0x40, 0xc2, 0xff, 0x04, 0x62, 0x03, 0x00, 0x04, 0x62, 0x00, 0x10, + 0x1b, 0x44, 0x36, 0x44, 0x03, 0xb1, 0x01, 0x00, 0xe6, 0xb0, 0x01, 0x00, + 0x60, 0x00, 0x90, 0x1b, 0x20, 0x31, 0x01, 0x00, 0x40, 0x0d, 0x8d, 0xcf, + 0xc0, 0x00, 0x90, 0x33, 0x02, 0xed, 0x45, 0xb4, 0xad, 0xff, 0x7f, 0xed, + 0x64, 0x60, 0x08, 0x00, 0xc4, 0x60, 0x0c, 0x00, 0x64, 0x60, 0x05, 0x10, + 0xe7, 0xcf, 0xc4, 0x60, 0x09, 0x10, 0x00, 0x0c, 0xed, 0x4f, 0x65, 0xb0, + 0x0f, 0x00, 0x75, 0x45, 0x45, 0x0c, 0x64, 0x0e, 0xb0, 0xad, 0x46, 0x0e, + 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0x88, 0xfb, 0x81, 0xee, 0xa3, 0x94, + 0x4b, 0x00, 0x00, 0x0c, 0x82, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xbd, 0x15, 0xc2, 0x45, 0xb1, 0x41, 0x09, 0x80, 0x91, 0xfc, 0x58, 0xbf, + 0xa2, 0x0c, 0x02, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xf5, 0x16, + 0xc2, 0x45, 0x84, 0x30, 0x20, 0x01, 0x81, 0xed, 0x73, 0x94, 0x2a, 0x00, + 0x00, 0x0c, 0x91, 0xfc, 0x58, 0xbf, 0xa2, 0x41, 0x10, 0x80, 0xb0, 0x0c, + 0x42, 0x30, 0x9b, 0x1f, 0xc2, 0x45, 0x84, 0x30, 0x20, 0x01, 0x2a, 0x8d, + 0xa2, 0x41, 0x09, 0x80, 0x40, 0x0c, 0x35, 0x45, 0x0a, 0x47, 0x82, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x0c, 0x42, 0x30, 0xbd, 0x15, 0xc2, 0x45, + 0xb1, 0x41, 0x09, 0x80, 0x91, 0xfc, 0x58, 0xbf, 0xa2, 0x0c, 0x02, 0x0e, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xf5, 0x16, 0xc2, 0x45, 0x84, 0x30, + 0x20, 0x01, 0x81, 0xed, 0x73, 0xb4, 0xdb, 0xff, 0x91, 0xfc, 0x58, 0xbf, + 0x25, 0x69, 0x52, 0x00, 0x90, 0x33, 0xc2, 0x00, 0x58, 0x90, 0xa2, 0x41, + 0x09, 0x80, 0xcf, 0xcf, 0x42, 0x1a, 0x8f, 0xfb, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0xf5, 0xdb, 0xe2, 0x45, 0x02, 0xee, 0xd4, 0xcf, 0x7f, 0xed, + 0xed, 0x4f, 0x75, 0x45, 0xb3, 0x41, 0x09, 0x80, 0x53, 0xfc, 0xac, 0x9b, + 0x04, 0x0e, 0x81, 0xed, 0x82, 0xfc, 0x38, 0x02, 0x44, 0xfe, 0x3c, 0x00, + 0x92, 0xfc, 0x24, 0x00, 0x64, 0x94, 0x3e, 0x00, 0xb1, 0x41, 0x10, 0x80, + 0x31, 0x32, 0xc1, 0x1d, 0x70, 0x14, 0xdd, 0x00, 0x2c, 0x6e, 0xc0, 0x30, + 0xc8, 0x00, 0x62, 0x18, 0x8d, 0x01, 0x70, 0x60, 0xe1, 0x00, 0x70, 0x60, + 0xde, 0x10, 0x62, 0xf8, 0xe0, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0xbd, 0xa4, 0xe2, 0x45, 0x84, 0x6e, 0x80, 0x86, 0xf1, 0x45, 0x00, 0x0c, + 0x01, 0xed, 0x52, 0xf8, 0x24, 0x00, 0xb0, 0x60, 0xd3, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0xc0, 0x0c, 0xb0, 0x60, 0xd0, 0x10, 0x42, 0x30, 0x9d, 0xdd, + 0xe2, 0x45, 0x0d, 0xee, 0x04, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x35, 0x45, + 0x0a, 0x47, 0x42, 0x30, 0x5d, 0xdc, 0xc2, 0x45, 0x90, 0x30, 0xd0, 0x00, + 0x60, 0x30, 0xfe, 0xff, 0x62, 0x94, 0xf5, 0xff, 0xb9, 0x41, 0x09, 0x80, + 0x01, 0xee, 0x39, 0x33, 0xf5, 0xdb, 0x35, 0x45, 0x99, 0x45, 0x15, 0x4c, + 0xa0, 0x0c, 0x01, 0xee, 0x31, 0x32, 0xc1, 0x1d, 0xd1, 0x45, 0x12, 0xf8, + 0x24, 0x00, 0xbe, 0xcf, 0x53, 0xfc, 0xac, 0x9b, 0xed, 0x4f, 0xbd, 0x22, + 0x10, 0xd0, 0xb1, 0x41, 0x09, 0x80, 0x51, 0xfc, 0xac, 0x9b, 0xa3, 0x41, + 0x01, 0xa5, 0x42, 0xfc, 0x38, 0x02, 0x42, 0xfe, 0x3c, 0x00, 0xa2, 0x41, + 0xcc, 0x00, 0x42, 0x30, 0x00, 0x01, 0x43, 0xf8, 0x04, 0x3c, 0x44, 0x14, + 0xe3, 0x00, 0x0c, 0x8d, 0x81, 0xed, 0x62, 0x94, 0x1b, 0x00, 0xb9, 0x41, + 0x09, 0x80, 0x01, 0xee, 0x39, 0x33, 0xf5, 0xdb, 0xbd, 0x22, 0x10, 0x50, + 0x99, 0x45, 0x15, 0x4c, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x0c, 0x01, 0xee, + 0x42, 0x30, 0xc1, 0x1d, 0xc2, 0x45, 0x12, 0xf8, 0x24, 0x00, 0xb9, 0x41, + 0x09, 0x80, 0x01, 0xee, 0x39, 0x33, 0xf5, 0xdb, 0xbd, 0x22, 0x10, 0x50, + 0x99, 0x45, 0x15, 0x4c, 0x72, 0xfc, 0x24, 0x00, 0x43, 0x94, 0x9c, 0x00, + 0x04, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x91, 0x1d, 0xe2, 0x45, + 0x90, 0x0c, 0x50, 0x1c, 0xde, 0x00, 0xb3, 0x41, 0x01, 0xa5, 0xb4, 0x41, + 0xcc, 0x00, 0x20, 0x25, 0x53, 0xf8, 0x04, 0x3c, 0x50, 0x60, 0xe2, 0x00, + 0xd4, 0x30, 0x00, 0x03, 0xa0, 0x30, 0xc8, 0x00, 0x50, 0x60, 0xdf, 0x10, + 0x90, 0x30, 0x09, 0x00, 0x20, 0x25, 0x53, 0xf8, 0x04, 0x3c, 0x71, 0xfc, + 0xac, 0x9b, 0x50, 0x14, 0xde, 0x00, 0x43, 0x18, 0x8d, 0x01, 0x50, 0x60, + 0xe2, 0x00, 0x50, 0x60, 0xdf, 0x10, 0x43, 0xf8, 0xe0, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0xd3, 0xf8, 0x04, 0x3c, 0x42, 0x30, 0xcd, 0x1d, 0xe2, 0x45, + 0x00, 0x0c, 0x74, 0x30, 0x00, 0x05, 0x73, 0xf8, 0x04, 0x3c, 0x72, 0xfc, + 0x24, 0x00, 0x03, 0x94, 0x41, 0x00, 0x94, 0x32, 0x00, 0x07, 0x81, 0xed, + 0x93, 0xfa, 0x04, 0x3c, 0x62, 0x94, 0x3e, 0x00, 0xa2, 0x41, 0xcc, 0x00, + 0x30, 0x32, 0xd1, 0x00, 0xa3, 0x41, 0xcc, 0x00, 0xa2, 0x41, 0x01, 0xa5, + 0x10, 0x26, 0x63, 0x30, 0x00, 0x0b, 0x62, 0xf8, 0x04, 0x3c, 0x82, 0xf8, + 0x04, 0x3c, 0x70, 0x60, 0xd4, 0x00, 0xc0, 0x0c, 0x06, 0xee, 0x70, 0x60, + 0xd1, 0x10, 0xb0, 0x25, 0x62, 0xf8, 0x04, 0x3c, 0x70, 0x14, 0xd5, 0x00, + 0xb0, 0x25, 0x62, 0xf8, 0x04, 0x3c, 0x70, 0x60, 0xd9, 0x00, 0x70, 0x60, + 0xd6, 0x10, 0xb0, 0x25, 0x62, 0xf8, 0x04, 0x3c, 0x70, 0x60, 0xdd, 0x00, + 0x70, 0x60, 0xda, 0x10, 0xb0, 0x25, 0x62, 0xf8, 0x04, 0x3c, 0xb0, 0x60, + 0xd4, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x9d, 0xdd, 0xc2, 0x45, + 0xb0, 0x60, 0xd1, 0x10, 0x1b, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0xbd, 0x22, + 0x10, 0x50, 0x0a, 0x47, 0x93, 0xfa, 0x04, 0x3c, 0xa2, 0x41, 0xcc, 0x00, + 0x42, 0x30, 0x00, 0x09, 0xa3, 0x41, 0x01, 0xa5, 0x43, 0xf8, 0x04, 0x3c, + 0xa2, 0x41, 0x10, 0x80, 0x80, 0x86, 0x42, 0x30, 0xc1, 0x1d, 0xc2, 0x45, + 0x30, 0x32, 0xd1, 0x00, 0x01, 0xed, 0xb6, 0xcf, 0x52, 0xf8, 0x24, 0x00, + 0x42, 0x30, 0x5d, 0xdc, 0xe2, 0x45, 0x91, 0x0c, 0x60, 0x30, 0xfe, 0xff, + 0x62, 0x94, 0xdf, 0xff, 0xb9, 0x41, 0x09, 0x80, 0x49, 0xcf, 0x01, 0xee, + 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x0c, 0x01, 0xee, 0x42, 0x30, 0xc1, 0x1d, + 0xc2, 0x45, 0x12, 0xf8, 0x24, 0x00, 0x5d, 0xcf, 0xa2, 0x41, 0x10, 0x80, + 0xe9, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0xeb, 0xcb, 0x12, 0xef, 0x96, 0xee, + 0x09, 0x6e, 0x42, 0x30, 0xf5, 0x22, 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, + 0x07, 0xc8, 0x08, 0xc8, 0xc2, 0x45, 0x1d, 0x38, 0x24, 0x00, 0xeb, 0x4b, + 0x0c, 0x47, 0x00, 0x0c, 0xd9, 0x4f, 0x81, 0xed, 0x44, 0x0c, 0x04, 0xc8, + 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0xa9, 0xc8, 0x0a, 0xc8, + 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, 0x0f, 0xc8, 0x10, 0xc8, 0x1d, 0x38, + 0x44, 0x00, 0x65, 0x94, 0x2f, 0x00, 0xf3, 0xcb, 0x9f, 0x8e, 0x82, 0xed, + 0x65, 0x94, 0x10, 0x00, 0x03, 0xee, 0x85, 0xb4, 0x02, 0x00, 0x00, 0x0c, + 0x6a, 0xc8, 0x4c, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x0f, 0xef, 0xb6, 0xee, + 0x42, 0x30, 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0xf3, 0x4b, 0x14, 0x47, + 0x4c, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xaa, 0xc8, 0x0f, 0xef, 0xb6, 0xee, + 0x42, 0x30, 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0xf3, 0x4b, 0x14, 0x47, + 0x4c, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x83, 0xed, 0x0f, 0xef, 0xb6, 0xee, + 0x09, 0x6e, 0x42, 0x30, 0xf5, 0x22, 0xc2, 0x45, 0x7d, 0xf8, 0x28, 0x00, + 0xf3, 0x4b, 0x14, 0x47, 0x4c, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x87, 0xed, + 0x0f, 0xef, 0xb6, 0xee, 0x09, 0x6e, 0x42, 0x30, 0xf5, 0x22, 0xc2, 0x45, + 0x7d, 0xf8, 0x28, 0x00, 0xf3, 0x4b, 0x14, 0x47, 0xf5, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0xa4, 0xb0, 0x0f, 0x00, 0x42, 0x30, 0xbd, 0x15, 0xe5, 0xcb, + 0xc2, 0x45, 0xa5, 0x70, 0x01, 0x00, 0x82, 0x30, 0x94, 0xf6, 0x84, 0xb0, + 0x49, 0x00, 0x62, 0x0c, 0x05, 0x8e, 0x40, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x14, 0x78, 0xfb, 0x83, 0x30, 0xd8, 0xeb, 0x84, 0xb0, 0xb5, 0x00, + 0x06, 0x8e, 0x83, 0x30, 0x98, 0xea, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, + 0x79, 0xfb, 0x84, 0xb0, 0xf1, 0x00, 0xe4, 0x40, 0x04, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0x7a, 0xfb, 0x63, 0x30, 0x8f, 0xe9, 0x63, 0xb0, + 0x8d, 0x00, 0x85, 0x8d, 0xe5, 0x4b, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, + 0x7b, 0xfb, 0x06, 0x47, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x24, 0x9b, + 0x24, 0x31, 0xf6, 0xff, 0x43, 0x15, 0x08, 0x00, 0x0a, 0x94, 0x25, 0x00, + 0x84, 0x30, 0x0a, 0x00, 0xa8, 0x41, 0x62, 0x10, 0xb8, 0x6d, 0xc0, 0x0c, + 0x08, 0x31, 0xd3, 0x4d, 0x30, 0x69, 0xb1, 0x6a, 0x60, 0x6f, 0x02, 0x01, + 0x3c, 0x9b, 0x02, 0x46, 0x2d, 0x25, 0x49, 0x00, 0x90, 0x3b, 0x90, 0xaf, + 0x63, 0x30, 0x60, 0x00, 0x05, 0x01, 0x3c, 0x9b, 0x05, 0x46, 0xdd, 0x26, + 0x85, 0x00, 0x90, 0x3b, 0xa7, 0x40, 0x06, 0x00, 0x49, 0x94, 0x09, 0x00, + 0x00, 0x0c, 0xa4, 0x94, 0x08, 0x00, 0x00, 0x0c, 0x46, 0xb5, 0xe4, 0xff, + 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, + 0x02, 0xed, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0xe5, 0xcb, + 0x42, 0x30, 0x01, 0xe2, 0xe2, 0x45, 0x64, 0x0d, 0x10, 0x8d, 0x6b, 0x30, + 0x94, 0xf6, 0x63, 0xb0, 0x49, 0x00, 0x8d, 0x8d, 0x6b, 0x30, 0xd8, 0xeb, + 0x81, 0xed, 0x62, 0x94, 0x24, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0x7d, 0xfb, 0xe5, 0x4b, 0x06, 0x47, 0x63, 0xb0, + 0x51, 0x00, 0x91, 0xad, 0x81, 0xed, 0x6b, 0x30, 0x74, 0xeb, 0x63, 0xb0, + 0x51, 0x00, 0x96, 0x8d, 0x6b, 0x30, 0x98, 0xea, 0x81, 0xed, 0x62, 0x94, + 0x30, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xec, 0xcf, 0x42, 0x14, + 0x81, 0xfb, 0x62, 0x94, 0x23, 0x00, 0xe5, 0x4b, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x14, 0x7f, 0xfb, 0x06, 0x47, 0xe1, 0xcf, 0x42, 0x14, 0x7c, 0xfb, + 0x63, 0xb0, 0xf1, 0x00, 0x8f, 0xad, 0x81, 0xed, 0x6b, 0x30, 0x8f, 0xe9, + 0x63, 0xb0, 0x51, 0x00, 0x9b, 0x8d, 0x81, 0xed, 0x62, 0x94, 0x2d, 0x00, + 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xcf, 0xcf, 0x42, 0x14, 0x85, 0xfb, + 0x62, 0x94, 0x1e, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xc7, 0xcf, + 0x42, 0x14, 0x83, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xc2, 0xcf, 0x42, 0x14, + 0x7e, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xbd, 0xcf, 0x42, 0x14, 0x80, 0xfb, + 0x6b, 0x31, 0x2b, 0xe9, 0x6b, 0xb1, 0x29, 0x00, 0xeb, 0x40, 0x0d, 0x00, + 0x62, 0x94, 0x12, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xaf, 0xcf, + 0x42, 0x14, 0x87, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0xaa, 0xcf, 0x42, 0x14, + 0x82, 0xfb, 0xa7, 0xcf, 0x40, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0xcf, + 0x42, 0x14, 0x84, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x9e, 0xcf, 0x42, 0x14, + 0x86, 0xfb, 0x00, 0x0c, 0xe1, 0x4f, 0x3d, 0x23, 0x18, 0xd0, 0xb4, 0x41, + 0x09, 0x80, 0xbe, 0x41, 0x09, 0x80, 0xb7, 0x41, 0x09, 0x80, 0xb6, 0x41, + 0x09, 0x80, 0xb3, 0x41, 0x09, 0x80, 0x14, 0xf8, 0x74, 0xfb, 0x1e, 0x18, + 0x8c, 0xfb, 0x17, 0x18, 0x8d, 0xfb, 0x16, 0x18, 0x8e, 0xfb, 0x13, 0x18, + 0x8f, 0xfb, 0xb1, 0x41, 0x09, 0x80, 0xd1, 0xfc, 0xac, 0x9b, 0x44, 0x60, + 0xe3, 0x00, 0x66, 0xfc, 0x38, 0x02, 0x44, 0x60, 0xe0, 0x10, 0x02, 0xb4, + 0x6b, 0x01, 0x43, 0xfe, 0x3c, 0x00, 0x44, 0x14, 0xfc, 0x00, 0xa7, 0x41, + 0x09, 0x80, 0x07, 0x18, 0x64, 0xee, 0x02, 0x94, 0x6d, 0x01, 0x04, 0x0e, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x50, 0xbe, 0x62, 0x60, 0x0f, 0x00, + 0xa6, 0xfe, 0x74, 0x01, 0x62, 0x60, 0x0c, 0x10, 0xb0, 0x6d, 0x62, 0x60, + 0x0f, 0x80, 0x15, 0xb4, 0x7e, 0x01, 0x62, 0x60, 0x0c, 0x90, 0x72, 0xfc, + 0x24, 0x00, 0x01, 0xed, 0x43, 0x94, 0xd5, 0x01, 0xa2, 0x41, 0x10, 0x80, + 0x50, 0x14, 0xdb, 0x00, 0x81, 0xed, 0x46, 0x18, 0x8d, 0x01, 0x50, 0x60, + 0xdf, 0x00, 0x50, 0x60, 0xdc, 0x10, 0x46, 0xf8, 0xe0, 0x00, 0x08, 0x09, + 0x62, 0xb4, 0x0e, 0x00, 0x00, 0x0c, 0x66, 0x14, 0x17, 0x00, 0x43, 0x94, + 0x09, 0x00, 0x00, 0x0c, 0x46, 0x18, 0x16, 0x00, 0x46, 0x18, 0x17, 0x00, + 0x46, 0xf8, 0x2c, 0x01, 0x46, 0xf8, 0x30, 0x01, 0xa2, 0x41, 0x10, 0x80, + 0xa0, 0x30, 0xc8, 0x00, 0x90, 0x30, 0x0a, 0x00, 0x42, 0x30, 0xcd, 0x1d, + 0xc2, 0x45, 0xfd, 0xf8, 0x10, 0x00, 0x72, 0xfc, 0x24, 0x00, 0x03, 0x94, + 0x6f, 0x01, 0xe4, 0x48, 0x81, 0xed, 0x62, 0x94, 0x6d, 0x01, 0xa7, 0x14, + 0x64, 0xee, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xd1, 0xd7, 0xc2, 0x45, + 0x90, 0x14, 0xd2, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x4d, 0xd8, + 0xc2, 0x45, 0x90, 0x14, 0xd3, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x25, 0xd9, 0xc2, 0x45, 0x90, 0x14, 0xd4, 0x00, 0x71, 0xfc, 0xac, 0x9b, + 0x43, 0xfc, 0x1c, 0x01, 0x42, 0xd0, 0xc0, 0x00, 0x02, 0x94, 0x35, 0x01, + 0xa2, 0x41, 0x09, 0x80, 0x82, 0x30, 0xa4, 0x9a, 0x81, 0xee, 0xc2, 0x8a, + 0xd0, 0x14, 0x00, 0x01, 0xb0, 0x14, 0x01, 0x01, 0x41, 0x8b, 0x90, 0x14, + 0xd3, 0x00, 0xa2, 0x18, 0xa4, 0x9a, 0x05, 0xed, 0x44, 0x94, 0x2e, 0x01, + 0x00, 0x0c, 0x50, 0x14, 0xd5, 0x00, 0xe2, 0x40, 0x06, 0x00, 0x83, 0x14, + 0x17, 0x00, 0x44, 0x00, 0x90, 0x23, 0xe4, 0x40, 0x3b, 0x01, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0xa5, 0xd9, 0xc2, 0x45, 0x90, 0x14, 0xd6, 0x00, + 0x50, 0x14, 0xd7, 0x00, 0x62, 0xb0, 0x02, 0x00, 0x03, 0xb4, 0x44, 0x01, + 0x71, 0xfc, 0xac, 0x9b, 0x50, 0x14, 0xd8, 0x00, 0x62, 0xb0, 0x02, 0x00, + 0x03, 0xb4, 0x4b, 0x01, 0x71, 0xfc, 0xac, 0x9b, 0x50, 0x14, 0xd3, 0x00, + 0x02, 0xb4, 0xf5, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x19, 0xdb, 0xc2, 0x45, 0x90, 0x1c, 0xda, 0x00, 0xd0, 0x60, + 0xfb, 0x00, 0x50, 0x14, 0x19, 0x01, 0xd0, 0x60, 0xf8, 0x10, 0x33, 0xad, + 0xd3, 0x18, 0x8f, 0xfb, 0xb0, 0x60, 0xe7, 0x00, 0xa2, 0x41, 0x09, 0x80, + 0x01, 0xee, 0x42, 0x30, 0x9d, 0xdd, 0xc2, 0x45, 0xb0, 0x60, 0xe4, 0x10, + 0x02, 0xb4, 0xd1, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x90, 0x60, 0xe7, 0x00, + 0x42, 0x30, 0xbd, 0x15, 0x90, 0x60, 0xe4, 0x10, 0xa4, 0xb0, 0x0f, 0x00, + 0xc2, 0x45, 0xa5, 0x70, 0x01, 0x00, 0xc2, 0x0e, 0xa2, 0x41, 0x09, 0x80, + 0x82, 0xfc, 0x58, 0xbf, 0xa2, 0x41, 0x10, 0x80, 0xb6, 0x0c, 0x42, 0x30, + 0xf5, 0x16, 0xc2, 0x45, 0x84, 0x30, 0x20, 0x01, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x6d, 0xe2, 0xe2, 0x45, 0x96, 0x0c, 0x73, 0x14, 0x8f, 0xfb, + 0x27, 0x05, 0x53, 0x18, 0x8f, 0xfb, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x5d, 0xdc, 0xc2, 0x45, 0x90, 0x30, 0xe4, 0x00, 0x60, 0x30, 0xfe, 0xff, + 0x62, 0x94, 0xa1, 0x00, 0x71, 0xfc, 0xac, 0x9b, 0x50, 0x60, 0xf5, 0x00, + 0x50, 0x60, 0xf2, 0x10, 0x83, 0xfc, 0x74, 0x01, 0x82, 0x94, 0x03, 0x00, + 0x00, 0x0c, 0x43, 0xf8, 0x74, 0x01, 0x50, 0x14, 0xf7, 0x00, 0xb0, 0x14, + 0xf6, 0x00, 0x83, 0xfc, 0x78, 0x01, 0x20, 0x25, 0xd5, 0x44, 0x82, 0x94, + 0x03, 0x00, 0x00, 0x0c, 0x43, 0xf8, 0x78, 0x01, 0x90, 0x60, 0xe7, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x99, 0xe1, 0xc2, 0x45, 0x90, 0x60, + 0xe4, 0x10, 0x93, 0x14, 0x8f, 0xfb, 0x71, 0xfc, 0xac, 0x9b, 0x29, 0x06, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xb9, 0xd7, 0x83, 0xf8, 0x64, 0x01, + 0xc2, 0x45, 0x03, 0xf8, 0x88, 0x01, 0x3e, 0xad, 0xb3, 0x41, 0x09, 0x80, + 0x20, 0x0e, 0x73, 0x32, 0xf9, 0xe0, 0xc0, 0x32, 0x04, 0x00, 0x90, 0x60, + 0x1f, 0x01, 0x9d, 0x2e, 0x90, 0x6c, 0xd3, 0x45, 0x90, 0x60, 0x1c, 0x11, + 0xd1, 0xb6, 0xf7, 0xff, 0x83, 0xed, 0x50, 0x60, 0x0f, 0x01, 0xb3, 0x41, + 0x04, 0x80, 0x50, 0x60, 0x0c, 0x11, 0x20, 0x0e, 0x73, 0x32, 0x39, 0xfe, + 0x54, 0xf8, 0x74, 0xfb, 0x50, 0x60, 0xf5, 0x00, 0xb4, 0x41, 0x09, 0x80, + 0xc0, 0x32, 0x0c, 0x00, 0x50, 0x60, 0xf2, 0x10, 0x94, 0x32, 0x1d, 0xd3, + 0x02, 0x92, 0x04, 0x00, 0x01, 0xed, 0x03, 0x02, 0x58, 0x10, 0x02, 0x02, + 0x00, 0x60, 0x92, 0x0c, 0xf3, 0x45, 0x81, 0xee, 0xc2, 0x96, 0x3d, 0x00, + 0x82, 0x0c, 0xbc, 0xfc, 0x24, 0x82, 0xa5, 0x30, 0xf0, 0x29, 0x9a, 0x06, + 0xd4, 0x45, 0x31, 0x32, 0x00, 0x10, 0x30, 0xb6, 0xf1, 0xff, 0x92, 0x0c, + 0x55, 0x0c, 0x3d, 0x23, 0x18, 0x50, 0x10, 0x47, 0x81, 0xed, 0x62, 0xb4, + 0x2a, 0x00, 0xa7, 0x41, 0x09, 0x80, 0x47, 0x18, 0x64, 0xee, 0x44, 0x14, + 0xfc, 0x00, 0x02, 0xb4, 0x95, 0xfe, 0x04, 0x0e, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x50, 0xbe, 0x62, 0x60, 0x0b, 0x00, 0xa0, 0x0e, 0xa0, 0x0c, + 0x62, 0x60, 0x08, 0x10, 0x01, 0xee, 0x06, 0xf8, 0x74, 0x01, 0xb0, 0x6d, + 0x62, 0x60, 0x0b, 0x80, 0x62, 0x60, 0x08, 0x90, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0xf8, 0x60, 0xee, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xc1, 0x1d, + 0xc2, 0x45, 0x12, 0xf8, 0x24, 0x00, 0x55, 0x0c, 0x3d, 0x23, 0x18, 0x50, + 0x10, 0x47, 0xa0, 0x32, 0xff, 0xff, 0x55, 0x0c, 0x3d, 0x23, 0x18, 0x50, + 0x10, 0x47, 0x42, 0x30, 0xc9, 0xda, 0xc2, 0x45, 0x90, 0x1c, 0xd9, 0x00, + 0x10, 0xcf, 0xd0, 0x60, 0xfb, 0x00, 0x82, 0x30, 0xa4, 0x9a, 0xc2, 0x0a, + 0xa5, 0x40, 0xcc, 0xfe, 0x90, 0x14, 0xd3, 0x00, 0x05, 0xed, 0x44, 0xb4, + 0xd4, 0xfe, 0x00, 0x0c, 0x50, 0x14, 0x13, 0x01, 0x90, 0x14, 0x12, 0x01, + 0x57, 0x18, 0x8d, 0xfb, 0x01, 0xed, 0x9e, 0x18, 0x8c, 0xfb, 0xc9, 0xce, + 0x56, 0x18, 0x8e, 0xfb, 0xa7, 0x14, 0x64, 0xee, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xc1, 0x1d, 0xe2, 0x45, 0x80, 0x0c, 0x01, 0xed, 0x8d, 0xce, + 0x52, 0xf8, 0x24, 0x00, 0x83, 0x14, 0x16, 0x00, 0x44, 0x94, 0xc1, 0xfe, + 0x00, 0x0c, 0x43, 0x18, 0x16, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xa5, 0xd9, 0xc2, 0x45, 0x90, 0x14, 0xd6, 0x00, 0x50, 0x14, 0xd7, 0x00, + 0x62, 0xb0, 0x02, 0x00, 0x03, 0x94, 0xc0, 0xfe, 0x71, 0xfc, 0xac, 0x9b, + 0x83, 0xfc, 0x24, 0x01, 0x44, 0x94, 0xba, 0xfe, 0x00, 0x0c, 0x43, 0xf8, + 0x24, 0x01, 0x50, 0x14, 0xd8, 0x00, 0x62, 0xb0, 0x02, 0x00, 0x03, 0x94, + 0xb9, 0xfe, 0x71, 0xfc, 0xac, 0x9b, 0x83, 0xfc, 0x28, 0x01, 0x44, 0x94, + 0xb3, 0xfe, 0x00, 0x0c, 0xb1, 0xce, 0x43, 0xf8, 0x28, 0x01, 0xa0, 0x0c, + 0x01, 0xee, 0x42, 0x30, 0xc1, 0x1d, 0x12, 0xf8, 0x24, 0x00, 0xc2, 0x45, + 0xfd, 0xf8, 0x10, 0x00, 0xd1, 0xfc, 0xac, 0x9b, 0x21, 0xce, 0xe4, 0x48, + 0xe5, 0x4f, 0x3d, 0x23, 0x10, 0xd0, 0xc4, 0x63, 0x03, 0x00, 0xc4, 0x63, + 0x00, 0x10, 0xde, 0x33, 0xf4, 0xff, 0x9e, 0x40, 0x31, 0x00, 0x64, 0x0e, + 0xb5, 0x41, 0x09, 0x80, 0xb1, 0x41, 0x09, 0x80, 0xb4, 0x41, 0x09, 0x80, + 0x46, 0x6c, 0x31, 0x32, 0xb8, 0xed, 0x55, 0x32, 0xc4, 0xbe, 0xb7, 0x41, + 0x09, 0x80, 0x94, 0x32, 0xf5, 0xdb, 0xb6, 0x41, 0x10, 0x80, 0x50, 0x60, + 0x03, 0x00, 0x50, 0x60, 0x00, 0x10, 0x62, 0xb0, 0x29, 0x00, 0xe3, 0x40, + 0xd2, 0x00, 0x51, 0x00, 0x18, 0x11, 0xa2, 0x45, 0xa4, 0x41, 0x09, 0x80, + 0xa2, 0x41, 0x01, 0x80, 0x22, 0xef, 0xb0, 0x0c, 0x42, 0x30, 0xbd, 0xa4, + 0xc2, 0x45, 0x84, 0x30, 0xe8, 0x01, 0x50, 0x60, 0x07, 0x00, 0x50, 0x60, + 0x04, 0x10, 0x5e, 0x00, 0xd0, 0xf1, 0xde, 0x40, 0xe2, 0xff, 0x20, 0x04, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe7, 0x24, 0xe2, 0x45, 0x93, 0x0c, + 0x40, 0x0c, 0x3d, 0x23, 0x10, 0x50, 0x0e, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x61, 0xde, 0xe2, 0x45, 0x90, 0x0c, 0xe8, 0xcf, 0x50, 0x60, + 0x07, 0x00, 0x52, 0x14, 0x02, 0x00, 0x20, 0x6d, 0x52, 0x18, 0x02, 0x00, + 0x57, 0x30, 0x45, 0xc2, 0xe2, 0x45, 0x90, 0x0c, 0xf4, 0x45, 0x01, 0xee, + 0xda, 0xcf, 0x50, 0x60, 0x07, 0x00, 0x56, 0x30, 0x97, 0x1d, 0xe2, 0x45, + 0x90, 0x0c, 0xd3, 0xcf, 0x50, 0x60, 0x07, 0x00, 0x01, 0xed, 0x5c, 0x18, + 0xf0, 0x81, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x89, 0xd6, 0xe2, 0x45, + 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x0c, 0x42, 0x30, 0xc1, 0x1d, + 0xe2, 0x45, 0x01, 0xee, 0xc0, 0xcf, 0x50, 0x60, 0x07, 0x00, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0xbd, 0xfc, 0xe2, 0x45, 0x90, 0x0c, 0xb7, 0xcf, + 0x50, 0x60, 0x07, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x30, 0x50, 0xbe, + 0x65, 0x60, 0x03, 0x00, 0x65, 0x60, 0x00, 0x10, 0xb0, 0x6d, 0x65, 0x60, + 0x03, 0x80, 0x65, 0x60, 0x00, 0x90, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x11, 0xdf, 0xe2, 0x45, 0x90, 0x0c, 0xa1, 0xcf, 0x50, 0x60, 0x07, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x91, 0x1d, 0xe2, 0x45, 0x90, 0x0c, + 0x98, 0xcf, 0x50, 0x60, 0x07, 0x00, 0x52, 0x60, 0x07, 0x00, 0x52, 0x60, + 0x04, 0x10, 0x20, 0x6d, 0x52, 0x60, 0x07, 0x80, 0x52, 0x60, 0x04, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x9d, 0x1d, 0xe2, 0x45, 0x90, 0x0c, + 0x86, 0xcf, 0x50, 0x60, 0x07, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x50, 0xbe, 0x62, 0x60, 0x07, 0x00, 0x62, 0x60, 0x04, 0x10, 0xb0, 0x6d, + 0x62, 0x60, 0x07, 0x80, 0x62, 0x60, 0x04, 0x90, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x69, 0xe3, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x40, 0x6d, 0xff, + 0x91, 0xcf, 0x00, 0x0c, 0x55, 0x14, 0xc4, 0xbe, 0xa3, 0x41, 0x01, 0xa5, + 0x90, 0x0c, 0x20, 0x6d, 0x55, 0x18, 0xc4, 0xbe, 0xa2, 0x41, 0x11, 0x00, + 0x42, 0x30, 0x00, 0x11, 0x43, 0xf8, 0x04, 0x3c, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xa9, 0x1d, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xac, 0x9b, 0x42, 0x14, 0xe4, 0x00, 0x02, 0x94, 0x4f, 0xff, + 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, 0x44, 0x9a, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0x45, 0xc7, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xe3, 0x1c, 0xe2, 0x45, 0x00, 0x0c, 0x40, 0xcf, 0x50, 0x60, + 0x07, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0xac, 0x9b, 0x43, 0xfc, + 0x3c, 0x02, 0x20, 0x6d, 0x34, 0xcf, 0x43, 0xf8, 0x3c, 0x02, 0x00, 0x0c, + 0xf1, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x64, 0x45, 0xff, 0xef, 0x24, 0x0e, + 0x45, 0x0e, 0xc0, 0x0c, 0xa0, 0xee, 0x42, 0x30, 0x11, 0xb0, 0xe2, 0x45, + 0x80, 0x0c, 0x26, 0x8d, 0x02, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, + 0xd0, 0x00, 0x42, 0x30, 0x51, 0x1e, 0xe2, 0x45, 0x48, 0xee, 0x1c, 0x8d, + 0xa3, 0x41, 0x09, 0x80, 0x20, 0xe8, 0x83, 0xfc, 0xac, 0x9b, 0x62, 0x30, + 0x3c, 0x00, 0xae, 0xe8, 0x02, 0x38, 0x44, 0x00, 0xaf, 0xe9, 0x62, 0xf8, + 0x40, 0x00, 0x50, 0xf8, 0x74, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xd7, 0x1c, 0x50, 0xf8, 0x44, 0x00, 0x64, 0x14, 0xe4, 0x00, 0x01, 0xed, + 0x43, 0x94, 0x04, 0x00, 0xa3, 0x41, 0x09, 0x80, 0x24, 0x45, 0x08, 0x47, + 0x43, 0xfc, 0x5c, 0xee, 0xb1, 0x14, 0x1e, 0x00, 0x92, 0xfc, 0x0c, 0x0b, + 0x42, 0xb0, 0x0a, 0x00, 0x04, 0xad, 0xa4, 0xf8, 0x6c, 0x01, 0x03, 0xf8, + 0x5c, 0xee, 0xa2, 0x41, 0xf0, 0x00, 0x42, 0x30, 0x00, 0x03, 0xa3, 0x41, + 0x01, 0xa5, 0xb9, 0x41, 0x10, 0x80, 0x90, 0x0c, 0x43, 0xf8, 0x04, 0x3c, + 0x39, 0x33, 0x41, 0x13, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, + 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, 0x30, 0xea, 0x63, 0x30, + 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0xfc, 0xff, 0x34, 0x69, + 0xbf, 0x45, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, + 0x7d, 0xa4, 0xe9, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa6, 0x41, 0x01, 0xa4, + 0xc6, 0x50, 0x10, 0xb8, 0x89, 0x6e, 0x40, 0xee, 0x66, 0x30, 0xf4, 0xff, + 0xc4, 0xef, 0x60, 0xea, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0xfc, 0xff, + 0x34, 0x69, 0x40, 0x6e, 0x50, 0xe9, 0xe4, 0xb4, 0xf6, 0xff, 0xd2, 0x6e, + 0x44, 0x48, 0xff, 0xed, 0x62, 0x94, 0x58, 0x00, 0x00, 0x0c, 0xa3, 0x41, + 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, 0x55, 0xed, 0x30, 0xe9, 0x63, 0x30, + 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0xfc, 0xff, 0xb4, 0x69, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0xf8, 0x2c, 0xfb, 0xa3, 0x41, 0x01, 0xa4, + 0x63, 0x50, 0x10, 0xb8, 0x1d, 0xed, 0x30, 0xe9, 0x63, 0x30, 0xf4, 0xff, + 0x30, 0x69, 0x22, 0x2d, 0x7d, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x5c, 0xbf, 0x34, 0x6b, 0x2f, 0x6a, 0xa3, 0x41, 0xfa, 0x50, 0xa5, 0x41, + 0x09, 0x80, 0x63, 0x30, 0xfa, 0x50, 0x64, 0x94, 0x03, 0x00, 0xc5, 0xf8, + 0x30, 0xfb, 0x2f, 0xe8, 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, + 0x56, 0xed, 0x30, 0xe9, 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, + 0xe2, 0x40, 0xfc, 0xff, 0xb4, 0x69, 0xa6, 0x41, 0x01, 0xa4, 0xc6, 0x50, + 0x10, 0xb8, 0xa2, 0x41, 0x09, 0x80, 0xa5, 0x41, 0x09, 0x80, 0x62, 0xf8, + 0x34, 0xfb, 0xa5, 0x30, 0x38, 0xfb, 0x57, 0xee, 0x66, 0x30, 0xf4, 0xff, + 0xe6, 0xef, 0x60, 0xea, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0xfc, 0xff, + 0x34, 0x69, 0x40, 0x6e, 0x50, 0xe9, 0xe4, 0xb4, 0xf6, 0xff, 0xd2, 0x6e, + 0xe9, 0x4b, 0x0a, 0x47, 0x85, 0x48, 0x44, 0xb4, 0xa8, 0xff, 0xa3, 0x41, + 0x01, 0xa4, 0x66, 0x48, 0x83, 0xb4, 0xa1, 0xff, 0x47, 0x48, 0x62, 0xb4, + 0xa0, 0xff, 0xa3, 0x41, 0x01, 0xa4, 0xa3, 0x41, 0x09, 0x80, 0xaa, 0xcf, + 0x43, 0xf8, 0x2c, 0xfb, 0xf5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, + 0xf1, 0xa5, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0x2c, 0xfb, 0xa2, 0x41, 0x00, 0xb0, 0x62, 0xf8, 0xdc, 0x4f, + 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0x30, 0xfb, 0x62, 0xf8, 0xd8, 0x4f, + 0xe5, 0x4b, 0x06, 0x47, 0xbf, 0x45, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0xed, 0x0f, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc8, 0x9e, + 0x63, 0x30, 0x78, 0xa4, 0x28, 0xee, 0x20, 0xea, 0x42, 0x30, 0x34, 0x00, + 0x62, 0xb4, 0xfb, 0xff, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x41, + 0x09, 0x80, 0x42, 0x30, 0xf0, 0x9b, 0x63, 0x30, 0xc8, 0x9e, 0x28, 0xee, + 0x20, 0xea, 0x42, 0x30, 0x34, 0x00, 0x43, 0xb4, 0xfb, 0xff, 0xe5, 0x4b, + 0x06, 0x47, 0x00, 0x0c, 0xe9, 0x4f, 0xdd, 0x22, 0x14, 0xd0, 0xb2, 0x41, + 0x09, 0x80, 0x52, 0xfc, 0x24, 0x9b, 0xb0, 0x41, 0x09, 0x80, 0x10, 0x32, + 0x90, 0xfb, 0x84, 0x0e, 0xa5, 0x0e, 0x02, 0x96, 0x2e, 0x00, 0xa4, 0x41, + 0x13, 0x80, 0xa3, 0x41, 0x06, 0x80, 0x63, 0x30, 0x2c, 0xae, 0x62, 0x94, + 0x2a, 0x00, 0x04, 0xf8, 0x8c, 0x1e, 0x02, 0x02, 0x10, 0x1b, 0x60, 0x00, + 0x58, 0x10, 0xb1, 0x41, 0x03, 0x80, 0x82, 0x0c, 0x31, 0x32, 0x2d, 0x33, + 0xd1, 0x45, 0xb3, 0x41, 0x13, 0x80, 0xd1, 0x45, 0x93, 0xfc, 0x8c, 0x1e, + 0x13, 0xfa, 0x8c, 0x1e, 0xb2, 0xfa, 0x24, 0x9b, 0x14, 0xb4, 0x05, 0x00, + 0xb9, 0x41, 0x10, 0x80, 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0xa4, 0x41, + 0x13, 0x80, 0x84, 0x30, 0xfc, 0x5f, 0x39, 0x33, 0x23, 0x22, 0xdd, 0x22, + 0x14, 0x50, 0x99, 0x45, 0x19, 0x4c, 0x40, 0x0c, 0xde, 0xcf, 0x04, 0xf8, + 0x8c, 0x1e, 0xdb, 0xcf, 0x40, 0x0c, 0x00, 0x0c, 0xed, 0x4f, 0x30, 0xed, + 0xd5, 0xed, 0x5d, 0x18, 0x10, 0x00, 0x5d, 0x18, 0x11, 0x00, 0xa2, 0x41, + 0x03, 0x80, 0x7d, 0x18, 0x14, 0x00, 0x42, 0x30, 0x8d, 0x36, 0xd3, 0xed, + 0x66, 0x45, 0xc2, 0x45, 0x7d, 0x18, 0x15, 0x00, 0xb1, 0x41, 0x01, 0x80, + 0x42, 0x32, 0x09, 0x00, 0x31, 0x32, 0xa1, 0xa4, 0x02, 0xef, 0x8b, 0x6e, + 0x92, 0x0c, 0xf1, 0x45, 0x02, 0x0e, 0x07, 0xad, 0x02, 0xef, 0xa2, 0x41, + 0x59, 0x00, 0x42, 0x30, 0xf8, 0x08, 0x50, 0xf8, 0xf0, 0x01, 0x89, 0x6e, + 0xf1, 0x45, 0x92, 0x0c, 0x18, 0xad, 0xa2, 0x41, 0x59, 0x00, 0x62, 0x30, + 0xf8, 0x08, 0x42, 0x50, 0x58, 0xf3, 0x50, 0xf8, 0xb4, 0x02, 0x40, 0x50, + 0x40, 0x9c, 0x50, 0xf8, 0xb8, 0x02, 0x40, 0x30, 0x8c, 0x0a, 0x50, 0xf8, + 0xc0, 0x02, 0x40, 0x30, 0x88, 0x08, 0x70, 0xf8, 0xb0, 0x02, 0x10, 0xf8, + 0xbc, 0x02, 0x50, 0xf8, 0x04, 0x03, 0x50, 0x0c, 0x26, 0x45, 0x0a, 0x47, + 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x69, 0xcb, 0xe5, 0xcb, + 0xe2, 0x45, 0x00, 0x0c, 0xa3, 0x41, 0x09, 0x80, 0x83, 0xfc, 0x88, 0xfb, + 0x81, 0xed, 0x64, 0xb4, 0x08, 0x00, 0xe5, 0x4b, 0xa3, 0x41, 0x09, 0x80, + 0x63, 0xfc, 0xac, 0x9b, 0x03, 0xf8, 0xec, 0x00, 0xe5, 0x4b, 0x06, 0x47, + 0x09, 0xc9, 0x08, 0x80, 0x1d, 0xc9, 0x08, 0x80, 0x5b, 0xc9, 0x08, 0x80, + 0x01, 0xca, 0x08, 0x80, 0x19, 0xca, 0x08, 0x80, 0x0f, 0xc8, 0x08, 0x80, + 0x21, 0xca, 0x08, 0x80, 0x3d, 0xc8, 0x08, 0x80, 0x75, 0xc8, 0x08, 0x80, + 0xed, 0xc7, 0x08, 0x80, 0xed, 0xc7, 0x08, 0x80, 0xed, 0xc7, 0x08, 0x80, + 0xb5, 0xc7, 0x08, 0x80, 0xed, 0xc7, 0x08, 0x80, 0xed, 0xc7, 0x08, 0x80, + 0x9f, 0xc8, 0x08, 0x80, 0xc1, 0xc8, 0x08, 0x80, 0xed, 0xc7, 0x08, 0x80, + 0xed, 0xc7, 0x08, 0x80, 0xe3, 0xc8, 0x08, 0x80, 0x8d, 0xc8, 0x08, 0x80, + 0x46, 0x34, 0x43, 0x45, 0x33, 0x36, 0x31, 0x31, 0x32, 0x32, 0x33, 0x33, + 0x00, 0x00, 0x00, 0x00, 0x45, 0xe9, 0x08, 0x80, 0x17, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xf3, 0xe8, 0x08, 0x80, + 0xe1, 0xe8, 0x08, 0x80, 0xb5, 0xe8, 0x08, 0x80, 0xa3, 0xe8, 0x08, 0x80, + 0x7d, 0xe8, 0x08, 0x80, 0x6f, 0xe8, 0x08, 0x80, 0x53, 0xe8, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0x41, 0xe8, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, + 0xa3, 0xe9, 0x08, 0x80, 0xa3, 0xe9, 0x08, 0x80, 0x05, 0xe8, 0x08, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x55, 0x4d, 0x41, 0x43, 0x20, 0x3a, 0x20, 0x4c, + 0x4d, 0x41, 0x43, 0x5f, 0x45, 0x56, 0x45, 0x4e, 0x54, 0x5f, 0x50, 0x57, + 0x52, 0x5f, 0x4d, 0x4f, 0x4e, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xf3, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0xa0, 0x9d, 0x13, 0x80, 0x47, 0x43, 0x43, 0x3a, + 0x20, 0x28, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, + 0x47, 0x4e, 0x55, 0x20, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x32, 0x30, + 0x31, 0x37, 0x2e, 0x31, 0x30, 0x2d, 0x30, 0x35, 0x20, 0x66, 0x6f, 0x72, + 0x20, 0x4d, 0x49, 0x50, 0x53, 0x20, 0x4d, 0x54, 0x49, 0x20, 0x42, 0x61, + 0x72, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x29, 0x20, 0x36, 0x2e, + 0x33, 0x2e, 0x30, 0x00, 0x41, 0x0f, 0x00, 0x00, 0x00, 0x67, 0x6e, 0x75, + 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x04, 0x03, 0x7b, 0x6e, 0x01, 0x00, + 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x98, 0xf6, 0x00, 0x00, + 0x0c, 0x12, 0x51, 0x00, 0x00, 0x70, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, 0xf6, 0xc1, 0x00, 0x00, + 0x02, 0x01, 0x06, 0x79, 0x3c, 0x00, 0x00, 0x03, 0x7e, 0x0e, 0x00, 0x00, + 0x06, 0x2b, 0x3a, 0x00, 0x00, 0x00, 0x02, 0x01, 0x08, 0x77, 0x3c, 0x00, + 0x00, 0x04, 0x3a, 0x00, 0x00, 0x00, 0x02, 0x02, 0x05, 0xa8, 0xc9, 0x00, + 0x00, 0x02, 0x02, 0x07, 0x8e, 0x93, 0x00, 0x00, 0x03, 0xa2, 0x84, 0x00, + 0x00, 0x06, 0x4d, 0x5f, 0x00, 0x00, 0x00, 0x02, 0x04, 0x05, 0x8e, 0xfb, + 0x00, 0x00, 0x03, 0xa5, 0x6b, 0x00, 0x00, 0x06, 0x4f, 0x71, 0x00, 0x00, + 0x00, 0x02, 0x04, 0x07, 0xf1, 0xc1, 0x00, 0x00, 0x03, 0x53, 0x25, 0x00, + 0x00, 0x06, 0x67, 0x83, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x89, 0xfb, + 0x00, 0x00, 0x03, 0x2f, 0x11, 0x00, 0x00, 0x06, 0x69, 0x95, 0x00, 0x00, + 0x00, 0x02, 0x08, 0x07, 0xec, 0xc1, 0x00, 0x00, 0x03, 0x12, 0x67, 0x00, + 0x00, 0x06, 0xe8, 0x71, 0x00, 0x00, 0x00, 0x03, 0x80, 0x0e, 0x00, 0x00, + 0x07, 0x18, 0x2f, 0x00, 0x00, 0x00, 0x03, 0xa4, 0x84, 0x00, 0x00, 0x07, + 0x2c, 0x54, 0x00, 0x00, 0x00, 0x05, 0xb2, 0x00, 0x00, 0x00, 0x03, 0xa7, + 0x6b, 0x00, 0x00, 0x07, 0x30, 0x66, 0x00, 0x00, 0x00, 0x05, 0xc2, 0x00, + 0x00, 0x00, 0x03, 0x55, 0x25, 0x00, 0x00, 0x07, 0x38, 0x78, 0x00, 0x00, + 0x00, 0x03, 0x31, 0x11, 0x00, 0x00, 0x07, 0x3c, 0x8a, 0x00, 0x00, 0x00, + 0x03, 0x14, 0x67, 0x00, 0x00, 0x07, 0x52, 0x9c, 0x00, 0x00, 0x00, 0x06, + 0x04, 0x05, 0x69, 0x6e, 0x74, 0x00, 0x04, 0xf3, 0x00, 0x00, 0x00, 0x03, + 0x8d, 0x09, 0x00, 0x00, 0x08, 0xd8, 0x71, 0x00, 0x00, 0x00, 0x02, 0x08, + 0x04, 0x7b, 0xa8, 0x00, 0x00, 0x03, 0xc6, 0x10, 0x00, 0x00, 0x09, 0x07, + 0xf3, 0x00, 0x00, 0x00, 0x03, 0xb2, 0x48, 0x00, 0x00, 0x0a, 0x2c, 0x5f, + 0x00, 0x00, 0x00, 0x03, 0x48, 0x9c, 0x00, 0x00, 0x0a, 0x72, 0x5f, 0x00, + 0x00, 0x00, 0x07, 0xf5, 0x8f, 0x00, 0x00, 0x08, 0x65, 0x01, 0x21, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x0a, 0xa6, 0x5d, 0x01, 0x00, 0x00, 0x09, 0x81, + 0x59, 0x00, 0x00, 0x0a, 0xa8, 0x32, 0x01, 0x00, 0x00, 0x09, 0x73, 0x33, + 0x00, 0x00, 0x0a, 0xa9, 0x5d, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x3a, 0x00, + 0x00, 0x00, 0x6d, 0x01, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x03, + 0x00, 0x02, 0x04, 0x07, 0xd5, 0xab, 0x00, 0x00, 0x0c, 0x08, 0x0a, 0xa3, + 0x95, 0x01, 0x00, 0x00, 0x0d, 0x7c, 0xf2, 0x00, 0x00, 0x0a, 0xa5, 0xf3, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0xf3, 0x56, 0x00, 0x00, 0x0a, 0xaa, 0x3e, + 0x01, 0x00, 0x00, 0x04, 0x00, 0x03, 0xd6, 0xa1, 0x00, 0x00, 0x0a, 0xab, + 0x74, 0x01, 0x00, 0x00, 0x03, 0x4e, 0x48, 0x00, 0x00, 0x0a, 0xaf, 0x11, + 0x01, 0x00, 0x00, 0x0e, 0x04, 0x03, 0x7e, 0x8d, 0x00, 0x00, 0x0b, 0x16, + 0x71, 0x00, 0x00, 0x00, 0x0f, 0x4b, 0x4a, 0x00, 0x00, 0x18, 0x0b, 0x2f, + 0x0b, 0x02, 0x00, 0x00, 0x0d, 0x16, 0x20, 0x00, 0x00, 0x0b, 0x31, 0x0b, + 0x02, 0x00, 0x00, 0x00, 0x10, 0x5f, 0x6b, 0x00, 0x0b, 0x32, 0xf3, 0x00, + 0x00, 0x00, 0x04, 0x0d, 0x9a, 0x01, 0x00, 0x00, 0x0b, 0x32, 0xf3, 0x00, + 0x00, 0x00, 0x08, 0x0d, 0x37, 0xbf, 0x00, 0x00, 0x0b, 0x32, 0xf3, 0x00, + 0x00, 0x00, 0x0c, 0x0d, 0xb0, 0x3b, 0x00, 0x00, 0x0b, 0x32, 0xf3, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x5f, 0x78, 0x00, 0x0b, 0x33, 0x11, 0x02, 0x00, + 0x00, 0x14, 0x00, 0x11, 0x04, 0xb8, 0x01, 0x00, 0x00, 0x0a, 0xad, 0x01, + 0x00, 0x00, 0x21, 0x02, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x01, 0x97, 0x00, 0x00, 0x24, 0x0b, 0x37, 0x9a, 0x02, 0x00, + 0x00, 0x0d, 0x21, 0x28, 0x00, 0x00, 0x0b, 0x39, 0xf3, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x89, 0x88, 0x00, 0x00, 0x0b, 0x3a, 0xf3, 0x00, 0x00, 0x00, + 0x04, 0x0d, 0x98, 0xe7, 0x00, 0x00, 0x0b, 0x3b, 0xf3, 0x00, 0x00, 0x00, + 0x08, 0x0d, 0x5c, 0x9c, 0x00, 0x00, 0x0b, 0x3c, 0xf3, 0x00, 0x00, 0x00, + 0x0c, 0x0d, 0xa9, 0x8e, 0x00, 0x00, 0x0b, 0x3d, 0xf3, 0x00, 0x00, 0x00, + 0x10, 0x0d, 0xbe, 0x36, 0x00, 0x00, 0x0b, 0x3e, 0xf3, 0x00, 0x00, 0x00, + 0x14, 0x0d, 0xe4, 0x37, 0x00, 0x00, 0x0b, 0x3f, 0xf3, 0x00, 0x00, 0x00, + 0x18, 0x0d, 0xde, 0xf0, 0x00, 0x00, 0x0b, 0x40, 0xf3, 0x00, 0x00, 0x00, + 0x1c, 0x0d, 0xdd, 0x0d, 0x00, 0x00, 0x0b, 0x41, 0xf3, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x12, 0xb3, 0xc6, 0x00, 0x00, 0x08, 0x01, 0x0b, 0x4a, 0xda, + 0x02, 0x00, 0x00, 0x0d, 0xc1, 0x06, 0x00, 0x00, 0x0b, 0x4b, 0xda, 0x02, + 0x00, 0x00, 0x00, 0x0d, 0x32, 0x2f, 0x00, 0x00, 0x0b, 0x4c, 0xda, 0x02, + 0x00, 0x00, 0x80, 0x13, 0x31, 0xbe, 0x00, 0x00, 0x0b, 0x4e, 0xad, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x13, 0x14, 0x8a, 0x00, 0x00, 0x0b, 0x51, 0xad, + 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0a, 0xab, 0x01, 0x00, 0x00, 0xea, + 0x02, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x12, 0xb8, + 0x1a, 0x00, 0x00, 0x90, 0x01, 0x0b, 0x5d, 0x28, 0x03, 0x00, 0x00, 0x0d, + 0x16, 0x20, 0x00, 0x00, 0x0b, 0x5e, 0x28, 0x03, 0x00, 0x00, 0x00, 0x0d, + 0xb1, 0x4b, 0x00, 0x00, 0x0b, 0x5f, 0xf3, 0x00, 0x00, 0x00, 0x04, 0x0d, + 0x64, 0x7a, 0x00, 0x00, 0x0b, 0x61, 0x2e, 0x03, 0x00, 0x00, 0x08, 0x0d, + 0xb3, 0xc6, 0x00, 0x00, 0x0b, 0x62, 0x9a, 0x02, 0x00, 0x00, 0x88, 0x00, + 0x11, 0x04, 0xea, 0x02, 0x00, 0x00, 0x0a, 0x3e, 0x03, 0x00, 0x00, 0x3e, + 0x03, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x11, 0x04, + 0x44, 0x03, 0x00, 0x00, 0x14, 0x0f, 0x0d, 0x8a, 0x00, 0x00, 0x08, 0x0b, + 0x75, 0x6a, 0x03, 0x00, 0x00, 0x0d, 0x51, 0x01, 0x00, 0x00, 0x0b, 0x76, + 0x6a, 0x03, 0x00, 0x00, 0x00, 0x0d, 0x2f, 0x9e, 0x00, 0x00, 0x0b, 0x77, + 0xf3, 0x00, 0x00, 0x00, 0x04, 0x00, 0x11, 0x04, 0x3a, 0x00, 0x00, 0x00, + 0x0f, 0xa9, 0x62, 0x00, 0x00, 0x68, 0x0b, 0xb5, 0x9a, 0x04, 0x00, 0x00, + 0x10, 0x5f, 0x70, 0x00, 0x0b, 0xb6, 0x6a, 0x03, 0x00, 0x00, 0x00, 0x10, + 0x5f, 0x72, 0x00, 0x0b, 0xb7, 0xf3, 0x00, 0x00, 0x00, 0x04, 0x10, 0x5f, + 0x77, 0x00, 0x0b, 0xb8, 0xf3, 0x00, 0x00, 0x00, 0x08, 0x0d, 0x25, 0xab, + 0x00, 0x00, 0x0b, 0xb9, 0x46, 0x00, 0x00, 0x00, 0x0c, 0x0d, 0x34, 0x9c, + 0x00, 0x00, 0x0b, 0xba, 0x46, 0x00, 0x00, 0x00, 0x0e, 0x10, 0x5f, 0x62, + 0x66, 0x00, 0x0b, 0xbb, 0x45, 0x03, 0x00, 0x00, 0x10, 0x0d, 0x09, 0x0d, + 0x00, 0x00, 0x0b, 0xbc, 0xf3, 0x00, 0x00, 0x00, 0x18, 0x0d, 0x2a, 0x2f, + 0x00, 0x00, 0x0b, 0xc3, 0xab, 0x01, 0x00, 0x00, 0x1c, 0x0d, 0x77, 0x42, + 0x00, 0x00, 0x0b, 0xc5, 0x07, 0x06, 0x00, 0x00, 0x20, 0x0d, 0xbe, 0xbd, + 0x00, 0x00, 0x0b, 0xc7, 0x36, 0x06, 0x00, 0x00, 0x24, 0x0d, 0x3e, 0xa3, + 0x00, 0x00, 0x0b, 0xca, 0x5a, 0x06, 0x00, 0x00, 0x28, 0x0d, 0xb5, 0x2d, + 0x00, 0x00, 0x0b, 0xcb, 0x74, 0x06, 0x00, 0x00, 0x2c, 0x10, 0x5f, 0x75, + 0x62, 0x00, 0x0b, 0xce, 0x45, 0x03, 0x00, 0x00, 0x30, 0x10, 0x5f, 0x75, + 0x70, 0x00, 0x0b, 0xcf, 0x6a, 0x03, 0x00, 0x00, 0x38, 0x10, 0x5f, 0x75, + 0x72, 0x00, 0x0b, 0xd0, 0xf3, 0x00, 0x00, 0x00, 0x3c, 0x0d, 0xff, 0x9a, + 0x00, 0x00, 0x0b, 0xd3, 0x7a, 0x06, 0x00, 0x00, 0x40, 0x0d, 0x22, 0x17, + 0x00, 0x00, 0x0b, 0xd4, 0x8a, 0x06, 0x00, 0x00, 0x43, 0x10, 0x5f, 0x6c, + 0x62, 0x00, 0x0b, 0xd7, 0x45, 0x03, 0x00, 0x00, 0x44, 0x0d, 0x49, 0x3e, + 0x00, 0x00, 0x0b, 0xda, 0xf3, 0x00, 0x00, 0x00, 0x4c, 0x0d, 0x6a, 0x04, + 0x00, 0x00, 0x0b, 0xdb, 0x1c, 0x01, 0x00, 0x00, 0x50, 0x0d, 0x0a, 0x7e, + 0x00, 0x00, 0x0b, 0xde, 0xb8, 0x04, 0x00, 0x00, 0x54, 0x0d, 0x83, 0xde, + 0x00, 0x00, 0x0b, 0xe2, 0xa0, 0x01, 0x00, 0x00, 0x58, 0x0d, 0x9b, 0x9a, + 0x00, 0x00, 0x0b, 0xe4, 0x95, 0x01, 0x00, 0x00, 0x5c, 0x0d, 0x2f, 0xbf, + 0x00, 0x00, 0x0b, 0xe5, 0xf3, 0x00, 0x00, 0x00, 0x64, 0x00, 0x15, 0xf3, + 0x00, 0x00, 0x00, 0xb8, 0x04, 0x00, 0x00, 0x16, 0xb8, 0x04, 0x00, 0x00, + 0x16, 0xab, 0x01, 0x00, 0x00, 0x16, 0xf5, 0x05, 0x00, 0x00, 0x16, 0xf3, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0xc3, 0x04, 0x00, 0x00, 0x04, 0xb8, + 0x04, 0x00, 0x00, 0x17, 0x1c, 0x2d, 0x00, 0x00, 0x28, 0x04, 0x0b, 0x39, + 0x02, 0xf5, 0x05, 0x00, 0x00, 0x18, 0xfe, 0x9e, 0x00, 0x00, 0x0b, 0x3b, + 0x02, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x18, 0xc9, 0x6d, 0x00, 0x00, 0x0b, + 0x40, 0x02, 0xe1, 0x06, 0x00, 0x00, 0x04, 0x18, 0x19, 0xa8, 0x00, 0x00, + 0x0b, 0x40, 0x02, 0xe1, 0x06, 0x00, 0x00, 0x08, 0x18, 0xf6, 0xe8, 0x00, + 0x00, 0x0b, 0x40, 0x02, 0xe1, 0x06, 0x00, 0x00, 0x0c, 0x18, 0xac, 0x4b, + 0x00, 0x00, 0x0b, 0x42, 0x02, 0xf3, 0x00, 0x00, 0x00, 0x10, 0x18, 0x0c, + 0xa1, 0x00, 0x00, 0x0b, 0x43, 0x02, 0xc3, 0x08, 0x00, 0x00, 0x14, 0x18, + 0xee, 0x36, 0x00, 0x00, 0x0b, 0x46, 0x02, 0xf3, 0x00, 0x00, 0x00, 0x30, + 0x18, 0x59, 0x5c, 0x00, 0x00, 0x0b, 0x47, 0x02, 0xd8, 0x08, 0x00, 0x00, + 0x34, 0x18, 0xe6, 0xb6, 0x00, 0x00, 0x0b, 0x49, 0x02, 0xf3, 0x00, 0x00, + 0x00, 0x38, 0x18, 0xb3, 0x54, 0x00, 0x00, 0x0b, 0x4b, 0x02, 0xe9, 0x08, + 0x00, 0x00, 0x3c, 0x18, 0xf2, 0x35, 0x00, 0x00, 0x0b, 0x4e, 0x02, 0x0b, + 0x02, 0x00, 0x00, 0x40, 0x18, 0xc1, 0xdd, 0x00, 0x00, 0x0b, 0x4f, 0x02, + 0xf3, 0x00, 0x00, 0x00, 0x44, 0x18, 0x1b, 0x00, 0x00, 0x00, 0x0b, 0x50, + 0x02, 0x0b, 0x02, 0x00, 0x00, 0x48, 0x18, 0x39, 0x15, 0x00, 0x00, 0x0b, + 0x51, 0x02, 0xef, 0x08, 0x00, 0x00, 0x4c, 0x18, 0x73, 0xdf, 0x00, 0x00, + 0x0b, 0x54, 0x02, 0xf3, 0x00, 0x00, 0x00, 0x50, 0x18, 0xe8, 0x33, 0x00, + 0x00, 0x0b, 0x55, 0x02, 0xf5, 0x05, 0x00, 0x00, 0x54, 0x18, 0xaf, 0xa1, + 0x00, 0x00, 0x0b, 0x78, 0x02, 0xa1, 0x08, 0x00, 0x00, 0x58, 0x19, 0xb8, + 0x1a, 0x00, 0x00, 0x0b, 0x7c, 0x02, 0x28, 0x03, 0x00, 0x00, 0x48, 0x01, + 0x19, 0x33, 0x27, 0x00, 0x00, 0x0b, 0x7d, 0x02, 0xea, 0x02, 0x00, 0x00, + 0x4c, 0x01, 0x19, 0xfb, 0xc8, 0x00, 0x00, 0x0b, 0x81, 0x02, 0x00, 0x09, + 0x00, 0x00, 0xdc, 0x02, 0x19, 0x45, 0x10, 0x00, 0x00, 0x0b, 0x86, 0x02, + 0xa6, 0x06, 0x00, 0x00, 0xe0, 0x02, 0x19, 0xb5, 0x95, 0x00, 0x00, 0x0b, + 0x87, 0x02, 0x0c, 0x09, 0x00, 0x00, 0xec, 0x02, 0x00, 0x11, 0x04, 0xfb, + 0x05, 0x00, 0x00, 0x02, 0x01, 0x08, 0x80, 0x3c, 0x00, 0x00, 0x04, 0xfb, + 0x05, 0x00, 0x00, 0x11, 0x04, 0x9a, 0x04, 0x00, 0x00, 0x15, 0xf3, 0x00, + 0x00, 0x00, 0x2b, 0x06, 0x00, 0x00, 0x16, 0xb8, 0x04, 0x00, 0x00, 0x16, + 0xab, 0x01, 0x00, 0x00, 0x16, 0x2b, 0x06, 0x00, 0x00, 0x16, 0xf3, 0x00, + 0x00, 0x00, 0x00, 0x11, 0x04, 0x02, 0x06, 0x00, 0x00, 0x04, 0x2b, 0x06, + 0x00, 0x00, 0x11, 0x04, 0x0d, 0x06, 0x00, 0x00, 0x15, 0x27, 0x01, 0x00, + 0x00, 0x5a, 0x06, 0x00, 0x00, 0x16, 0xb8, 0x04, 0x00, 0x00, 0x16, 0xab, + 0x01, 0x00, 0x00, 0x16, 0x27, 0x01, 0x00, 0x00, 0x16, 0xf3, 0x00, 0x00, + 0x00, 0x00, 0x11, 0x04, 0x3c, 0x06, 0x00, 0x00, 0x15, 0xf3, 0x00, 0x00, + 0x00, 0x74, 0x06, 0x00, 0x00, 0x16, 0xb8, 0x04, 0x00, 0x00, 0x16, 0xab, + 0x01, 0x00, 0x00, 0x00, 0x11, 0x04, 0x60, 0x06, 0x00, 0x00, 0x0a, 0x3a, + 0x00, 0x00, 0x00, 0x8a, 0x06, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, + 0x02, 0x00, 0x0a, 0x3a, 0x00, 0x00, 0x00, 0x9a, 0x06, 0x00, 0x00, 0x0b, + 0x6d, 0x01, 0x00, 0x00, 0x00, 0x00, 0x07, 0x68, 0x49, 0x00, 0x00, 0x0b, + 0x1f, 0x01, 0x70, 0x03, 0x00, 0x00, 0x1a, 0xca, 0x4a, 0x00, 0x00, 0x0c, + 0x0b, 0x23, 0x01, 0xdb, 0x06, 0x00, 0x00, 0x18, 0x16, 0x20, 0x00, 0x00, + 0x0b, 0x25, 0x01, 0xdb, 0x06, 0x00, 0x00, 0x00, 0x18, 0x91, 0xb1, 0x00, + 0x00, 0x0b, 0x26, 0x01, 0xf3, 0x00, 0x00, 0x00, 0x04, 0x18, 0x34, 0xc4, + 0x00, 0x00, 0x0b, 0x27, 0x01, 0xe1, 0x06, 0x00, 0x00, 0x08, 0x00, 0x11, + 0x04, 0xa6, 0x06, 0x00, 0x00, 0x11, 0x04, 0x9a, 0x06, 0x00, 0x00, 0x1a, + 0xfe, 0xe7, 0x00, 0x00, 0x0e, 0x0b, 0x3f, 0x01, 0x1c, 0x07, 0x00, 0x00, + 0x18, 0x0f, 0xa3, 0x00, 0x00, 0x0b, 0x40, 0x01, 0x1c, 0x07, 0x00, 0x00, + 0x00, 0x18, 0xa8, 0xe4, 0x00, 0x00, 0x0b, 0x41, 0x01, 0x1c, 0x07, 0x00, + 0x00, 0x06, 0x18, 0x92, 0x15, 0x00, 0x00, 0x0b, 0x42, 0x01, 0x4d, 0x00, + 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x4d, 0x00, 0x00, 0x00, 0x2c, 0x07, 0x00, + 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x02, 0x00, 0x1b, 0xd0, 0x0b, 0x59, + 0x02, 0x2d, 0x08, 0x00, 0x00, 0x18, 0xd8, 0x97, 0x00, 0x00, 0x0b, 0x5b, + 0x02, 0x21, 0x00, 0x00, 0x00, 0x00, 0x18, 0x3c, 0x21, 0x00, 0x00, 0x0b, + 0x5c, 0x02, 0xf5, 0x05, 0x00, 0x00, 0x04, 0x18, 0xe4, 0x28, 0x00, 0x00, + 0x0b, 0x5d, 0x02, 0x2d, 0x08, 0x00, 0x00, 0x08, 0x18, 0x06, 0xd4, 0x00, + 0x00, 0x0b, 0x5e, 0x02, 0x21, 0x02, 0x00, 0x00, 0x24, 0x18, 0xea, 0xab, + 0x00, 0x00, 0x0b, 0x5f, 0x02, 0xf3, 0x00, 0x00, 0x00, 0x48, 0x18, 0x8d, + 0xf6, 0x00, 0x00, 0x0b, 0x60, 0x02, 0x95, 0x00, 0x00, 0x00, 0x50, 0x18, + 0x9e, 0x87, 0x00, 0x00, 0x0b, 0x61, 0x02, 0xe7, 0x06, 0x00, 0x00, 0x58, + 0x18, 0xce, 0x37, 0x00, 0x00, 0x0b, 0x62, 0x02, 0x95, 0x01, 0x00, 0x00, + 0x68, 0x18, 0xa0, 0xc0, 0x00, 0x00, 0x0b, 0x63, 0x02, 0x95, 0x01, 0x00, + 0x00, 0x70, 0x18, 0xc0, 0xf1, 0x00, 0x00, 0x0b, 0x64, 0x02, 0x95, 0x01, + 0x00, 0x00, 0x78, 0x18, 0xff, 0x97, 0x00, 0x00, 0x0b, 0x65, 0x02, 0x3d, + 0x08, 0x00, 0x00, 0x80, 0x18, 0x03, 0xd2, 0x00, 0x00, 0x0b, 0x66, 0x02, + 0x4d, 0x08, 0x00, 0x00, 0x88, 0x18, 0xf1, 0x53, 0x00, 0x00, 0x0b, 0x67, + 0x02, 0xf3, 0x00, 0x00, 0x00, 0xa0, 0x18, 0x5c, 0x20, 0x00, 0x00, 0x0b, + 0x68, 0x02, 0x95, 0x01, 0x00, 0x00, 0xa4, 0x18, 0x7e, 0x8a, 0x00, 0x00, + 0x0b, 0x69, 0x02, 0x95, 0x01, 0x00, 0x00, 0xac, 0x18, 0x66, 0xee, 0x00, + 0x00, 0x0b, 0x6a, 0x02, 0x95, 0x01, 0x00, 0x00, 0xb4, 0x18, 0x88, 0xad, + 0x00, 0x00, 0x0b, 0x6b, 0x02, 0x95, 0x01, 0x00, 0x00, 0xbc, 0x18, 0x73, + 0xc0, 0x00, 0x00, 0x0b, 0x6c, 0x02, 0x95, 0x01, 0x00, 0x00, 0xc4, 0x18, + 0xfc, 0x9e, 0x00, 0x00, 0x0b, 0x6d, 0x02, 0xf3, 0x00, 0x00, 0x00, 0xcc, + 0x00, 0x0a, 0xfb, 0x05, 0x00, 0x00, 0x3d, 0x08, 0x00, 0x00, 0x0b, 0x6d, + 0x01, 0x00, 0x00, 0x19, 0x00, 0x0a, 0xfb, 0x05, 0x00, 0x00, 0x4d, 0x08, + 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x07, 0x00, 0x0a, 0xfb, 0x05, + 0x00, 0x00, 0x5d, 0x08, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x17, + 0x00, 0x1b, 0xf0, 0x0b, 0x72, 0x02, 0x81, 0x08, 0x00, 0x00, 0x18, 0x85, + 0xcb, 0x00, 0x00, 0x0b, 0x75, 0x02, 0x81, 0x08, 0x00, 0x00, 0x00, 0x18, + 0x75, 0x72, 0x00, 0x00, 0x0b, 0x76, 0x02, 0x91, 0x08, 0x00, 0x00, 0x78, + 0x00, 0x0a, 0x6a, 0x03, 0x00, 0x00, 0x91, 0x08, 0x00, 0x00, 0x0b, 0x6d, + 0x01, 0x00, 0x00, 0x1d, 0x00, 0x0a, 0x21, 0x00, 0x00, 0x00, 0xa1, 0x08, + 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x1d, 0x00, 0x1c, 0xf0, 0x0b, + 0x57, 0x02, 0xc3, 0x08, 0x00, 0x00, 0x1d, 0x1c, 0x2d, 0x00, 0x00, 0x0b, + 0x6e, 0x02, 0x2c, 0x07, 0x00, 0x00, 0x1d, 0x5d, 0x45, 0x00, 0x00, 0x0b, + 0x77, 0x02, 0x5d, 0x08, 0x00, 0x00, 0x00, 0x0a, 0xfb, 0x05, 0x00, 0x00, + 0xd3, 0x08, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x18, 0x00, 0x1e, + 0x07, 0xbd, 0x00, 0x00, 0x11, 0x04, 0xd3, 0x08, 0x00, 0x00, 0x1f, 0xe9, + 0x08, 0x00, 0x00, 0x16, 0xb8, 0x04, 0x00, 0x00, 0x00, 0x11, 0x04, 0xde, + 0x08, 0x00, 0x00, 0x11, 0x04, 0x0b, 0x02, 0x00, 0x00, 0x1f, 0x00, 0x09, + 0x00, 0x00, 0x16, 0xf3, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0x06, 0x09, + 0x00, 0x00, 0x11, 0x04, 0xf5, 0x08, 0x00, 0x00, 0x0a, 0x9a, 0x06, 0x00, + 0x00, 0x1c, 0x09, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x02, 0x00, + 0x20, 0xaa, 0xec, 0x00, 0x00, 0x0b, 0xfe, 0x02, 0xb8, 0x04, 0x00, 0x00, + 0x20, 0xa3, 0xec, 0x00, 0x00, 0x0b, 0xff, 0x02, 0xbe, 0x04, 0x00, 0x00, + 0x03, 0x6a, 0x49, 0x00, 0x00, 0x0c, 0x42, 0x9a, 0x06, 0x00, 0x00, 0x0c, + 0x04, 0x0d, 0x25, 0x54, 0x09, 0x00, 0x00, 0x0d, 0x39, 0xd7, 0x00, 0x00, + 0x0d, 0x28, 0x54, 0x09, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0xab, 0x01, + 0x00, 0x00, 0x03, 0x45, 0x60, 0x00, 0x00, 0x0d, 0x31, 0x3f, 0x09, 0x00, + 0x00, 0x0c, 0x08, 0x0d, 0x32, 0x86, 0x09, 0x00, 0x00, 0x0d, 0x39, 0xd7, + 0x00, 0x00, 0x0d, 0x35, 0x54, 0x09, 0x00, 0x00, 0x00, 0x0d, 0x44, 0x21, + 0x00, 0x00, 0x0d, 0x37, 0x54, 0x09, 0x00, 0x00, 0x04, 0x00, 0x03, 0x19, + 0x89, 0x00, 0x00, 0x0d, 0x3a, 0x65, 0x09, 0x00, 0x00, 0x03, 0x6c, 0x0c, + 0x00, 0x00, 0x0e, 0x21, 0xb2, 0x00, 0x00, 0x00, 0x07, 0xd2, 0x02, 0x00, + 0x00, 0x0f, 0x05, 0x04, 0x21, 0x00, 0x00, 0x00, 0x21, 0x46, 0x05, 0x00, + 0x00, 0x10, 0x41, 0xf3, 0x00, 0x00, 0x00, 0x21, 0x87, 0xe4, 0x00, 0x00, + 0x10, 0x41, 0xf3, 0x00, 0x00, 0x00, 0x21, 0x14, 0x41, 0x00, 0x00, 0x10, + 0x41, 0xf3, 0x00, 0x00, 0x00, 0x21, 0xbf, 0xe9, 0x00, 0x00, 0x10, 0x42, + 0xf3, 0x00, 0x00, 0x00, 0x21, 0x82, 0x70, 0x00, 0x00, 0x10, 0x42, 0xf3, + 0x00, 0x00, 0x00, 0x21, 0x56, 0x29, 0x00, 0x00, 0x10, 0x42, 0xf3, 0x00, + 0x00, 0x00, 0x21, 0x73, 0x37, 0x00, 0x00, 0x10, 0x43, 0xf3, 0x00, 0x00, + 0x00, 0x21, 0x10, 0xc9, 0x00, 0x00, 0x10, 0x43, 0xf3, 0x00, 0x00, 0x00, + 0x21, 0x59, 0x74, 0x00, 0x00, 0x10, 0x43, 0xf3, 0x00, 0x00, 0x00, 0x21, + 0x7d, 0xd5, 0x00, 0x00, 0x10, 0x44, 0xf3, 0x00, 0x00, 0x00, 0x21, 0x4e, + 0xa9, 0x00, 0x00, 0x10, 0x44, 0xf3, 0x00, 0x00, 0x00, 0x21, 0x3c, 0x17, + 0x00, 0x00, 0x10, 0x44, 0xf3, 0x00, 0x00, 0x00, 0x0c, 0x7c, 0x11, 0xef, + 0xaa, 0x0a, 0x00, 0x00, 0x10, 0x61, 0x74, 0x00, 0x11, 0xf1, 0x9c, 0x09, + 0x00, 0x00, 0x00, 0x10, 0x76, 0x00, 0x11, 0xf2, 0xaa, 0x0a, 0x00, 0x00, + 0x04, 0x10, 0x61, 0x00, 0x11, 0xf7, 0xba, 0x0a, 0x00, 0x00, 0x0c, 0x10, + 0x74, 0x00, 0x11, 0xf8, 0xca, 0x0a, 0x00, 0x00, 0x1c, 0x10, 0x73, 0x00, + 0x11, 0xfa, 0xca, 0x0a, 0x00, 0x00, 0x3c, 0x10, 0x74, 0x32, 0x00, 0x11, + 0xfb, 0xaa, 0x0a, 0x00, 0x00, 0x5c, 0x10, 0x6b, 0x00, 0x11, 0xfc, 0xaa, + 0x0a, 0x00, 0x00, 0x64, 0x10, 0x67, 0x70, 0x00, 0x11, 0xfd, 0x9c, 0x09, + 0x00, 0x00, 0x6c, 0x10, 0x73, 0x70, 0x00, 0x11, 0xfe, 0x9c, 0x09, 0x00, + 0x00, 0x70, 0x10, 0x66, 0x70, 0x00, 0x11, 0xff, 0x9c, 0x09, 0x00, 0x00, + 0x74, 0x22, 0x72, 0x61, 0x00, 0x11, 0x00, 0x01, 0x9c, 0x09, 0x00, 0x00, + 0x78, 0x00, 0x0a, 0x9c, 0x09, 0x00, 0x00, 0xba, 0x0a, 0x00, 0x00, 0x0b, + 0x6d, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0a, 0x9c, 0x09, 0x00, 0x00, 0xca, + 0x0a, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x9c, + 0x09, 0x00, 0x00, 0xda, 0x0a, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, + 0x07, 0x00, 0x08, 0x7c, 0x11, 0xed, 0xf2, 0x0a, 0x00, 0x00, 0x23, 0x2c, + 0x0a, 0x00, 0x00, 0x24, 0x72, 0x00, 0x11, 0x02, 0x01, 0xf2, 0x0a, 0x00, + 0x00, 0x00, 0x0a, 0x9c, 0x09, 0x00, 0x00, 0x02, 0x0b, 0x00, 0x00, 0x0b, + 0x6d, 0x01, 0x00, 0x00, 0x1e, 0x00, 0x0f, 0xc2, 0x48, 0x00, 0x00, 0xa0, + 0x11, 0xeb, 0x88, 0x0b, 0x00, 0x00, 0x25, 0xda, 0x0a, 0x00, 0x00, 0x00, + 0x22, 0x65, 0x70, 0x63, 0x00, 0x11, 0x05, 0x01, 0x9c, 0x09, 0x00, 0x00, + 0x7c, 0x18, 0xfd, 0xad, 0x00, 0x00, 0x11, 0x06, 0x01, 0x9c, 0x09, 0x00, + 0x00, 0x80, 0x22, 0x68, 0x69, 0x00, 0x11, 0x07, 0x01, 0x9c, 0x09, 0x00, + 0x00, 0x84, 0x22, 0x6c, 0x6f, 0x00, 0x11, 0x08, 0x01, 0x9c, 0x09, 0x00, + 0x00, 0x88, 0x18, 0x3c, 0x73, 0x00, 0x00, 0x11, 0x0a, 0x01, 0xaf, 0x0b, + 0x00, 0x00, 0x8c, 0x18, 0x28, 0x1c, 0x00, 0x00, 0x11, 0x0d, 0x01, 0xc2, + 0x00, 0x00, 0x00, 0x90, 0x18, 0x3a, 0x34, 0x00, 0x00, 0x11, 0x0f, 0x01, + 0xc2, 0x00, 0x00, 0x00, 0x94, 0x18, 0x46, 0x92, 0x00, 0x00, 0x11, 0x10, + 0x01, 0xc2, 0x00, 0x00, 0x00, 0x98, 0x18, 0x39, 0x53, 0x00, 0x00, 0x11, + 0x11, 0x01, 0xc2, 0x00, 0x00, 0x00, 0x9c, 0x00, 0x1a, 0x83, 0xda, 0x00, + 0x00, 0x08, 0x11, 0x14, 0x01, 0xaf, 0x0b, 0x00, 0x00, 0x22, 0x69, 0x64, + 0x00, 0x11, 0x16, 0x01, 0x9c, 0x09, 0x00, 0x00, 0x00, 0x18, 0x17, 0x20, + 0x00, 0x00, 0x11, 0x17, 0x01, 0xaf, 0x0b, 0x00, 0x00, 0x04, 0x00, 0x11, + 0x04, 0x88, 0x0b, 0x00, 0x00, 0x0a, 0xfb, 0x05, 0x00, 0x00, 0xc5, 0x0b, + 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x0f, 0x00, 0x02, 0x08, 0x04, + 0x80, 0xa8, 0x00, 0x00, 0x02, 0x04, 0x04, 0x36, 0xe8, 0x00, 0x00, 0x0f, + 0x3c, 0x08, 0x00, 0x00, 0xa4, 0x12, 0x33, 0xf7, 0x0b, 0x00, 0x00, 0x10, + 0x67, 0x70, 0x00, 0x12, 0x34, 0x02, 0x0b, 0x00, 0x00, 0x00, 0x0d, 0x65, + 0xa1, 0x00, 0x00, 0x12, 0x35, 0x9c, 0x09, 0x00, 0x00, 0xa0, 0x00, 0x03, + 0xc4, 0xe5, 0x00, 0x00, 0x12, 0x42, 0xd3, 0x0b, 0x00, 0x00, 0x21, 0xb4, + 0x30, 0x00, 0x00, 0x13, 0x2c, 0xbd, 0x00, 0x00, 0x00, 0x21, 0x52, 0x04, + 0x00, 0x00, 0x13, 0x2d, 0xb2, 0x00, 0x00, 0x00, 0x21, 0x30, 0x9c, 0x00, + 0x00, 0x14, 0x2e, 0x23, 0x0c, 0x00, 0x00, 0x11, 0x04, 0x34, 0x09, 0x00, + 0x00, 0x0a, 0xf3, 0x00, 0x00, 0x00, 0x34, 0x0c, 0x00, 0x00, 0x26, 0x00, + 0x21, 0xe0, 0x43, 0x00, 0x00, 0x14, 0x39, 0x29, 0x0c, 0x00, 0x00, 0x21, + 0x9e, 0x9e, 0x00, 0x00, 0x14, 0x3a, 0x29, 0x0c, 0x00, 0x00, 0x0f, 0x02, + 0x0d, 0x00, 0x00, 0x08, 0x15, 0x25, 0x6f, 0x0c, 0x00, 0x00, 0x10, 0x66, + 0x77, 0x64, 0x00, 0x15, 0x28, 0x6f, 0x0c, 0x00, 0x00, 0x00, 0x0d, 0xf2, + 0x60, 0x00, 0x00, 0x15, 0x2a, 0x6f, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x11, + 0x04, 0x4a, 0x0c, 0x00, 0x00, 0x03, 0x0d, 0xcc, 0x00, 0x00, 0x15, 0x2d, + 0x4a, 0x0c, 0x00, 0x00, 0x0c, 0x08, 0x15, 0x2e, 0x95, 0x0c, 0x00, 0x00, + 0x0d, 0x39, 0x73, 0x00, 0x00, 0x15, 0x30, 0x75, 0x0c, 0x00, 0x00, 0x00, + 0x00, 0x03, 0x8b, 0xed, 0x00, 0x00, 0x15, 0x32, 0x80, 0x0c, 0x00, 0x00, + 0x04, 0x95, 0x0c, 0x00, 0x00, 0x03, 0xa0, 0x8b, 0x00, 0x00, 0x16, 0x1c, + 0xb0, 0x0c, 0x00, 0x00, 0x0f, 0x67, 0x6f, 0x00, 0x00, 0x08, 0x16, 0x46, + 0xd5, 0x0c, 0x00, 0x00, 0x0d, 0x17, 0x20, 0x00, 0x00, 0x16, 0x48, 0xab, + 0x01, 0x00, 0x00, 0x00, 0x0d, 0x7e, 0x5f, 0x00, 0x00, 0x16, 0x49, 0xab, + 0x01, 0x00, 0x00, 0x04, 0x00, 0x03, 0xdd, 0x7f, 0x00, 0x00, 0x17, 0xa7, + 0x95, 0x0c, 0x00, 0x00, 0x03, 0x28, 0x91, 0x00, 0x00, 0x17, 0xa8, 0xb2, + 0x00, 0x00, 0x00, 0x03, 0xa3, 0x16, 0x00, 0x00, 0x17, 0xa9, 0x91, 0x09, + 0x00, 0x00, 0x0c, 0x0c, 0x17, 0xba, 0x17, 0x0d, 0x00, 0x00, 0x0d, 0xf5, + 0x56, 0x00, 0x00, 0x17, 0xc3, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x88, + 0xf4, 0x00, 0x00, 0x17, 0xc5, 0xd5, 0x0c, 0x00, 0x00, 0x04, 0x00, 0x03, + 0xe8, 0xb2, 0x00, 0x00, 0x17, 0xc8, 0xf6, 0x0c, 0x00, 0x00, 0x03, 0xe2, + 0xbf, 0x00, 0x00, 0x17, 0xfa, 0x17, 0x0d, 0x00, 0x00, 0x03, 0x03, 0xe0, + 0x00, 0x00, 0x17, 0xfd, 0x38, 0x0d, 0x00, 0x00, 0x1a, 0xa0, 0x6f, 0x00, + 0x00, 0xe4, 0x17, 0x15, 0x02, 0x07, 0x0e, 0x00, 0x00, 0x18, 0xa7, 0x1d, + 0x00, 0x00, 0x17, 0x16, 0x02, 0xbe, 0x0e, 0x00, 0x00, 0x00, 0x18, 0xc4, + 0x6b, 0x00, 0x00, 0x17, 0x18, 0x02, 0x3e, 0x03, 0x00, 0x00, 0x0c, 0x18, + 0xc8, 0x74, 0x00, 0x00, 0x17, 0x19, 0x02, 0x3e, 0x03, 0x00, 0x00, 0x10, + 0x18, 0xc3, 0xa0, 0x00, 0x00, 0x17, 0x20, 0x02, 0x5f, 0x12, 0x00, 0x00, + 0x14, 0x18, 0x29, 0x9c, 0x00, 0x00, 0x17, 0x21, 0x02, 0xe0, 0x0c, 0x00, + 0x00, 0x18, 0x18, 0xb0, 0x6b, 0x00, 0x00, 0x17, 0x22, 0x02, 0x65, 0x12, + 0x00, 0x00, 0x1c, 0x18, 0xde, 0x29, 0x00, 0x00, 0x17, 0x23, 0x02, 0xa7, + 0x00, 0x00, 0x00, 0x20, 0x18, 0x91, 0x8d, 0x00, 0x00, 0x17, 0x24, 0x02, + 0xa7, 0x00, 0x00, 0x00, 0x21, 0x18, 0x7e, 0xb9, 0x00, 0x00, 0x17, 0x25, + 0x02, 0xa7, 0x00, 0x00, 0x00, 0x22, 0x18, 0x95, 0xb0, 0x00, 0x00, 0x17, + 0x2a, 0x02, 0x2b, 0x06, 0x00, 0x00, 0x24, 0x18, 0x57, 0x7a, 0x00, 0x00, + 0x17, 0x2b, 0x02, 0xf7, 0x0b, 0x00, 0x00, 0x28, 0x18, 0xef, 0xd9, 0x00, + 0x00, 0x17, 0x2d, 0x02, 0xab, 0x01, 0x00, 0x00, 0xcc, 0x18, 0xa9, 0x7e, + 0x00, 0x00, 0x17, 0x31, 0x02, 0x40, 0x11, 0x00, 0x00, 0xd0, 0x22, 0x70, + 0x31, 0x00, 0x17, 0x3e, 0x02, 0x0f, 0x12, 0x00, 0x00, 0xdc, 0x22, 0x70, + 0x32, 0x00, 0x17, 0x43, 0x02, 0x31, 0x12, 0x00, 0x00, 0xe0, 0x00, 0x0c, + 0x14, 0x17, 0xfe, 0x2a, 0x0e, 0x00, 0x00, 0x22, 0x73, 0x65, 0x6d, 0x00, + 0x17, 0x00, 0x01, 0x17, 0x0d, 0x00, 0x00, 0x00, 0x18, 0xb2, 0x8e, 0x00, + 0x00, 0x17, 0x03, 0x01, 0x86, 0x09, 0x00, 0x00, 0x0c, 0x00, 0x07, 0xf3, + 0xe3, 0x00, 0x00, 0x17, 0x06, 0x01, 0x07, 0x0e, 0x00, 0x00, 0x1b, 0x14, + 0x17, 0x07, 0x01, 0x5a, 0x0e, 0x00, 0x00, 0x22, 0x73, 0x65, 0x6d, 0x00, + 0x17, 0x09, 0x01, 0x17, 0x0d, 0x00, 0x00, 0x00, 0x18, 0x17, 0xd6, 0x00, + 0x00, 0x17, 0x0c, 0x01, 0x86, 0x09, 0x00, 0x00, 0x0c, 0x00, 0x07, 0x3b, + 0x19, 0x00, 0x00, 0x17, 0x0f, 0x01, 0x36, 0x0e, 0x00, 0x00, 0x1c, 0x08, + 0x17, 0x12, 0x01, 0x94, 0x0e, 0x00, 0x00, 0x1d, 0xf4, 0x5d, 0x00, 0x00, + 0x17, 0x14, 0x01, 0x5a, 0x09, 0x00, 0x00, 0x1d, 0x39, 0x73, 0x00, 0x00, + 0x17, 0x16, 0x01, 0x75, 0x0c, 0x00, 0x00, 0x1d, 0x03, 0x1b, 0x00, 0x00, + 0x17, 0x18, 0x01, 0xa5, 0x0c, 0x00, 0x00, 0x00, 0x1b, 0x0c, 0x17, 0x10, + 0x01, 0xb8, 0x0e, 0x00, 0x00, 0x18, 0xc1, 0x65, 0x00, 0x00, 0x17, 0x1a, + 0x01, 0x66, 0x0e, 0x00, 0x00, 0x00, 0x18, 0xcb, 0x7a, 0x00, 0x00, 0x17, + 0x1d, 0x01, 0xb8, 0x0e, 0x00, 0x00, 0x08, 0x00, 0x11, 0x04, 0x5a, 0x0e, + 0x00, 0x00, 0x07, 0x7f, 0x5c, 0x00, 0x00, 0x17, 0x26, 0x01, 0x94, 0x0e, + 0x00, 0x00, 0x07, 0x67, 0x2f, 0x00, 0x00, 0x17, 0x27, 0x01, 0xd6, 0x0e, + 0x00, 0x00, 0x1a, 0x6f, 0xb4, 0x00, 0x00, 0x28, 0x17, 0x0b, 0x02, 0x25, + 0x0f, 0x00, 0x00, 0x18, 0xa7, 0x1d, 0x00, 0x00, 0x17, 0x0c, 0x02, 0xbe, + 0x0e, 0x00, 0x00, 0x00, 0x18, 0xd0, 0x51, 0x00, 0x00, 0x17, 0x0e, 0x02, + 0xdd, 0x00, 0x00, 0x00, 0x10, 0x18, 0x3d, 0x69, 0x00, 0x00, 0x17, 0x0f, + 0x02, 0xb2, 0x00, 0x00, 0x00, 0x18, 0x18, 0x31, 0x90, 0x00, 0x00, 0x17, + 0x10, 0x02, 0x09, 0x12, 0x00, 0x00, 0x1c, 0x18, 0x32, 0xbb, 0x00, 0x00, + 0x17, 0x11, 0x02, 0xab, 0x01, 0x00, 0x00, 0x20, 0x00, 0x07, 0xf3, 0x17, + 0x00, 0x00, 0x17, 0x28, 0x01, 0x31, 0x0f, 0x00, 0x00, 0x1f, 0x41, 0x0f, + 0x00, 0x00, 0x16, 0x41, 0x0f, 0x00, 0x00, 0x16, 0xab, 0x01, 0x00, 0x00, + 0x00, 0x11, 0x04, 0xca, 0x0e, 0x00, 0x00, 0x07, 0x59, 0x94, 0x00, 0x00, + 0x17, 0x30, 0x01, 0x53, 0x0f, 0x00, 0x00, 0x17, 0x54, 0xdf, 0x00, 0x00, + 0x38, 0x02, 0x17, 0x60, 0x02, 0x49, 0x10, 0x00, 0x00, 0x18, 0x42, 0x4a, + 0x00, 0x00, 0x17, 0x62, 0x02, 0x3a, 0x11, 0x00, 0x00, 0x00, 0x18, 0xc3, + 0xa0, 0x00, 0x00, 0x17, 0x63, 0x02, 0x6b, 0x12, 0x00, 0x00, 0x04, 0x18, + 0x35, 0xb7, 0x00, 0x00, 0x17, 0x64, 0x02, 0x65, 0x12, 0x00, 0x00, 0x24, + 0x18, 0x7f, 0xd9, 0x00, 0x00, 0x17, 0x65, 0x02, 0x5f, 0x12, 0x00, 0x00, + 0x28, 0x18, 0x2c, 0xf6, 0x00, 0x00, 0x17, 0x66, 0x02, 0xc2, 0x00, 0x00, + 0x00, 0x2c, 0x18, 0xeb, 0x0f, 0x00, 0x00, 0x17, 0x67, 0x02, 0xc2, 0x00, + 0x00, 0x00, 0x30, 0x18, 0xd8, 0xf7, 0x00, 0x00, 0x17, 0x68, 0x02, 0x2d, + 0x0d, 0x00, 0x00, 0x34, 0x19, 0x34, 0xc3, 0x00, 0x00, 0x17, 0x69, 0x02, + 0x2d, 0x0d, 0x00, 0x00, 0x18, 0x01, 0x19, 0xf4, 0xe4, 0x00, 0x00, 0x17, + 0x6a, 0x02, 0x2a, 0x0e, 0x00, 0x00, 0xfc, 0x01, 0x19, 0xf2, 0x9b, 0x00, + 0x00, 0x17, 0x6b, 0x02, 0x95, 0x0c, 0x00, 0x00, 0x10, 0x02, 0x19, 0x78, + 0x84, 0x00, 0x00, 0x17, 0x6c, 0x02, 0x95, 0x0c, 0x00, 0x00, 0x18, 0x02, + 0x19, 0xdf, 0xce, 0x00, 0x00, 0x17, 0x6e, 0x02, 0xc2, 0x00, 0x00, 0x00, + 0x20, 0x02, 0x19, 0x64, 0x11, 0x00, 0x00, 0x17, 0x6f, 0x02, 0xb2, 0x00, + 0x00, 0x00, 0x24, 0x02, 0x19, 0x7e, 0x0f, 0x00, 0x00, 0x17, 0x70, 0x02, + 0xcd, 0x00, 0x00, 0x00, 0x28, 0x02, 0x19, 0x83, 0x3a, 0x00, 0x00, 0x17, + 0x71, 0x02, 0xcd, 0x00, 0x00, 0x00, 0x2c, 0x02, 0x19, 0xc3, 0x29, 0x00, + 0x00, 0x17, 0x73, 0x02, 0xc2, 0x00, 0x00, 0x00, 0x30, 0x02, 0x19, 0x62, + 0x7d, 0x00, 0x00, 0x17, 0x74, 0x02, 0xe0, 0x0c, 0x00, 0x00, 0x34, 0x02, + 0x00, 0x1b, 0x0c, 0x17, 0x60, 0x01, 0x78, 0x10, 0x00, 0x00, 0x18, 0x7b, + 0xca, 0x00, 0x00, 0x17, 0x62, 0x01, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x22, + 0x70, 0x31, 0x00, 0x17, 0x64, 0x01, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x22, + 0x70, 0x32, 0x00, 0x17, 0x66, 0x01, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, + 0x1b, 0x0c, 0x17, 0x69, 0x01, 0xa6, 0x10, 0x00, 0x00, 0x22, 0x70, 0x31, + 0x00, 0x17, 0x6b, 0x01, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x22, 0x70, 0x32, + 0x00, 0x17, 0x6d, 0x01, 0xe8, 0x00, 0x00, 0x00, 0x04, 0x22, 0x70, 0x33, + 0x00, 0x17, 0x6f, 0x01, 0xe8, 0x00, 0x00, 0x00, 0x08, 0x00, 0x1c, 0x0c, + 0x17, 0x5e, 0x01, 0xd4, 0x10, 0x00, 0x00, 0x1d, 0xc4, 0x82, 0x00, 0x00, + 0x17, 0x68, 0x01, 0x49, 0x10, 0x00, 0x00, 0x1d, 0xe9, 0x2d, 0x00, 0x00, + 0x17, 0x71, 0x01, 0x78, 0x10, 0x00, 0x00, 0x1d, 0x5f, 0x7a, 0x00, 0x00, + 0x17, 0x72, 0x01, 0xd4, 0x10, 0x00, 0x00, 0x00, 0x0a, 0xfb, 0x05, 0x00, + 0x00, 0xe4, 0x10, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x0b, 0x00, + 0x1a, 0x7f, 0x01, 0x00, 0x00, 0x10, 0x17, 0x5a, 0x01, 0x05, 0x11, 0x00, + 0x00, 0x18, 0xda, 0x2b, 0x00, 0x00, 0x17, 0x5c, 0x01, 0xe8, 0x00, 0x00, + 0x00, 0x00, 0x25, 0xa6, 0x10, 0x00, 0x00, 0x04, 0x00, 0x07, 0x33, 0xc1, + 0x00, 0x00, 0x17, 0x75, 0x01, 0xe4, 0x10, 0x00, 0x00, 0x05, 0x05, 0x11, + 0x00, 0x00, 0x1b, 0x0c, 0x17, 0x76, 0x01, 0x3a, 0x11, 0x00, 0x00, 0x18, + 0x39, 0x73, 0x00, 0x00, 0x17, 0x78, 0x01, 0x75, 0x0c, 0x00, 0x00, 0x00, + 0x18, 0xcb, 0x7a, 0x00, 0x00, 0x17, 0x7a, 0x01, 0x3a, 0x11, 0x00, 0x00, + 0x08, 0x00, 0x11, 0x04, 0x2d, 0x0d, 0x00, 0x00, 0x07, 0x01, 0xe5, 0x00, + 0x00, 0x17, 0x7c, 0x01, 0x16, 0x11, 0x00, 0x00, 0x07, 0xcc, 0xa3, 0x00, + 0x00, 0x17, 0x7e, 0x01, 0x58, 0x11, 0x00, 0x00, 0x1a, 0xb3, 0xb0, 0x00, + 0x00, 0x14, 0x17, 0x05, 0x02, 0x8d, 0x11, 0x00, 0x00, 0x18, 0x95, 0xb0, + 0x00, 0x00, 0x17, 0x06, 0x02, 0x2b, 0x06, 0x00, 0x00, 0x00, 0x18, 0x7f, + 0x1d, 0x00, 0x00, 0x17, 0x07, 0x02, 0xb2, 0x00, 0x00, 0x00, 0x04, 0x18, + 0xd8, 0xc5, 0x00, 0x00, 0x17, 0x08, 0x02, 0xfd, 0x11, 0x00, 0x00, 0x08, + 0x00, 0x20, 0x1b, 0xe5, 0x00, 0x00, 0x17, 0x83, 0x01, 0x99, 0x11, 0x00, + 0x00, 0x11, 0x04, 0x05, 0x11, 0x00, 0x00, 0x20, 0xc8, 0xdc, 0x00, 0x00, + 0x17, 0x84, 0x01, 0x99, 0x11, 0x00, 0x00, 0x20, 0x4c, 0xc3, 0x00, 0x00, + 0x17, 0x85, 0x01, 0xb7, 0x11, 0x00, 0x00, 0x11, 0x04, 0x11, 0x11, 0x00, + 0x00, 0x20, 0x7b, 0xc1, 0x00, 0x00, 0x17, 0x86, 0x01, 0xff, 0x00, 0x00, + 0x00, 0x1b, 0x0c, 0x17, 0xfe, 0x01, 0xed, 0x11, 0x00, 0x00, 0x18, 0xe8, + 0xe1, 0x00, 0x00, 0x17, 0xff, 0x01, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x18, + 0xa7, 0x81, 0x00, 0x00, 0x17, 0x00, 0x02, 0xed, 0x11, 0x00, 0x00, 0x04, + 0x00, 0x0a, 0xc2, 0x00, 0x00, 0x00, 0xfd, 0x11, 0x00, 0x00, 0x0b, 0x6d, + 0x01, 0x00, 0x00, 0x01, 0x00, 0x07, 0x4a, 0x74, 0x00, 0x00, 0x17, 0x01, + 0x02, 0xc9, 0x11, 0x00, 0x00, 0x11, 0x04, 0x25, 0x0f, 0x00, 0x00, 0x1c, + 0x04, 0x17, 0x3b, 0x02, 0x31, 0x12, 0x00, 0x00, 0x1d, 0xf3, 0x5a, 0x00, + 0x00, 0x17, 0x3c, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x1d, 0xa2, 0xc8, 0x00, + 0x00, 0x17, 0x3d, 0x02, 0xe8, 0x00, 0x00, 0x00, 0x00, 0x1c, 0x04, 0x17, + 0x3f, 0x02, 0x5f, 0x12, 0x00, 0x00, 0x1d, 0x86, 0xe6, 0x00, 0x00, 0x17, + 0x40, 0x02, 0xc2, 0x00, 0x00, 0x00, 0x1d, 0x17, 0xf8, 0x00, 0x00, 0x17, + 0x41, 0x02, 0xc2, 0x00, 0x00, 0x00, 0x1d, 0xd4, 0xb2, 0x00, 0x00, 0x17, + 0x42, 0x02, 0xc2, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0xc2, 0x00, 0x00, + 0x00, 0x11, 0x04, 0xd5, 0x0c, 0x00, 0x00, 0x0a, 0xc2, 0x00, 0x00, 0x00, + 0x7b, 0x12, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x07, 0x00, 0x20, + 0xcd, 0x6b, 0x00, 0x00, 0x17, 0x8d, 0x02, 0x87, 0x12, 0x00, 0x00, 0x11, + 0x04, 0x47, 0x0f, 0x00, 0x00, 0x20, 0xee, 0x37, 0x00, 0x00, 0x17, 0x8f, + 0x02, 0x3a, 0x11, 0x00, 0x00, 0x20, 0xa4, 0x2c, 0x00, 0x00, 0x17, 0x99, + 0x02, 0xa5, 0x12, 0x00, 0x00, 0x11, 0x04, 0x4c, 0x11, 0x00, 0x00, 0x20, + 0xf3, 0x15, 0x00, 0x00, 0x17, 0x9a, 0x02, 0xb2, 0x00, 0x00, 0x00, 0x20, + 0xbe, 0x77, 0x00, 0x00, 0x17, 0x9b, 0x02, 0xb2, 0x00, 0x00, 0x00, 0x20, + 0x5d, 0x38, 0x00, 0x00, 0x17, 0x9c, 0x02, 0xd2, 0x00, 0x00, 0x00, 0x20, + 0x53, 0xec, 0x00, 0x00, 0x17, 0x9d, 0x02, 0xd2, 0x00, 0x00, 0x00, 0x20, + 0x64, 0x21, 0x00, 0x00, 0x17, 0x9e, 0x02, 0xb2, 0x00, 0x00, 0x00, 0x20, + 0xca, 0x72, 0x00, 0x00, 0x17, 0xa0, 0x02, 0xd2, 0x00, 0x00, 0x00, 0x20, + 0x3c, 0xa4, 0x00, 0x00, 0x17, 0xab, 0x02, 0x65, 0x12, 0x00, 0x00, 0x0a, + 0xfb, 0x05, 0x00, 0x00, 0x0f, 0x13, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, + 0x00, 0x1f, 0x00, 0x0c, 0x14, 0x18, 0x47, 0x30, 0x13, 0x00, 0x00, 0x0d, + 0x71, 0x7b, 0x00, 0x00, 0x18, 0x49, 0x30, 0x13, 0x00, 0x00, 0x00, 0x0d, + 0x95, 0xeb, 0x00, 0x00, 0x18, 0x4a, 0x21, 0x00, 0x00, 0x00, 0x10, 0x00, + 0x0a, 0x21, 0x00, 0x00, 0x00, 0x40, 0x13, 0x00, 0x00, 0x0b, 0x6d, 0x01, + 0x00, 0x00, 0x03, 0x00, 0x03, 0xef, 0xde, 0x00, 0x00, 0x18, 0x4b, 0x0f, + 0x13, 0x00, 0x00, 0x03, 0xcf, 0xe2, 0x00, 0x00, 0x18, 0x57, 0x56, 0x13, + 0x00, 0x00, 0x1f, 0x6b, 0x13, 0x00, 0x00, 0x16, 0x21, 0x00, 0x00, 0x00, + 0x16, 0x21, 0x00, 0x00, 0x00, 0x16, 0xab, 0x01, 0x00, 0x00, 0x00, 0x0c, + 0x08, 0x18, 0x5a, 0x8c, 0x13, 0x00, 0x00, 0x10, 0x69, 0x73, 0x72, 0x00, + 0x18, 0x5c, 0x8c, 0x13, 0x00, 0x00, 0x00, 0x0d, 0xef, 0xd9, 0x00, 0x00, + 0x18, 0x5e, 0xab, 0x01, 0x00, 0x00, 0x04, 0x00, 0x11, 0x04, 0x4b, 0x13, + 0x00, 0x00, 0x03, 0x9e, 0xd5, 0x00, 0x00, 0x18, 0x5f, 0x6b, 0x13, 0x00, + 0x00, 0x0c, 0x34, 0x18, 0x62, 0xfa, 0x13, 0x00, 0x00, 0x0d, 0xaa, 0xe6, + 0x00, 0x00, 0x18, 0x65, 0x30, 0x13, 0x00, 0x00, 0x00, 0x0d, 0x90, 0x22, + 0x00, 0x00, 0x18, 0x67, 0x30, 0x13, 0x00, 0x00, 0x10, 0x0d, 0x28, 0xac, + 0x00, 0x00, 0x18, 0x69, 0xfa, 0x13, 0x00, 0x00, 0x20, 0x0d, 0x83, 0xee, + 0x00, 0x00, 0x18, 0x6b, 0xf3, 0x00, 0x00, 0x00, 0x24, 0x0d, 0x64, 0x8c, + 0x00, 0x00, 0x18, 0x6d, 0x00, 0x14, 0x00, 0x00, 0x28, 0x0d, 0x7e, 0x0b, + 0x00, 0x00, 0x18, 0x6f, 0x06, 0x14, 0x00, 0x00, 0x2c, 0x0d, 0xd3, 0xf8, + 0x00, 0x00, 0x18, 0x71, 0xf3, 0x00, 0x00, 0x00, 0x30, 0x00, 0x11, 0x04, + 0x92, 0x13, 0x00, 0x00, 0x11, 0x04, 0x40, 0x13, 0x00, 0x00, 0x02, 0x01, + 0x02, 0x88, 0xc2, 0x00, 0x00, 0x03, 0xac, 0x51, 0x00, 0x00, 0x18, 0x72, + 0x9d, 0x13, 0x00, 0x00, 0x21, 0xbc, 0x2d, 0x00, 0x00, 0x18, 0x75, 0x23, + 0x14, 0x00, 0x00, 0x11, 0x04, 0x0d, 0x14, 0x00, 0x00, 0x27, 0x04, 0xf3, + 0x00, 0x00, 0x00, 0x19, 0x23, 0x5a, 0x14, 0x00, 0x00, 0x28, 0xa7, 0xc6, + 0x00, 0x00, 0x00, 0x28, 0x2a, 0x5e, 0x00, 0x00, 0x01, 0x28, 0x66, 0x95, + 0x00, 0x00, 0x02, 0x28, 0x1b, 0x16, 0x00, 0x00, 0x03, 0x29, 0x89, 0x02, + 0x00, 0x00, 0x7f, 0x29, 0xb5, 0x9a, 0x00, 0x00, 0x7e, 0x00, 0x03, 0x2d, + 0xb3, 0x00, 0x00, 0x19, 0x2a, 0x29, 0x14, 0x00, 0x00, 0x0c, 0x10, 0x19, + 0x43, 0x9d, 0x14, 0x00, 0x00, 0x10, 0x69, 0x64, 0x00, 0x19, 0x45, 0xf3, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0x05, 0x7f, 0x00, 0x00, 0x19, 0x46, 0xc2, + 0x00, 0x00, 0x00, 0x04, 0x0d, 0x52, 0x13, 0x00, 0x00, 0x19, 0x47, 0xc2, + 0x00, 0x00, 0x00, 0x08, 0x0d, 0x11, 0xb5, 0x00, 0x00, 0x19, 0x48, 0xc2, + 0x00, 0x00, 0x00, 0x0c, 0x00, 0x03, 0x78, 0x6b, 0x00, 0x00, 0x19, 0x49, + 0x65, 0x14, 0x00, 0x00, 0x21, 0xce, 0x89, 0x00, 0x00, 0x1a, 0x17, 0x5a, + 0x14, 0x00, 0x00, 0x0a, 0x9d, 0x14, 0x00, 0x00, 0xbe, 0x14, 0x00, 0x00, + 0x26, 0x00, 0x21, 0x10, 0xbc, 0x00, 0x00, 0x1a, 0x1b, 0xb3, 0x14, 0x00, + 0x00, 0x21, 0x00, 0x99, 0x00, 0x00, 0x1a, 0x1c, 0xb3, 0x14, 0x00, 0x00, + 0x11, 0x04, 0xf3, 0x00, 0x00, 0x00, 0x11, 0x04, 0x21, 0x00, 0x00, 0x00, + 0x21, 0x04, 0xd5, 0x00, 0x00, 0x1b, 0xb0, 0x00, 0x14, 0x00, 0x00, 0x21, + 0x7e, 0x9b, 0x00, 0x00, 0x1b, 0xba, 0xda, 0x14, 0x00, 0x00, 0x0c, 0x0c, + 0x1c, 0x1d, 0x22, 0x15, 0x00, 0x00, 0x10, 0x69, 0x64, 0x00, 0x1c, 0x1f, + 0xc2, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x51, 0x96, 0x00, 0x00, 0x1c, 0x21, + 0xc2, 0x00, 0x00, 0x00, 0x04, 0x0d, 0xb2, 0x57, 0x00, 0x00, 0x1c, 0x22, + 0xc2, 0x00, 0x00, 0x00, 0x08, 0x00, 0x03, 0xff, 0x06, 0x00, 0x00, 0x1c, + 0x23, 0xf6, 0x14, 0x00, 0x00, 0x27, 0x04, 0x21, 0x00, 0x00, 0x00, 0x1d, + 0x13, 0x5e, 0x15, 0x00, 0x00, 0x28, 0x88, 0xf5, 0x00, 0x00, 0x00, 0x28, + 0x32, 0x67, 0x00, 0x00, 0x01, 0x28, 0x88, 0x47, 0x00, 0x00, 0x02, 0x28, + 0xc9, 0x1f, 0x00, 0x00, 0x03, 0x28, 0x31, 0x4a, 0x00, 0x00, 0x04, 0x28, + 0xd9, 0x73, 0x00, 0x00, 0x09, 0x00, 0x11, 0x04, 0x69, 0x15, 0x00, 0x00, + 0x04, 0x5e, 0x15, 0x00, 0x00, 0x2a, 0x21, 0x90, 0x1d, 0x00, 0x00, 0x1e, + 0x63, 0xf5, 0x05, 0x00, 0x00, 0x0f, 0x67, 0x63, 0x00, 0x00, 0x08, 0x1f, + 0x14, 0x9a, 0x15, 0x00, 0x00, 0x0d, 0x1b, 0x50, 0x00, 0x00, 0x1f, 0x17, + 0x9f, 0x15, 0x00, 0x00, 0x00, 0x0d, 0x71, 0x57, 0x00, 0x00, 0x1f, 0x19, + 0x9f, 0x15, 0x00, 0x00, 0x04, 0x00, 0x2b, 0xf3, 0x00, 0x00, 0x00, 0x11, + 0x04, 0x9a, 0x15, 0x00, 0x00, 0x03, 0xe6, 0x00, 0x00, 0x00, 0x1f, 0x1a, + 0x75, 0x15, 0x00, 0x00, 0x21, 0x4d, 0xfb, 0x00, 0x00, 0x1f, 0x1b, 0xa5, + 0x15, 0x00, 0x00, 0x0f, 0x58, 0xc9, 0x00, 0x00, 0x2c, 0x1f, 0x1d, 0x4c, + 0x16, 0x00, 0x00, 0x0d, 0x9b, 0xe2, 0x00, 0x00, 0x1f, 0x1e, 0x21, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x13, 0x68, 0x00, 0x00, 0x1f, 0x1f, 0x21, 0x00, + 0x00, 0x00, 0x04, 0x0d, 0x01, 0x3c, 0x00, 0x00, 0x1f, 0x21, 0x21, 0x00, + 0x00, 0x00, 0x08, 0x0d, 0x32, 0x9b, 0x00, 0x00, 0x1f, 0x22, 0x21, 0x00, + 0x00, 0x00, 0x0c, 0x0d, 0x10, 0x7d, 0x00, 0x00, 0x1f, 0x23, 0x21, 0x00, + 0x00, 0x00, 0x10, 0x0d, 0x61, 0xa5, 0x00, 0x00, 0x1f, 0x24, 0x21, 0x00, + 0x00, 0x00, 0x14, 0x0d, 0x3e, 0x7e, 0x00, 0x00, 0x1f, 0x25, 0x21, 0x00, + 0x00, 0x00, 0x18, 0x0d, 0x28, 0x17, 0x00, 0x00, 0x1f, 0x26, 0x21, 0x00, + 0x00, 0x00, 0x1c, 0x0d, 0xc4, 0x99, 0x00, 0x00, 0x1f, 0x27, 0x21, 0x00, + 0x00, 0x00, 0x20, 0x0d, 0x66, 0xca, 0x00, 0x00, 0x1f, 0x28, 0x71, 0x00, + 0x00, 0x00, 0x24, 0x0d, 0x4b, 0x0c, 0x00, 0x00, 0x1f, 0x2a, 0x21, 0x00, + 0x00, 0x00, 0x28, 0x00, 0x03, 0x08, 0x48, 0x00, 0x00, 0x1f, 0x2b, 0xbb, + 0x15, 0x00, 0x00, 0x21, 0xda, 0x92, 0x00, 0x00, 0x1f, 0x2c, 0x4c, 0x16, + 0x00, 0x00, 0x0f, 0x64, 0x7b, 0x00, 0x00, 0x08, 0x20, 0xe4, 0x87, 0x16, + 0x00, 0x00, 0x0d, 0x49, 0x21, 0x00, 0x00, 0x20, 0xe5, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x16, 0x03, 0x00, 0x00, 0x20, 0xe6, 0x21, 0x00, 0x00, + 0x00, 0x04, 0x00, 0x0f, 0x51, 0x57, 0x00, 0x00, 0x38, 0x20, 0xf7, 0xd0, + 0x16, 0x00, 0x00, 0x0d, 0x73, 0x8e, 0x00, 0x00, 0x20, 0xf8, 0x62, 0x16, + 0x00, 0x00, 0x00, 0x0d, 0xe4, 0x5d, 0x00, 0x00, 0x20, 0xf9, 0x62, 0x16, + 0x00, 0x00, 0x08, 0x0d, 0xa1, 0xbc, 0x00, 0x00, 0x20, 0xfa, 0x62, 0x16, + 0x00, 0x00, 0x10, 0x0d, 0x8c, 0x83, 0x00, 0x00, 0x20, 0xfb, 0x62, 0x16, + 0x00, 0x00, 0x18, 0x0d, 0x73, 0x44, 0x00, 0x00, 0x20, 0xfc, 0xd0, 0x16, + 0x00, 0x00, 0x20, 0x00, 0x0a, 0x62, 0x16, 0x00, 0x00, 0xe0, 0x16, 0x00, + 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x02, 0x00, 0x1a, 0x6d, 0xef, 0x00, + 0x00, 0x08, 0x20, 0x09, 0x01, 0x08, 0x17, 0x00, 0x00, 0x22, 0x6c, 0x65, + 0x6e, 0x00, 0x20, 0x0a, 0x01, 0x21, 0x00, 0x00, 0x00, 0x00, 0x18, 0x03, + 0xaf, 0x00, 0x00, 0x20, 0x0b, 0x01, 0x21, 0x00, 0x00, 0x00, 0x04, 0x00, + 0x2c, 0xed, 0x4b, 0x00, 0x00, 0x04, 0x21, 0x00, 0x00, 0x00, 0x21, 0x34, + 0x31, 0x17, 0x00, 0x00, 0x28, 0x90, 0xb8, 0x00, 0x00, 0x00, 0x28, 0xec, + 0x48, 0x00, 0x00, 0x01, 0x28, 0xd6, 0x50, 0x00, 0x00, 0x02, 0x28, 0xf7, + 0xa6, 0x00, 0x00, 0x03, 0x00, 0x0f, 0xcb, 0xdd, 0x00, 0x00, 0x0c, 0x21, + 0x44, 0x62, 0x17, 0x00, 0x00, 0x10, 0x68, 0x64, 0x72, 0x00, 0x21, 0x46, + 0xe0, 0x16, 0x00, 0x00, 0x00, 0x0d, 0xda, 0xb0, 0x00, 0x00, 0x21, 0x48, + 0xf3, 0x00, 0x00, 0x00, 0x08, 0x10, 0x6d, 0x73, 0x67, 0x00, 0x21, 0x4a, + 0x62, 0x17, 0x00, 0x00, 0x0c, 0x00, 0x0a, 0x28, 0x00, 0x00, 0x00, 0x71, + 0x17, 0x00, 0x00, 0x2d, 0x6d, 0x01, 0x00, 0x00, 0x00, 0x0f, 0xa7, 0xb7, + 0x00, 0x00, 0x07, 0x21, 0x58, 0x96, 0x17, 0x00, 0x00, 0x0d, 0x13, 0x47, + 0x00, 0x00, 0x21, 0x5a, 0x96, 0x17, 0x00, 0x00, 0x00, 0x0d, 0xab, 0xb7, + 0x00, 0x00, 0x21, 0x5c, 0x3a, 0x00, 0x00, 0x00, 0x06, 0x00, 0x0a, 0x3a, + 0x00, 0x00, 0x00, 0xa6, 0x17, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, + 0x05, 0x00, 0x0f, 0xa0, 0xaa, 0x00, 0x00, 0xb8, 0x21, 0x63, 0x5b, 0x18, + 0x00, 0x00, 0x0d, 0xc7, 0x58, 0x00, 0x00, 0x21, 0x65, 0x21, 0x00, 0x00, + 0x00, 0x00, 0x0d, 0x39, 0x4c, 0x00, 0x00, 0x21, 0x67, 0x21, 0x00, 0x00, + 0x00, 0x04, 0x0d, 0x1f, 0x12, 0x00, 0x00, 0x21, 0x69, 0x5b, 0x18, 0x00, + 0x00, 0x08, 0x0d, 0x5a, 0x57, 0x00, 0x00, 0x21, 0x6b, 0x87, 0x16, 0x00, + 0x00, 0x24, 0x0d, 0xc1, 0x2e, 0x00, 0x00, 0x21, 0x6d, 0x21, 0x00, 0x00, + 0x00, 0x5c, 0x0d, 0x95, 0x00, 0x00, 0x00, 0x21, 0x6f, 0x21, 0x00, 0x00, + 0x00, 0x60, 0x0d, 0xea, 0xc9, 0x00, 0x00, 0x21, 0x71, 0x21, 0x00, 0x00, + 0x00, 0x64, 0x0d, 0xa1, 0x5b, 0x00, 0x00, 0x21, 0x73, 0x21, 0x00, 0x00, + 0x00, 0x68, 0x0d, 0xe8, 0x6a, 0x00, 0x00, 0x21, 0x75, 0x30, 0x13, 0x00, + 0x00, 0x6c, 0x0d, 0x25, 0xcb, 0x00, 0x00, 0x21, 0x77, 0x21, 0x00, 0x00, + 0x00, 0x7c, 0x0d, 0x31, 0xcb, 0x00, 0x00, 0x21, 0x79, 0x21, 0x00, 0x00, + 0x00, 0x80, 0x0d, 0xf3, 0x0e, 0x00, 0x00, 0x21, 0x7b, 0x6b, 0x18, 0x00, + 0x00, 0x84, 0x0d, 0x00, 0x0f, 0x00, 0x00, 0x21, 0x7d, 0x6b, 0x18, 0x00, + 0x00, 0x8c, 0x0d, 0x31, 0x43, 0x00, 0x00, 0x21, 0x7f, 0x7b, 0x18, 0x00, + 0x00, 0x94, 0x00, 0x0a, 0x71, 0x17, 0x00, 0x00, 0x6b, 0x18, 0x00, 0x00, + 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x03, 0x00, 0x0a, 0x21, 0x00, 0x00, 0x00, + 0x7b, 0x18, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, 0x00, 0x01, 0x00, 0x0a, + 0x21, 0x00, 0x00, 0x00, 0x8b, 0x18, 0x00, 0x00, 0x0b, 0x6d, 0x01, 0x00, + 0x00, 0x08, 0x00, 0x2c, 0x07, 0xee, 0x00, 0x00, 0x04, 0x21, 0x00, 0x00, + 0x00, 0x22, 0x37, 0xc0, 0x18, 0x00, 0x00, 0x28, 0x3c, 0x56, 0x00, 0x00, + 0x00, 0x28, 0x51, 0x33, 0x00, 0x00, 0x01, 0x28, 0x46, 0x97, 0x00, 0x00, + 0x02, 0x28, 0x9b, 0xa5, 0x00, 0x00, 0x03, 0x28, 0xd8, 0x16, 0x00, 0x00, + 0x04, 0x28, 0x9c, 0x95, 0x00, 0x00, 0x05, 0x00, 0x0f, 0x49, 0x03, 0x00, + 0x00, 0x04, 0x22, 0x42, 0xd9, 0x18, 0x00, 0x00, 0x10, 0x68, 0x70, 0x71, + 0x00, 0x22, 0x44, 0xd9, 0x18, 0x00, 0x00, 0x00, 0x00, 0x11, 0x04, 0x22, + 0x15, 0x00, 0x00, 0x0c, 0x14, 0x22, 0x4a, 0xf4, 0x18, 0x00, 0x00, 0x0d, + 0x0c, 0x23, 0x00, 0x00, 0x22, 0x4c, 0xf4, 0x18, 0x00, 0x00, 0x00, 0x00, + 0x0a, 0xc0, 0x18, 0x00, 0x00, 0x04, 0x19, 0x00, 0x00, 0x0b, 0x6d, 0x01, + 0x00, 0x00, 0x04, 0x00, 0x03, 0x9c, 0x3d, 0x00, 0x00, 0x22, 0x4e, 0xdf, + 0x18, 0x00, 0x00, 0x21, 0x6f, 0x9b, 0x00, 0x00, 0x22, 0x50, 0x04, 0x19, + 0x00, 0x00, 0x12, 0x2c, 0x2c, 0x00, 0x00, 0x38, 0x50, 0x22, 0x67, 0x67, + 0x19, 0x00, 0x00, 0x0d, 0xb8, 0x75, 0x00, 0x00, 0x22, 0x68 +}; + +const unsigned char __aligned(4) nrf_wifi_lmac_patch_pri_bimg[] = { + 0xba, 0xda, 0xba, 0xab, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xcc, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x7d, 0xea, 0x00, 0x00, 0x02, 0xd4, 0xfe, 0x25, 0x6a, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x69, 0x49, 0x02, 0xd4, 0x1e, 0x2b, 0x84, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x97, 0x67, 0x02, 0xd4, 0xaa, 0x2c, 0xac, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xf8, 0x58, 0x02, 0xd4, 0x5c, 0x2c, 0x60, 0x17, 0x08, 0x80, + 0x01, 0x00, 0xb9, 0x47, 0x02, 0xd4, 0x54, 0x25, 0x8a, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x10, 0xb2, 0x02, 0xd4, 0x22, 0x2d, 0x72, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x01, 0x40, 0x02, 0xd4, 0xc2, 0x35, 0x66, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x4e, 0x45, 0x02, 0xd4, 0x62, 0x21, 0x10, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x36, 0x57, 0x02, 0xd4, 0x76, 0x26, 0xb8, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xc1, 0x90, 0x02, 0xd4, 0x8e, 0x2a, 0x0c, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xa1, 0xc6, 0x02, 0xd4, 0x52, 0x2a, 0xe2, 0x13, 0x08, 0x80, + 0x01, 0x00, 0xeb, 0xae, 0x02, 0xd4, 0xac, 0x2a, 0x2c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x61, 0x8e, 0x02, 0xd4, 0x00, 0x20, 0x16, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xa8, 0x60, 0x02, 0xd4, 0x40, 0x2a, 0x1a, 0x12, 0x08, 0x80, + 0x01, 0x00, 0x56, 0x2a, 0x02, 0xd4, 0xa2, 0x28, 0xbe, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x20, 0x16, 0x02, 0xd4, 0xde, 0x2d, 0x2c, 0x18, 0x08, 0x80, + 0x01, 0x00, 0xf5, 0x89, 0x02, 0xd4, 0xfa, 0x28, 0x3c, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x2a, 0xfb, 0x02, 0xd4, 0x54, 0x21, 0x28, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xef, 0xb3, 0x02, 0xd4, 0xd0, 0x29, 0x96, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x0f, 0xef, 0x02, 0xd4, 0xd6, 0x25, 0x5c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x64, 0x60, 0x02, 0xd4, 0x64, 0x25, 0xb4, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xe3, 0x5b, 0x02, 0xd4, 0x86, 0x26, 0xd0, 0x13, 0x08, 0x80, + 0x01, 0x00, 0xc4, 0x61, 0x02, 0xd4, 0x68, 0x2b, 0x4e, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x62, 0x6f, 0x02, 0xd4, 0xfc, 0x35, 0x54, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x4f, 0x39, 0x02, 0xd4, 0x4c, 0x28, 0xc4, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x96, 0x3b, 0x02, 0xd4, 0x5a, 0x24, 0x8c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x87, 0x90, 0x02, 0xd4, 0xc8, 0x2d, 0xb2, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xa0, 0x78, 0x02, 0xd4, 0x08, 0x2b, 0xf0, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x50, 0x54, 0x02, 0xd4, 0xb4, 0x27, 0xd4, 0x15, 0x08, 0x80, + 0x01, 0x00, 0xfb, 0xdb, 0x02, 0xd4, 0x44, 0x23, 0xda, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x13, 0xd7, 0x02, 0xd4, 0x46, 0x36, 0x6c, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x22, 0xe9, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0xba, 0x3e +}; + +const unsigned char __aligned(4) nrf_wifi_lmac_patch_sec_bin[] = { + 0x40, 0x09, 0x62, 0xb0, 0x08, 0x00, 0xe3, 0x40, 0x23, 0x00, 0xc1, 0x4f, + 0xa3, 0x41, 0x04, 0x80, 0x63, 0x30, 0xdc, 0x6c, 0x43, 0x00, 0x18, 0x11, + 0x3d, 0x22, 0x78, 0xd0, 0xa2, 0x45, 0xbc, 0xfc, 0xa4, 0x80, 0x41, 0x69, + 0xd0, 0x69, 0x82, 0xb0, 0x08, 0x00, 0xb0, 0x6d, 0xd0, 0xe9, 0x44, 0xc8, + 0x04, 0x94, 0xca, 0x00, 0x5c, 0xf8, 0x68, 0x81, 0x2e, 0x6d, 0x45, 0xc8, + 0x5d, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x3d, 0x1e, 0xe2, 0x45, + 0x2d, 0x6e, 0x3d, 0x22, 0x78, 0x50, 0x41, 0x4c, 0xbf, 0x45, 0x41, 0x69, + 0x81, 0xed, 0x62, 0x94, 0x0a, 0x01, 0x00, 0x0c, 0x02, 0x94, 0xf3, 0x00, + 0x82, 0xed, 0x62, 0xb4, 0xf2, 0xff, 0xa2, 0x41, 0x01, 0xa4, 0x42, 0x50, + 0x00, 0xbc, 0xa0, 0x69, 0x3d, 0x22, 0x78, 0x50, 0x63, 0x50, 0x02, 0x00, + 0xa0, 0xe9, 0xea, 0xcf, 0x41, 0x4c, 0xbc, 0xfc, 0xa4, 0x80, 0xc1, 0x69, + 0x51, 0x69, 0x20, 0x6d, 0x51, 0xe9, 0x66, 0xc8, 0x03, 0xb4, 0x96, 0x00, + 0xc2, 0x6a, 0xc3, 0x69, 0x44, 0x69, 0xa7, 0xc8, 0x68, 0xc8, 0x49, 0xc8, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x11, 0x10, 0xe2, 0x45, 0x09, 0x6e, + 0x50, 0x8d, 0x47, 0x48, 0x81, 0xed, 0x62, 0x94, 0xf2, 0x00, 0x00, 0x0c, + 0x4a, 0xad, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xed, 0x12, 0xe2, 0x45, + 0x80, 0x0c, 0x3d, 0x22, 0x78, 0x50, 0xc4, 0xcf, 0x41, 0x4c, 0x7c, 0xfc, + 0xa4, 0x80, 0xc1, 0x6b, 0x42, 0x6b, 0x3a, 0x69, 0xc3, 0x6a, 0xed, 0xc8, + 0x20, 0x6d, 0x3a, 0xe9, 0x48, 0x6d, 0x4e, 0xc8, 0xa2, 0x41, 0x08, 0x80, + 0x09, 0x6e, 0x42, 0x30, 0x23, 0x10, 0xd4, 0xc8, 0xc2, 0x45, 0xbd, 0xf8, + 0x54, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x3b, 0x10, 0xe2, 0x45, + 0x00, 0x0c, 0x3d, 0x22, 0x78, 0x50, 0xa6, 0xcf, 0x41, 0x4c, 0x5c, 0xfc, + 0xa4, 0x80, 0x41, 0x68, 0x42, 0x6b, 0xae, 0x69, 0xc3, 0x6a, 0x01, 0xee, + 0xb0, 0x6d, 0xae, 0xe9, 0x0f, 0xca, 0xbd, 0x20, 0x44, 0x90, 0x90, 0x94, + 0x7f, 0x00, 0x00, 0x0c, 0x62, 0xfc, 0x40, 0x00, 0x2d, 0x6e, 0x1c, 0xc8, + 0xb0, 0x6d, 0x62, 0xf8, 0x40, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0xb1, 0x1e, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x84, 0xee, + 0x42, 0x30, 0x23, 0x19, 0xe2, 0x45, 0x80, 0x0c, 0x3d, 0x22, 0x78, 0x50, + 0x7f, 0xcf, 0x41, 0x4c, 0x7c, 0xfc, 0xa4, 0x80, 0xc1, 0x6b, 0x42, 0x6b, + 0x43, 0xfc, 0x44, 0x00, 0xc3, 0x6a, 0x44, 0x6a, 0x20, 0x6d, 0xfc, 0xf8, + 0x6c, 0x81, 0xdc, 0xf8, 0x70, 0x81, 0xbc, 0xf8, 0x74, 0x81, 0x9c, 0xf8, + 0x78, 0x81, 0x43, 0xf8, 0x44, 0x00, 0x3d, 0x22, 0x78, 0x50, 0x68, 0xcf, + 0x41, 0x4c, 0x5c, 0xfc, 0xa4, 0x80, 0x41, 0x68, 0xa4, 0x20, 0x08, 0x10, + 0xab, 0x69, 0x04, 0xfd, 0x10, 0x00, 0xc5, 0x6b, 0xb0, 0x6d, 0x01, 0xee, + 0xab, 0xe9, 0x0f, 0xca, 0xbd, 0x20, 0x40, 0x90, 0x12, 0xc9, 0x90, 0x94, + 0x14, 0x00, 0xf3, 0xc8, 0xad, 0x69, 0x2d, 0x6e, 0x1c, 0xc8, 0xb0, 0x6d, + 0xad, 0xe9, 0xa2, 0x41, 0x01, 0x80, 0xc1, 0xcf, 0x42, 0x30, 0x1d, 0x1e, + 0xc3, 0x69, 0x44, 0x69, 0xaa, 0xc8, 0x6b, 0xc8, 0x6b, 0xcf, 0x4c, 0xc8, + 0x07, 0xed, 0x38, 0xcf, 0x45, 0xc8, 0xac, 0x69, 0x2d, 0x6e, 0x17, 0xc9, + 0xb0, 0x6d, 0xac, 0xe9, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xe5, 0x1d, + 0xf8, 0xc8, 0xd9, 0xc8, 0xc2, 0x45, 0xbd, 0xf8, 0x68, 0x00, 0xa2, 0x41, + 0x01, 0x80, 0x2d, 0x6e, 0x42, 0x30, 0x1d, 0x1e, 0x1c, 0xca, 0xe2, 0x45, + 0x00, 0x0c, 0x7c, 0xfc, 0xa4, 0x80, 0x9c, 0xfc, 0x6c, 0x81, 0x43, 0xfc, + 0x64, 0x00, 0x20, 0x6d, 0x43, 0xf8, 0x64, 0x00, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0x51, 0x96, 0xe2, 0x45, 0x00, 0x0c, 0x3d, 0x22, 0x78, 0x50, + 0x19, 0xcf, 0x41, 0x4c, 0xaf, 0x69, 0x2d, 0x6e, 0xd7, 0xc8, 0xb0, 0x6d, + 0xaf, 0xe9, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x8d, 0x1e, 0xc2, 0x45, + 0xbd, 0xf8, 0x64, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x2d, 0x6e, 0x42, 0x30, + 0xb1, 0x1e, 0xd9, 0xcf, 0x1c, 0xca, 0xa2, 0x41, 0x01, 0xa4, 0x42, 0x50, + 0x00, 0xbc, 0xa0, 0x69, 0xa4, 0x41, 0x00, 0xa4, 0x3d, 0x22, 0x78, 0x50, + 0x60, 0x00, 0x4c, 0x08, 0xa0, 0xe9, 0x44, 0xfc, 0xc8, 0x2d, 0x42, 0x50, + 0x00, 0x04, 0x44, 0xf8, 0xc8, 0x2d, 0xf2, 0xce, 0x41, 0x4c, 0xa2, 0x41, + 0x01, 0xa4, 0x42, 0x50, 0x00, 0xbc, 0xa0, 0x69, 0xa4, 0x41, 0x00, 0xa4, + 0x3d, 0x22, 0x78, 0x50, 0x60, 0x00, 0x4c, 0x08, 0xa0, 0xe9, 0x44, 0xfc, + 0xc8, 0x2d, 0x40, 0x00, 0x8c, 0x52, 0x44, 0xf8, 0xc8, 0x2d, 0xde, 0xce, + 0x41, 0x4c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xed, 0x12, 0xe2, 0x45, + 0x01, 0xee, 0x08, 0xcf, 0x47, 0x48, 0x00, 0x0c, 0xa2, 0x41, 0x01, 0xa4, + 0x42, 0x50, 0x00, 0xbc, 0xa3, 0x41, 0x00, 0xa4, 0x20, 0xe8, 0x43, 0xfc, + 0xc8, 0x2d, 0x42, 0x50, 0x00, 0x04, 0x43, 0xf8, 0xc8, 0x2d, 0xbf, 0x45, + 0xe1, 0x4f, 0x81, 0xed, 0xa2, 0x41, 0x01, 0xa4, 0x42, 0x50, 0x28, 0xbc, + 0x67, 0xc8, 0x20, 0x69, 0xc2, 0x6a, 0x6c, 0x45, 0x04, 0x0e, 0x21, 0x2e, + 0x65, 0x94, 0x4d, 0x00, 0x5c, 0xfc, 0xa4, 0x80, 0xa2, 0x6a, 0x03, 0x6b, + 0xd0, 0x6e, 0x66, 0x94, 0x16, 0x00, 0xa2, 0xea, 0xa4, 0x69, 0x09, 0x6e, + 0xb0, 0x6d, 0xa4, 0xe9, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xc5, 0x1d, + 0xc2, 0x45, 0x1d, 0xf8, 0x28, 0x00, 0x02, 0x69, 0x32, 0x8d, 0x7c, 0xfc, + 0xa4, 0x80, 0x39, 0x69, 0x20, 0x6d, 0x39, 0xe9, 0x01, 0xed, 0x2c, 0x45, + 0x10, 0x47, 0xa3, 0x69, 0xb0, 0x6d, 0x0d, 0x8e, 0xa3, 0xe9, 0x08, 0x69, + 0xe2, 0x40, 0x65, 0x00, 0xc2, 0x94, 0x74, 0x00, 0x00, 0x0c, 0x84, 0x69, + 0x07, 0x69, 0x62, 0x00, 0x90, 0x13, 0x6f, 0x8d, 0x01, 0xed, 0xb1, 0x41, + 0x01, 0x80, 0x09, 0x6e, 0x31, 0x32, 0xc5, 0x1d, 0xd1, 0x45, 0x1d, 0xf8, + 0x28, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xa1, 0x1d, 0x40, 0x32, + 0x01, 0x00, 0x09, 0x6e, 0xc2, 0x45, 0x5d, 0xfa, 0x10, 0x00, 0x09, 0x6e, + 0xd1, 0x45, 0x5d, 0xfa, 0x28, 0x00, 0x02, 0x69, 0x52, 0xad, 0x7c, 0xfc, + 0xa4, 0x80, 0x2c, 0x45, 0x35, 0x69, 0x20, 0x6d, 0x35, 0xe9, 0x01, 0xed, + 0x10, 0x47, 0xa6, 0x69, 0x06, 0x6b, 0xb0, 0x6d, 0xa6, 0x94, 0x0d, 0x00, + 0xa6, 0xe9, 0xa8, 0x69, 0x0a, 0xc8, 0xb0, 0x6d, 0xa8, 0xe9, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0xc5, 0x1d, 0xe2, 0x45, 0x09, 0x6e, 0xb6, 0xcf, + 0x02, 0x69, 0xa7, 0x69, 0xb0, 0x6d, 0x10, 0x8e, 0xa7, 0xe9, 0x05, 0x69, + 0xa2, 0x40, 0x2b, 0x00, 0x08, 0x69, 0x42, 0xb0, 0x02, 0x00, 0x02, 0xb4, + 0xb0, 0xff, 0x01, 0xed, 0x04, 0x69, 0x87, 0x69, 0x62, 0x00, 0x90, 0x13, + 0xe2, 0x40, 0xa8, 0xff, 0xb1, 0x41, 0x01, 0x80, 0x09, 0x6e, 0x31, 0x32, + 0xc5, 0x1d, 0xd1, 0x45, 0x1d, 0xf8, 0x28, 0x00, 0xa2, 0x41, 0x01, 0x80, + 0x09, 0x6e, 0x42, 0x30, 0xa1, 0x1d, 0xc2, 0x45, 0x1d, 0xf8, 0x10, 0x00, + 0x01, 0xed, 0x09, 0x6e, 0xd1, 0x45, 0x5d, 0xf8, 0x28, 0x00, 0x8c, 0xcf, + 0x02, 0x69, 0x05, 0x69, 0x42, 0xb0, 0x02, 0x00, 0x02, 0xb4, 0x8d, 0xff, + 0x01, 0xed, 0x98, 0xcf, 0x84, 0x69, 0xc2, 0xb4, 0xd9, 0xff, 0x00, 0x0c, + 0x08, 0x69, 0x5e, 0x8d, 0xb1, 0x41, 0x01, 0x80, 0xd4, 0xcf, 0x04, 0x69, + 0x05, 0x69, 0x02, 0x94, 0x92, 0xff, 0xb1, 0x41, 0x01, 0x80, 0x88, 0xcf, + 0x84, 0x69, 0x00, 0x0c, 0xa2, 0x41, 0x02, 0xa5, 0x62, 0xfc, 0x10, 0x0d, + 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xc0, 0x6e, 0x62, 0xfc, + 0x14, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xc4, 0x6e, + 0x62, 0xfc, 0x18, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, + 0xc8, 0x6e, 0x62, 0xfc, 0x1c, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, + 0x64, 0xf8, 0xcc, 0x6e, 0x62, 0xfc, 0x20, 0x0d, 0xa4, 0x41, 0x04, 0x80, + 0xb1, 0x25, 0x64, 0xf8, 0xd0, 0x6e, 0x62, 0xfc, 0x24, 0x0d, 0xa4, 0x41, + 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xd4, 0x6e, 0x62, 0xfc, 0x28, 0x0d, + 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xd8, 0x6e, 0x62, 0xfc, + 0x2c, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xdc, 0x6e, + 0x62, 0xfc, 0x30, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, + 0xe0, 0x6e, 0x62, 0xfc, 0x34, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, + 0x64, 0xf8, 0xe4, 0x6e, 0x42, 0xfc, 0x38, 0x0d, 0xa3, 0x41, 0x04, 0x80, + 0x21, 0x25, 0x9f, 0x45, 0x43, 0xf8, 0xe8, 0x6e, 0x44, 0xfc, 0xbc, 0x01, + 0x64, 0xfc, 0xc8, 0x01, 0xa5, 0x2e, 0xb0, 0xae, 0x63, 0x00, 0xac, 0x28, + 0xa2, 0x41, 0x04, 0x80, 0xa2, 0xfc, 0xc0, 0x6e, 0x44, 0x34, 0xbc, 0x01, + 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0x8c, 0x52, 0x44, 0x38, 0xbc, 0x01, + 0xa5, 0x41, 0x04, 0x80, 0xa5, 0xfc, 0xcc, 0x6e, 0xa3, 0x00, 0x50, 0x28, + 0x45, 0x00, 0xcc, 0x5a, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x04, 0x80, + 0xa5, 0xfc, 0xd8, 0x6e, 0xa3, 0x00, 0x50, 0x18, 0x43, 0x00, 0x0c, 0x63, + 0x44, 0x38, 0xbc, 0x01, 0x64, 0xfc, 0xbc, 0x01, 0x63, 0xd0, 0x18, 0x00, + 0xbc, 0xad, 0xa3, 0x41, 0x04, 0x80, 0x63, 0xfc, 0xe4, 0x6e, 0x43, 0x00, + 0x4c, 0x73, 0x9f, 0x45, 0x44, 0x38, 0xbc, 0x01, 0x42, 0xd0, 0x05, 0x00, + 0x01, 0xef, 0xc2, 0x94, 0x36, 0x00, 0x00, 0x0c, 0x07, 0xed, 0x45, 0x94, + 0x70, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xa2, 0xfc, 0xc8, 0x6e, 0x44, 0x34, + 0xbc, 0x01, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0x8c, 0x52, 0x44, 0x38, + 0xbc, 0x01, 0xa5, 0x41, 0x04, 0x80, 0xa5, 0xfc, 0xd4, 0x6e, 0xa3, 0x00, + 0x50, 0x28, 0x45, 0x00, 0xcc, 0x5a, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, + 0x04, 0x80, 0xa5, 0xfc, 0xe0, 0x6e, 0xa3, 0x00, 0x50, 0x18, 0x43, 0x00, + 0x0c, 0x63, 0x44, 0x38, 0xbc, 0x01, 0xa3, 0x41, 0x04, 0x80, 0x63, 0xfc, + 0xe4, 0x6e, 0xb1, 0x25, 0x43, 0x00, 0x4c, 0x73, 0x9f, 0x45, 0x44, 0x38, + 0xbc, 0x01, 0x63, 0xfc, 0xe4, 0x6e, 0xb5, 0x25, 0x43, 0x00, 0x4c, 0x73, + 0x9f, 0x45, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x04, 0x80, 0xc5, 0xfc, + 0xc4, 0x6e, 0xa4, 0x34, 0xbc, 0x01, 0xc3, 0x00, 0x50, 0x30, 0xa6, 0x00, + 0x8c, 0x52, 0xa4, 0x38, 0xbc, 0x01, 0xa6, 0x41, 0x04, 0x80, 0xc6, 0xfc, + 0xd0, 0x6e, 0xc3, 0x00, 0x50, 0x30, 0xa6, 0x00, 0xcc, 0x5a, 0xa4, 0x38, + 0xbc, 0x01, 0xa6, 0x41, 0x04, 0x80, 0xc6, 0xfc, 0xdc, 0x6e, 0xc3, 0x00, + 0x50, 0x30, 0xa6, 0x00, 0x0c, 0x63, 0xa4, 0x38, 0xbc, 0x01, 0xc4, 0xfc, + 0xbc, 0x01, 0x65, 0x2f, 0x46, 0x94, 0x0a, 0x00, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0xfc, 0xe4, 0x6e, 0x2d, 0x25, 0xa2, 0x00, 0x4c, 0x73, 0x9f, 0x45, + 0xa4, 0x38, 0xbc, 0x01, 0xa2, 0x41, 0x04, 0x80, 0xc2, 0xfc, 0xe8, 0x6e, + 0x46, 0x00, 0xac, 0x10, 0x43, 0x00, 0x90, 0x1b, 0xe3, 0x40, 0x2e, 0x00, + 0xa6, 0x00, 0x4c, 0x73, 0x9f, 0x45, 0xa4, 0x38, 0xbc, 0x01, 0xa2, 0xfc, + 0xc8, 0x6e, 0x44, 0x34, 0xbc, 0x01, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, + 0x8c, 0x52, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x04, 0x80, 0xa5, 0xfc, + 0xd4, 0x6e, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0xcc, 0x5a, 0x44, 0x38, + 0xbc, 0x01, 0xa5, 0x41, 0x04, 0x80, 0xa5, 0xfc, 0xe0, 0x6e, 0xa3, 0x00, + 0x50, 0x18, 0x43, 0x00, 0x0c, 0x63, 0x44, 0x38, 0xbc, 0x01, 0xa3, 0x41, + 0x04, 0x80, 0x63, 0xfc, 0xe4, 0x6e, 0x63, 0x00, 0x40, 0x50, 0x43, 0x00, + 0x4c, 0x73, 0x9f, 0x45, 0x44, 0x38, 0xbc, 0x01, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0xfc, 0xe4, 0x6e, 0x29, 0x25, 0xa2, 0x00, 0x4c, 0x73, 0x9f, 0x45, + 0xa4, 0x38, 0xbc, 0x01, 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xc5, 0x44, 0xe5, 0xcb, 0xe2, 0x45, 0xe4, 0x0c, 0x64, 0x34, 0xbc, 0x01, + 0x60, 0x00, 0x4c, 0x4a, 0x64, 0x38, 0xbc, 0x01, 0x44, 0x60, 0x52, 0x00, + 0x44, 0x60, 0x4f, 0x10, 0x21, 0x2d, 0xe2, 0x40, 0x5a, 0x00, 0x44, 0x14, + 0x75, 0x00, 0x07, 0xee, 0x64, 0x00, 0x0c, 0x10, 0x1a, 0xee, 0x82, 0x94, + 0x9d, 0x00, 0x67, 0x38, 0xbc, 0x01, 0xb4, 0xed, 0x62, 0x94, 0xc1, 0x00, + 0xea, 0xed, 0x62, 0x94, 0xa0, 0x00, 0x60, 0x30, 0xf2, 0x00, 0x62, 0x94, + 0xd1, 0x00, 0x00, 0x0c, 0x47, 0x20, 0xe4, 0x11, 0x80, 0x30, 0xa0, 0x0f, + 0xa7, 0xfc, 0xf8, 0x01, 0x44, 0x00, 0x4c, 0xa2, 0x60, 0x00, 0x8c, 0x52, + 0x40, 0x00, 0x4c, 0xb5, 0x60, 0x00, 0xcc, 0x6a, 0x47, 0x20, 0xe4, 0x91, + 0x47, 0xfc, 0xbc, 0x01, 0x84, 0xed, 0x42, 0xd0, 0x05, 0x00, 0x62, 0xb4, + 0x3d, 0x00, 0x00, 0x0c, 0x40, 0x30, 0x10, 0x01, 0x65, 0xd0, 0x10, 0x3f, + 0x43, 0x94, 0x89, 0x00, 0x00, 0x0c, 0xc7, 0xfc, 0xc8, 0x01, 0x87, 0x30, + 0x60, 0x00, 0x60, 0x0c, 0x00, 0x31, 0x04, 0x00, 0xc6, 0x00, 0xac, 0x28, + 0x40, 0x09, 0x2b, 0x2d, 0xc2, 0x94, 0x99, 0x00, 0x40, 0x6e, 0xb0, 0x6d, + 0x03, 0xb5, 0xf8, 0xff, 0x40, 0x30, 0x00, 0x01, 0xa5, 0xd0, 0x00, 0x3f, + 0x45, 0xb4, 0x27, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x47, 0x14, 0x7d, 0x00, + 0x81, 0xed, 0x62, 0xb4, 0x1e, 0x00, 0x00, 0x0c, 0x67, 0xfc, 0xf8, 0x01, + 0x62, 0x00, 0x0c, 0x21, 0x18, 0xcc, 0x67, 0xf8, 0xf8, 0x01, 0x44, 0x34, + 0xd0, 0x01, 0x84, 0xed, 0x40, 0x00, 0x0c, 0x00, 0x44, 0x38, 0xd0, 0x01, + 0x47, 0xfc, 0xbc, 0x01, 0x42, 0xd0, 0x05, 0x00, 0x62, 0x94, 0xc6, 0xff, + 0xa7, 0xfc, 0xf8, 0x01, 0xa5, 0xd0, 0x00, 0x3f, 0x40, 0x30, 0x00, 0x01, + 0x45, 0x94, 0xde, 0xff, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xe8, 0x02, 0x62, 0xfc, 0xa4, 0x0b, 0xb6, 0x2d, 0xa4, 0x8d, 0xbc, 0xfc, + 0x90, 0xab, 0x87, 0x34, 0x44, 0x01, 0xc7, 0xfc, 0xa4, 0x01, 0xd6, 0x25, + 0xd6, 0x05, 0xb6, 0x25, 0xd7, 0x05, 0xb6, 0x25, 0x34, 0x05, 0x62, 0xfc, + 0x50, 0x02, 0x68, 0x05, 0x43, 0x00, 0x90, 0x13, 0xe2, 0x40, 0x0b, 0x00, + 0xe3, 0x40, 0x09, 0x00, 0x47, 0xfc, 0x48, 0x01, 0x06, 0x8d, 0x81, 0xed, + 0x47, 0x14, 0x76, 0x00, 0x62, 0x94, 0x5c, 0x00, 0x00, 0x0c, 0x07, 0x18, + 0x15, 0x01, 0xe5, 0x4b, 0x07, 0x18, 0xf4, 0x01, 0x06, 0x47, 0x47, 0x14, + 0x15, 0x01, 0x7a, 0x8d, 0xe5, 0x4b, 0xe5, 0x4b, 0x01, 0xed, 0x47, 0x18, + 0xf4, 0x01, 0x06, 0x47, 0x47, 0x14, 0x74, 0x00, 0x67, 0xfc, 0xe8, 0x01, + 0x2e, 0x6d, 0x22, 0x25, 0x62, 0x00, 0x8c, 0x48, 0x67, 0xcf, 0x67, 0xf8, + 0xe8, 0x01, 0x47, 0x14, 0x74, 0x00, 0x67, 0xfc, 0xe8, 0x01, 0x42, 0x30, + 0x34, 0x00, 0x22, 0x25, 0x62, 0x00, 0x8c, 0x48, 0x5b, 0xcf, 0x67, 0xf8, + 0xe8, 0x01, 0x47, 0x60, 0x52, 0x00, 0x47, 0x60, 0x4f, 0x10, 0x22, 0x2d, + 0x02, 0x94, 0x71, 0xff, 0x01, 0xed, 0x67, 0x14, 0x7d, 0x00, 0x43, 0x94, + 0x6c, 0xff, 0x00, 0x0c, 0xa0, 0x00, 0x0c, 0x21, 0x68, 0xcf, 0xa7, 0xf8, + 0xf8, 0x01, 0x47, 0x14, 0x74, 0x00, 0x67, 0xfc, 0xe8, 0x01, 0x42, 0x30, + 0x24, 0x00, 0x22, 0x25, 0x62, 0x00, 0x8c, 0x48, 0x3d, 0xcf, 0x67, 0xf8, + 0xe8, 0x01, 0xbe, 0x05, 0x43, 0x14, 0x70, 0x00, 0x67, 0x34, 0xd0, 0x01, + 0x27, 0x25, 0x62, 0x00, 0x8c, 0x7b, 0x86, 0xcf, 0x67, 0x38, 0xd0, 0x01, + 0x47, 0x14, 0x74, 0x00, 0x67, 0xfc, 0xe8, 0x01, 0x42, 0x30, 0x3c, 0x00, + 0x22, 0x25, 0x62, 0x00, 0x8c, 0x48, 0x26, 0xcf, 0x67, 0xf8, 0xe8, 0x01, + 0xae, 0xcf, 0x47, 0x18, 0x15, 0x01, 0x00, 0x0c, 0xb9, 0x41, 0x02, 0x80, + 0x60, 0x30, 0xb0, 0x03, 0xa2, 0x41, 0x04, 0x80, 0x39, 0x33, 0xd5, 0x09, + 0x99, 0x45, 0x62, 0xf8, 0x9c, 0x0e, 0x00, 0x0c, 0xe9, 0x4f, 0xa5, 0x41, + 0x00, 0x00, 0xbd, 0x22, 0x18, 0xd0, 0xb2, 0x41, 0x02, 0x80, 0xb1, 0x41, + 0x04, 0x80, 0x31, 0x32, 0x20, 0x0f, 0xa5, 0x30, 0x00, 0x00, 0x01, 0xee, + 0x52, 0x32, 0x4d, 0x1b, 0xb0, 0x41, 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, + 0x04, 0xc8, 0xd2, 0x45, 0x1d, 0xf8, 0x14, 0x00, 0x51, 0xfc, 0x68, 0x00, + 0x70, 0xfc, 0x24, 0x06, 0x20, 0x6d, 0x87, 0xad, 0x51, 0xf8, 0x68, 0x00, + 0x50, 0xfc, 0x20, 0x06, 0x05, 0x8d, 0xb3, 0x41, 0x04, 0x80, 0xbd, 0x22, + 0x18, 0x50, 0x0c, 0x47, 0x73, 0x32, 0x2c, 0x36, 0x53, 0xfc, 0x2c, 0x00, + 0xe2, 0x40, 0xf7, 0xff, 0xe2, 0x45, 0x0b, 0x6e, 0x80, 0x32, 0x01, 0x00, + 0x82, 0x96, 0xf1, 0xff, 0x00, 0x0c, 0x53, 0xfc, 0x30, 0x00, 0xe2, 0x40, + 0x05, 0x00, 0xe2, 0x45, 0x09, 0x6e, 0x82, 0x96, 0xe8, 0xff, 0x00, 0x0c, + 0x45, 0x48, 0x70, 0xfe, 0x34, 0x00, 0x82, 0x0c, 0x53, 0x00, 0xd0, 0x99, + 0x53, 0x00, 0x80, 0xf8, 0x62, 0x02, 0x10, 0x9b, 0x53, 0x00, 0xd0, 0x99, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xc1, 0x69, 0xe2, 0x45, 0x00, 0x0c, + 0x07, 0x69, 0x62, 0x02, 0x50, 0x9b, 0x13, 0xb4, 0x3f, 0x00, 0x45, 0x48, + 0x86, 0x69, 0x0c, 0x69, 0x62, 0x94, 0x4c, 0x00, 0x05, 0x6a, 0x82, 0x94, + 0x3b, 0x00, 0x00, 0x0c, 0x84, 0x6a, 0xa2, 0x94, 0x54, 0x00, 0x44, 0x48, + 0xf3, 0x40, 0xc1, 0xff, 0x51, 0xfc, 0x6c, 0x00, 0x20, 0x6d, 0x51, 0xf8, + 0x6c, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x49, 0x1a, 0xe2, 0x45, + 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xcf, 0x12, 0xe2, 0x45, + 0x00, 0x0c, 0x02, 0xb4, 0x54, 0x00, 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x41, + 0x00, 0x00, 0xa5, 0x30, 0x30, 0x00, 0xf2, 0x45, 0x01, 0xee, 0xa2, 0x41, + 0x08, 0x80, 0xb3, 0x0c, 0x42, 0x30, 0x83, 0x19, 0xe2, 0x45, 0x01, 0xee, + 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x30, 0x40, 0x00, 0xf2, 0x45, 0x01, 0xee, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xab, 0x18, 0xe2, 0x45, 0x00, 0x0c, + 0x92, 0xcf, 0x00, 0x0c, 0x70, 0xfe, 0x04, 0x00, 0xbf, 0xcf, 0x0d, 0xe9, + 0x04, 0x6a, 0x44, 0x48, 0x44, 0x00, 0x50, 0x2b, 0x93, 0x8e, 0x62, 0x00, + 0x50, 0x13, 0xa2, 0x40, 0xc1, 0xff, 0x02, 0x69, 0x8c, 0xe9, 0xbe, 0xcf, + 0x53, 0x00, 0x90, 0x9a, 0x44, 0x48, 0x44, 0x00, 0x50, 0x1b, 0xa3, 0x40, + 0x16, 0x00, 0x84, 0x69, 0x43, 0x00, 0x50, 0x13, 0xe2, 0x40, 0xf1, 0xff, + 0x02, 0x69, 0x0c, 0xea, 0xaf, 0xcf, 0x53, 0x00, 0x90, 0x9a, 0x62, 0x00, + 0x50, 0x2b, 0xe9, 0x8e, 0x82, 0x00, 0x50, 0x13, 0xa2, 0x40, 0xa6, 0xff, + 0x02, 0x69, 0x0c, 0xea, 0xa3, 0xcf, 0x53, 0x00, 0x90, 0x9a, 0x84, 0x69, + 0x43, 0x00, 0x50, 0x13, 0xa2, 0x40, 0x9c, 0xff, 0x02, 0x69, 0x8c, 0xe9, + 0x99, 0xcf, 0x53, 0x00, 0x90, 0x9a, 0xb1, 0x41, 0x08, 0x80, 0xa5, 0x30, + 0x10, 0x00, 0x01, 0xee, 0x31, 0x32, 0x9f, 0x18, 0xd2, 0x45, 0xb0, 0x41, + 0x08, 0x80, 0xd1, 0x45, 0x10, 0x32, 0xe7, 0x18, 0xf0, 0x45, 0x01, 0xee, + 0xa5, 0x41, 0x00, 0x00, 0x01, 0xee, 0xd2, 0x45, 0xa5, 0x30, 0x30, 0x00, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x83, 0x19, 0xb3, 0x0c, 0xe2, 0x45, + 0x01, 0xee, 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x30, 0x40, 0x00, 0xf2, 0x45, + 0x01, 0xee, 0xa5, 0x41, 0x00, 0x00, 0x01, 0xee, 0xd2, 0x45, 0xa5, 0x30, + 0x58, 0x00, 0xf1, 0x45, 0x00, 0x0c, 0xf0, 0x45, 0x80, 0x0c, 0x96, 0xcf, + 0xa2, 0x41, 0x08, 0x80, 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x84, 0x4c, + 0x42, 0x30, 0x6d, 0xf3, 0xe5, 0xcb, 0xe2, 0x45, 0x4f, 0x2e, 0xe5, 0x4b, + 0xa2, 0x41, 0x00, 0xa5, 0x02, 0xf8, 0x98, 0x38, 0x06, 0x47, 0x00, 0x0c, + 0xf1, 0x4f, 0x5c, 0xfc, 0xc4, 0xa7, 0xa3, 0x41, 0x04, 0x80, 0xa6, 0x41, + 0x08, 0x80, 0x63, 0x30, 0x20, 0x0f, 0xa8, 0x26, 0xc6, 0x30, 0x80, 0x47, + 0xea, 0x06, 0x83, 0xfc, 0xf0, 0x00, 0x46, 0x45, 0x50, 0x68, 0xa5, 0x41, + 0x08, 0x80, 0x24, 0x25, 0xa5, 0x30, 0xd0, 0x46, 0x54, 0x05, 0x40, 0x6e, + 0x1c, 0xf8, 0xc8, 0xa7, 0x20, 0xe8, 0x83, 0xf8, 0xf0, 0x00, 0x04, 0xc8, + 0x37, 0x8c, 0x1d, 0x38, 0x14, 0x00, 0x90, 0x60, 0x4e, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xad, 0x13, 0x90, 0x60, 0x4b, 0x10, 0xc2, 0x45, + 0x84, 0x30, 0x1e, 0x00, 0x50, 0xfc, 0x48, 0x01, 0x1c, 0x18, 0xa0, 0x81, + 0x34, 0x8d, 0x10, 0xf8, 0xb8, 0x01, 0xa4, 0x41, 0x04, 0x80, 0x50, 0x20, + 0x20, 0x11, 0x84, 0xfc, 0xa0, 0x0e, 0x20, 0x6d, 0xc6, 0x05, 0x62, 0x00, + 0x90, 0x13, 0x1a, 0x8d, 0xdc, 0xfc, 0xc4, 0xa7, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xa1, 0x16, 0xc2, 0x45, 0x9c, 0xfc, 0xc4, 0xa7, 0xa2, 0x41, + 0x02, 0xa5, 0x60, 0x50, 0x00, 0xff, 0x62, 0xf8, 0xd4, 0x29, 0x60, 0x30, + 0x00, 0x01, 0xa2, 0xe9, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x65, 0x19, + 0xe2, 0x45, 0x80, 0x0c, 0x06, 0x45, 0x08, 0x47, 0xa2, 0x41, 0x08, 0x80, + 0x89, 0x6f, 0x81, 0xee, 0x90, 0x0c, 0x42, 0x30, 0x95, 0x19, 0xc2, 0x45, + 0x1c, 0xf8, 0xbc, 0xa7, 0xe6, 0xcf, 0xa2, 0x41, 0x02, 0xa5, 0xdc, 0xfc, + 0xc4, 0xa7, 0xa2, 0x41, 0x08, 0x80, 0x88, 0x86, 0x42, 0x30, 0x95, 0x19, + 0xe2, 0x45, 0x89, 0x6f, 0xda, 0xcf, 0xa2, 0x41, 0x02, 0xa5, 0x00, 0x0c, + 0xf1, 0x4f, 0xa2, 0x41, 0x00, 0xb7, 0xa3, 0x41, 0x01, 0x01, 0x42, 0x30, + 0x50, 0x0d, 0x63, 0x30, 0x01, 0x07, 0x64, 0x45, 0x62, 0x60, 0x07, 0x80, + 0x62, 0x60, 0x04, 0x90, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x25, 0x44, + 0xb2, 0x41, 0x08, 0x80, 0xb1, 0x41, 0x03, 0x80, 0xc2, 0x45, 0xb0, 0x41, + 0x08, 0x80, 0x52, 0x32, 0x3f, 0x15, 0x31, 0x32, 0x6d, 0xc2, 0x10, 0x32, + 0x7c, 0x49, 0x90, 0x0c, 0xf1, 0x45, 0xff, 0xee, 0x7c, 0x8d, 0x82, 0x0c, + 0xf2, 0x45, 0x00, 0x0c, 0xf9, 0xcf, 0x90, 0x0c, 0xf5, 0x4f, 0x9b, 0xed, + 0x44, 0x45, 0x64, 0x94, 0x0b, 0x00, 0x05, 0x0e, 0xa0, 0xed, 0x64, 0x94, + 0x2c, 0x00, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0xed, 0x8b, 0x04, 0x45, + 0x99, 0x45, 0x0d, 0x4c, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, + 0x62, 0xfc, 0x98, 0x00, 0xa4, 0x41, 0x04, 0x80, 0x84, 0xfc, 0x80, 0x36, + 0xb0, 0x6d, 0x0c, 0x8e, 0x62, 0xf8, 0x98, 0x00, 0x85, 0x60, 0x17, 0x00, + 0xa2, 0x41, 0x04, 0x80, 0xdc, 0x6e, 0x42, 0x30, 0x61, 0x5c, 0xc2, 0x45, + 0x90, 0x60, 0x14, 0x10, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x54, 0xaf, + 0xe2, 0x45, 0x90, 0x0c, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, 0x61, 0x14, + 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x8d, 0x4c, 0xe2, 0x45, 0x5a, 0x6e, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, + 0x54, 0xaf, 0xe2, 0x45, 0x90, 0x0c, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, + 0x61, 0x14, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0xa4, 0x0c, 0xb9, 0x41, + 0x01, 0x80, 0xa4, 0x41, 0x04, 0x80, 0x44, 0xef, 0x39, 0x33, 0x61, 0xda, + 0x99, 0x45, 0x84, 0x30, 0x08, 0x6f, 0x00, 0x0c, 0xa2, 0x41, 0x01, 0xa4, + 0x81, 0xed, 0x42, 0x50, 0x10, 0xb0, 0xa0, 0xe9, 0xa4, 0x41, 0x00, 0xa4, + 0x44, 0xfc, 0xc8, 0x2d, 0xa3, 0x41, 0x02, 0xa5, 0xb9, 0x41, 0x04, 0x80, + 0x42, 0x50, 0x40, 0x00, 0x44, 0xf8, 0xc8, 0x2d, 0xa2, 0x41, 0x00, 0xa5, + 0x80, 0x30, 0x00, 0x1e, 0x82, 0xf8, 0xd4, 0x3c, 0xa2, 0x41, 0x05, 0x00, + 0x42, 0x50, 0x00, 0xab, 0x43, 0xf8, 0x34, 0x0d, 0x39, 0x33, 0x25, 0x44, + 0x03, 0xf8, 0x18, 0x0d, 0xb9, 0x45, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x85, 0x98, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0x25, 0x44, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0x43, 0xe8, 0x51, 0x69, 0x89, 0xed, + 0x7d, 0x38, 0x0a, 0x00, 0x22, 0x25, 0x51, 0xe9, 0x61, 0x69, 0x8f, 0xed, + 0x7d, 0x38, 0x0c, 0x00, 0x22, 0x25, 0x61, 0xe9, 0x52, 0x69, 0x60, 0x30, + 0xfa, 0xff, 0xab, 0x41, 0xff, 0x01, 0x24, 0x25, 0x52, 0xe9, 0x62, 0x69, + 0xaa, 0x41, 0xff, 0x00, 0x7d, 0x38, 0x02, 0x00, 0x24, 0x25, 0x62, 0xe9, + 0x25, 0xfd, 0x00, 0x00, 0xe0, 0x0c, 0x7d, 0x20, 0x14, 0xd0, 0x49, 0x00, + 0x80, 0xf8, 0x22, 0x01, 0x10, 0x1b, 0x1d, 0x0f, 0xfd, 0x31, 0x08, 0x00, + 0xc4, 0x0d, 0x40, 0x0e, 0xa0, 0x0d, 0x6b, 0x51, 0x25, 0xc0, 0x4a, 0x51, + 0x00, 0xc0, 0x81, 0xec, 0x02, 0xec, 0x20, 0x33, 0x03, 0x00, 0x1d, 0x38, + 0x00, 0x00, 0x1d, 0x38, 0x04, 0x00, 0x1d, 0x38, 0x08, 0x00, 0x87, 0x40, + 0x8d, 0x00, 0xa7, 0x05, 0x43, 0x01, 0x50, 0x13, 0xe2, 0x40, 0xda, 0x00, + 0x03, 0xcc, 0x40, 0x0c, 0xe8, 0x40, 0x08, 0x00, 0x20, 0x6d, 0xb2, 0x25, + 0x42, 0x00, 0x3c, 0x3b, 0xe2, 0xb4, 0xf8, 0xff, 0x43, 0x01, 0x50, 0x43, + 0x52, 0x00, 0x50, 0x43, 0x08, 0x94, 0xba, 0x00, 0x63, 0x01, 0x50, 0x43, + 0x08, 0x94, 0x07, 0x00, 0x2e, 0x6d, 0x20, 0x6d, 0xb4, 0xcc, 0xe0, 0x69, + 0xa8, 0x40, 0x0b, 0x00, 0x2e, 0x6d, 0x42, 0x00, 0x3c, 0x3b, 0x63, 0x00, + 0x80, 0x08, 0x52, 0x00, 0x50, 0x63, 0x0c, 0xb4, 0xf5, 0xff, 0x63, 0x01, + 0x50, 0x43, 0xe0, 0x69, 0x03, 0x01, 0x80, 0xf8, 0x68, 0x00, 0x10, 0x1b, + 0x87, 0x40, 0xa9, 0x00, 0x03, 0x01, 0xd0, 0x19, 0x43, 0x01, 0x50, 0x43, + 0xe8, 0x40, 0xa3, 0x00, 0x03, 0xcc, 0x40, 0x0e, 0xec, 0x40, 0x0b, 0x00, + 0x12, 0x31, 0x01, 0x00, 0x48, 0x02, 0x3c, 0x3b, 0xb2, 0x25, 0xf2, 0x00, + 0x50, 0x43, 0x08, 0xb4, 0xf5, 0xff, 0x43, 0x01, 0x50, 0x63, 0x42, 0x02, + 0x50, 0x1b, 0x82, 0x8d, 0x12, 0x0d, 0x02, 0x0d, 0x2d, 0x96, 0x9e, 0x00, + 0x08, 0x01, 0x3c, 0x3b, 0x0d, 0x96, 0x92, 0x00, 0x00, 0x0c, 0x08, 0x31, + 0xf2, 0xff, 0xe8, 0x00, 0x3c, 0x3b, 0x87, 0x40, 0x5a, 0x00, 0xe0, 0x69, + 0x40, 0x0c, 0x20, 0x6d, 0x42, 0x00, 0x3c, 0x3b, 0x29, 0x01, 0x00, 0x08, + 0x47, 0xb4, 0xf9, 0xff, 0xb2, 0x25, 0x49, 0x30, 0x00, 0x10, 0xe9, 0x90, + 0x00, 0x00, 0xe2, 0x00, 0x18, 0x48, 0x43, 0x30, 0x00, 0x10, 0xe3, 0x90, + 0x00, 0x00, 0xa2, 0x4d, 0xe2, 0x00, 0x18, 0x18, 0x29, 0x01, 0x00, 0x60, + 0x69, 0x00, 0x50, 0x19, 0x4d, 0xd0, 0xff, 0xff, 0x6e, 0xf8, 0x00, 0x00, + 0xa2, 0x01, 0x3c, 0x3b, 0xd2, 0x6e, 0x04, 0x4f, 0xe4, 0x4d, 0x62, 0x6f, + 0x22, 0x97, 0x30, 0x00, 0xc8, 0x4d, 0x25, 0xfd, 0x00, 0x00, 0xef, 0x3c, + 0x00, 0x00, 0x58, 0x3e, 0x00, 0x00, 0x49, 0x00, 0x80, 0xf8, 0x22, 0x01, + 0x10, 0x1b, 0xc7, 0x40, 0x75, 0xff, 0xa7, 0x05, 0x52, 0x40, 0x52, 0x00, + 0x40, 0x0c, 0x63, 0x01, 0x50, 0x13, 0x02, 0x94, 0x8b, 0xff, 0x40, 0x0c, + 0xe0, 0x69, 0xe3, 0x00, 0x80, 0xf8, 0x5f, 0x44, 0xf7, 0x05, 0x63, 0x01, + 0x50, 0x43, 0x08, 0x94, 0x05, 0x00, 0xe0, 0x0c, 0xa6, 0xcf, 0x40, 0x0e, + 0xa8, 0x40, 0x2a, 0x00, 0xfe, 0x6f, 0x63, 0x00, 0x80, 0x08, 0xe7, 0x00, + 0x3c, 0x3b, 0x47, 0xb6, 0xf7, 0xff, 0x63, 0x01, 0x50, 0x43, 0x9b, 0xcf, + 0x42, 0x02, 0x50, 0x1b, 0x7d, 0x20, 0x14, 0x50, 0x08, 0x47, 0x07, 0x94, + 0xae, 0xff, 0xe0, 0x00, 0xd0, 0x39, 0x40, 0x0c, 0x20, 0x6d, 0x03, 0x01, + 0x40, 0xf8, 0x89, 0x01, 0x40, 0xf8, 0x42, 0x00, 0x3c, 0x3b, 0x68, 0x00, + 0x50, 0x19, 0x2c, 0x01, 0x50, 0x49, 0xe2, 0x00, 0x50, 0x43, 0x29, 0x01, + 0x80, 0x08, 0x08, 0xb4, 0xef, 0xff, 0x63, 0x00, 0x80, 0x08, 0x99, 0xcf, + 0x49, 0x30, 0x00, 0x10, 0x78, 0xcf, 0x47, 0x0e, 0xe0, 0x69, 0x03, 0x01, + 0x80, 0xf8, 0x68, 0x00, 0x10, 0x1b, 0x03, 0x01, 0xd0, 0x19, 0x43, 0x01, + 0x50, 0x43, 0xa8, 0x40, 0x5d, 0xff, 0x12, 0x40, 0xbe, 0xff, 0x00, 0x0c, + 0x68, 0xcf, 0x40, 0x0e, 0x31, 0xcf, 0x40, 0x0c, 0x64, 0xcf, 0x40, 0x0e, + 0x43, 0x69, 0x68, 0x00, 0x00, 0x20, 0x34, 0x05, 0x43, 0xe9, 0x69, 0xcf, + 0x25, 0xfd, 0x00, 0x00, 0x43, 0x69, 0x4c, 0x4c, 0x02, 0x01, 0x50, 0x11, + 0x43, 0xe9, 0x61, 0xcf, 0x25, 0xfd, 0x00, 0x00, 0xf1, 0x4f, 0x64, 0x45, + 0x24, 0x62, 0x03, 0x00, 0x04, 0x0e, 0xa2, 0x41, 0x03, 0x80, 0x30, 0x62, + 0x00, 0x10, 0x80, 0x30, 0x2c, 0x01, 0x42, 0x30, 0x65, 0xab, 0xe2, 0x45, + 0x47, 0x0e, 0x11, 0x94, 0x5d, 0x00, 0xb9, 0x41, 0x01, 0x80, 0x08, 0x09, + 0x82, 0x30, 0xdc, 0xff, 0x62, 0x30, 0x9c, 0xff, 0x84, 0x00, 0x3c, 0x2b, + 0x63, 0x00, 0x3c, 0x2b, 0xe4, 0x00, 0x80, 0xf8, 0xc3, 0x00, 0x80, 0xf8, + 0x42, 0x30, 0x5b, 0x00, 0x42, 0x00, 0x3c, 0x2b, 0x67, 0x44, 0x5e, 0x44, + 0xa2, 0x00, 0x80, 0xf8, 0x79, 0x06, 0xe7, 0x05, 0x55, 0x44, 0x84, 0x00, + 0x3c, 0x2b, 0x63, 0x00, 0x3c, 0x2b, 0x55, 0x05, 0x64, 0x00, 0x50, 0x2b, + 0xa0, 0x8e, 0x42, 0x00, 0x3c, 0x2b, 0x44, 0x00, 0x50, 0x13, 0x02, 0xb4, + 0x4b, 0x00, 0x39, 0x33, 0xf9, 0xf4, 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, + 0x0e, 0x00, 0xb9, 0x41, 0x01, 0x80, 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, + 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, + 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x39, 0x33, 0xf9, 0xf4, + 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x43, 0x00, 0x50, 0x13, 0x65, 0x8d, + 0xb9, 0x41, 0x01, 0x80, 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, 0x0d, 0x00, + 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, + 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, + 0x3c, 0x2b, 0x39, 0x33, 0xf9, 0xf4, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, 0x0b, 0x00, 0xa2, 0x00, 0xec, 0x01, + 0x82, 0x00, 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, + 0xd2, 0x26, 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x39, 0x33, + 0xf9, 0xf4, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x52, 0x14, 0x3d, 0x00, + 0x72, 0x1c, 0x0c, 0x00, 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, 0x00, 0xc8, + 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, 0xa5, 0xd0, + 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0xd5, 0x4f, 0x3d, 0x23, 0x30, 0xd0, 0x3f, 0x49, 0x9d, 0x22, 0x68, 0x10, + 0xdd, 0x22, 0x70, 0x10, 0x0f, 0x8e, 0xde, 0x4b, 0xb9, 0x41, 0x02, 0x80, + 0x39, 0x33, 0xfd, 0xa8, 0x9d, 0x22, 0x68, 0x90, 0xdd, 0x22, 0x70, 0x90, + 0xde, 0xcb, 0x3f, 0xc9, 0x3d, 0x23, 0x30, 0x50, 0x99, 0x45, 0x2d, 0x4c, + 0xb0, 0x41, 0x02, 0x80, 0x45, 0x0e, 0x66, 0x0e, 0x83, 0xee, 0xc0, 0x0c, + 0x01, 0xee, 0x10, 0x32, 0xa9, 0x95, 0x27, 0x0e, 0xd0, 0x45, 0x3d, 0xf9, + 0x28, 0x00, 0x2a, 0x49, 0xa2, 0x41, 0x02, 0x80, 0x6a, 0x84, 0x90, 0x87, + 0x42, 0x30, 0xfd, 0xa8, 0x29, 0xc9, 0x9d, 0x22, 0x10, 0x90, 0xdd, 0x22, + 0x18, 0x90, 0xc2, 0x45, 0xdd, 0xfb, 0x20, 0x00, 0x80, 0x0c, 0xc0, 0x0c, + 0xf0, 0x45, 0x83, 0xee, 0xa2, 0x41, 0x04, 0x80, 0x62, 0x30, 0xb4, 0x1a, + 0x63, 0x60, 0x03, 0x00, 0x82, 0x30, 0xb4, 0x1a, 0x64, 0x60, 0x00, 0x10, + 0xe3, 0x40, 0x03, 0x00, 0x3d, 0x23, 0x30, 0x50, 0x16, 0x47, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0xb9, 0x74, 0xe2, 0x45, 0x00, 0x0c, 0x81, 0xed, + 0xa2, 0x41, 0x04, 0x80, 0x62, 0x18, 0x05, 0x6f, 0x3d, 0x23, 0x30, 0x50, + 0x16, 0x47, 0x00, 0x0c, 0xc1, 0x4f, 0x9d, 0x22, 0x6c, 0xd0, 0xb3, 0x41, + 0x04, 0x80, 0x53, 0x14, 0x05, 0x6f, 0x04, 0x0e, 0x3d, 0xfe, 0x90, 0x00, + 0x23, 0x8d, 0x5d, 0xfe, 0xa0, 0x00, 0x45, 0xb0, 0x0f, 0x00, 0x42, 0x70, + 0x01, 0x00, 0x50, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0x81, 0xed, 0x21, 0x6e, + 0x42, 0x30, 0xd9, 0x74, 0xbd, 0x18, 0x48, 0x00, 0xfd, 0x18, 0x4a, 0x00, + 0xf6, 0xc8, 0xbd, 0x20, 0x5c, 0x90, 0x11, 0xca, 0x3d, 0x1a, 0x49, 0x00, + 0x5d, 0x1a, 0x4b, 0x00, 0x7d, 0x18, 0x4c, 0x00, 0xc2, 0x45, 0x7d, 0x18, + 0x4d, 0x00, 0xf6, 0x48, 0xbd, 0x20, 0x5c, 0x10, 0x13, 0x18, 0x05, 0x6f, + 0x5d, 0xfc, 0xbc, 0x00, 0x24, 0xca, 0x4f, 0xc8, 0x5d, 0xfc, 0xb8, 0x00, + 0x48, 0xca, 0x4e, 0xc8, 0x5d, 0xfc, 0xb4, 0x00, 0x4d, 0xc8, 0x5d, 0xfc, + 0xb0, 0x00, 0x4c, 0xc8, 0x5d, 0x14, 0xac, 0x00, 0x4b, 0xc8, 0x5d, 0xfc, + 0xa8, 0x00, 0x4a, 0xc8, 0x5d, 0xfc, 0xa4, 0x00, 0x49, 0xc8, 0x5d, 0xfc, + 0x9c, 0x00, 0x47, 0xc8, 0x5d, 0xfc, 0x98, 0x00, 0x46, 0xc8, 0x5d, 0xfc, + 0x94, 0x00, 0x45, 0xc8, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x49, 0xab, + 0xe2, 0x45, 0x90, 0x0c, 0x9d, 0x22, 0x6c, 0x50, 0x9f, 0x45, 0x41, 0x4c, + 0xe5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x1d, 0x23, 0x14, 0xd0, 0xa2, 0x36, + 0x0a, 0x6f, 0xb5, 0xd2, 0x0f, 0x00, 0x55, 0x30, 0xff, 0xff, 0x42, 0xb0, + 0x02, 0x00, 0x02, 0xb4, 0xc2, 0x00, 0x09, 0xed, 0xb5, 0x72, 0x03, 0x00, + 0x80, 0x32, 0x03, 0x00, 0xa0, 0x02, 0x18, 0x10, 0xa0, 0x02, 0x18, 0xa0, + 0xa2, 0x0e, 0x04, 0x94, 0xb0, 0x00, 0xb3, 0x41, 0x08, 0x80, 0xb2, 0x41, + 0x08, 0x80, 0xc4, 0x0e, 0x24, 0x32, 0x3c, 0x00, 0xe0, 0x0e, 0x00, 0x32, + 0xff, 0x3f, 0x73, 0x32, 0x43, 0x11, 0x11, 0xcc, 0x52, 0x32, 0x1f, 0x17, + 0x64, 0x94, 0x36, 0x00, 0x00, 0x0c, 0xc2, 0x00, 0x58, 0x28, 0xd3, 0x45, + 0xdc, 0xfc, 0x48, 0x81, 0xd2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0xc8, 0x4e, + 0xd1, 0x96, 0x2e, 0x00, 0x00, 0x0c, 0xb6, 0xfc, 0x00, 0x00, 0x40, 0x50, + 0x00, 0x90, 0x0f, 0xef, 0x51, 0x26, 0xa9, 0x05, 0x44, 0x00, 0x90, 0x13, + 0x84, 0xd0, 0xff, 0x3f, 0xf7, 0x30, 0x01, 0x00, 0x00, 0x31, 0x04, 0x09, + 0x04, 0x96, 0xeb, 0xff, 0x63, 0xd0, 0xff, 0x3f, 0x43, 0x00, 0x58, 0x20, + 0x44, 0x00, 0x2c, 0x1a, 0x60, 0x30, 0xd4, 0x09, 0xdd, 0x2e, 0xc2, 0x94, + 0xda, 0xff, 0xe7, 0xd2, 0xff, 0x00, 0x85, 0x02, 0xd0, 0x11, 0x2d, 0x2d, + 0x04, 0xb5, 0xce, 0xff, 0xc4, 0x70, 0xd8, 0x09, 0xa5, 0x02, 0xd0, 0x29, + 0xce, 0xcf, 0xdd, 0x2e, 0x85, 0x02, 0xd0, 0x29, 0xca, 0xcf, 0xdd, 0x2e, + 0x17, 0x94, 0x64, 0x00, 0x81, 0xed, 0xb4, 0x41, 0x04, 0x80, 0xb0, 0x41, + 0x04, 0x80, 0xb3, 0x41, 0x08, 0x80, 0xb2, 0x41, 0x08, 0x80, 0x94, 0x32, + 0x10, 0x6f, 0x10, 0x32, 0x4c, 0x6f, 0x20, 0x32, 0xff, 0x3f, 0x73, 0x32, + 0x43, 0x11, 0x52, 0x32, 0x1f, 0x17, 0x54, 0xfc, 0x00, 0x00, 0x80, 0x50, + 0x00, 0x90, 0x88, 0x4e, 0xad, 0x2e, 0x21, 0x25, 0xc5, 0x05, 0x63, 0xd0, + 0xff, 0x3f, 0x82, 0x00, 0x90, 0x23, 0x42, 0xd0, 0xff, 0x3f, 0x82, 0x00, + 0x18, 0x18, 0x22, 0x96, 0x07, 0x00, 0x83, 0x0c, 0xd3, 0x45, 0xdc, 0xfc, + 0x48, 0x81, 0xd2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0x90, 0xb6, 0xe5, 0xff, + 0xa2, 0x41, 0x04, 0x80, 0x62, 0x14, 0x4c, 0x6f, 0x01, 0xed, 0x43, 0xb4, + 0x2b, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x62, 0xfc, 0x50, 0x6f, 0xa2, 0x41, + 0x00, 0xa4, 0x42, 0x50, 0x04, 0x99, 0xa0, 0xe9, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x54, 0x6f, 0x62, 0xf8, 0xd0, 0x00, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x58, 0x6f, 0x62, 0xf8, 0xd4, 0x00, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x5c, 0x6f, 0x62, 0xf8, 0x00, 0x06, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x60, 0x6f, 0x62, 0xf8, 0xd0, 0x06, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x64, 0x6f, 0x62, 0xf8, 0xd4, 0x06, 0xa2, 0x41, 0x04, 0x80, + 0x02, 0x18, 0x04, 0x6f, 0x1d, 0x23, 0x14, 0x50, 0x0e, 0x47, 0x81, 0xed, + 0xa2, 0x41, 0x04, 0x80, 0x9a, 0xcf, 0x62, 0x18, 0x04, 0x6f, 0x80, 0x0e, + 0x46, 0xcf, 0xa0, 0x32, 0x05, 0x00, 0x00, 0x0c, 0xd5, 0x4f, 0xdd, 0x22, + 0x3c, 0xd0, 0x04, 0x0e, 0x3d, 0x22, 0x68, 0x10, 0x7d, 0x22, 0x70, 0x10, + 0x2d, 0x8e, 0xbe, 0x4a, 0x47, 0x14, 0xa8, 0x00, 0xa4, 0x41, 0x04, 0x80, + 0x81, 0xed, 0x62, 0x94, 0x3a, 0x00, 0x44, 0x18, 0x4c, 0x6f, 0xa2, 0x41, + 0x03, 0x80, 0x90, 0x0c, 0x42, 0x30, 0x85, 0x99, 0x3d, 0x22, 0x10, 0x90, + 0x7d, 0x22, 0x18, 0x90, 0xc2, 0x45, 0xbd, 0xfa, 0x20, 0x00, 0x0e, 0x8c, + 0x01, 0xed, 0x50, 0xb4, 0x08, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x02, 0x18, + 0x6d, 0x6f, 0xa2, 0x41, 0x04, 0x80, 0x02, 0x18, 0x68, 0x6f, 0xdd, 0x22, + 0x3c, 0x50, 0x16, 0x47, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0xdd, 0x6a, + 0xdd, 0x22, 0x3c, 0x50, 0x99, 0x45, 0x2d, 0x4c, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0x15, 0x5a, 0xbd, 0x20, 0x28, 0x90, 0xc2, 0x45, 0xfd, 0xf8, + 0x30, 0x00, 0xec, 0x48, 0xa4, 0x41, 0x04, 0x80, 0x81, 0xed, 0x47, 0x14, + 0xa8, 0x00, 0xbd, 0x20, 0x28, 0x10, 0x62, 0xb4, 0xca, 0xff, 0x44, 0x18, + 0x4c, 0x6f, 0x67, 0x15, 0xa9, 0x00, 0x47, 0x15, 0xaa, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0x27, 0x15, 0xab, 0x00, 0x07, 0x15, 0xac, 0x00, 0x62, 0xf9, + 0x50, 0x6f, 0xa2, 0x41, 0x04, 0x80, 0x87, 0x14, 0xad, 0x00, 0x42, 0xf9, + 0x54, 0x6f, 0xa2, 0x41, 0x04, 0x80, 0x67, 0x14, 0xae, 0x00, 0x22, 0xf9, + 0x58, 0x6f, 0xa2, 0x41, 0x04, 0x80, 0x02, 0xf9, 0x5c, 0x6f, 0xa2, 0x41, + 0x04, 0x80, 0x82, 0xf8, 0x60, 0x6f, 0xa2, 0x41, 0x04, 0x80, 0xa5, 0xcf, + 0x62, 0xf8, 0x64, 0x6f, 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0x45, 0x44, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0xb9, 0x41, + 0x03, 0x80, 0x80, 0x30, 0x2c, 0x01, 0x39, 0x33, 0x65, 0xab, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xe5, 0x4f, 0x1d, 0x23, 0x14, 0xd0, 0x86, 0x40, + 0x2d, 0x00, 0xc4, 0x0e, 0x66, 0x32, 0xff, 0xff, 0x73, 0xd2, 0xff, 0xff, + 0x62, 0x4e, 0x73, 0x02, 0x00, 0x10, 0xb7, 0x41, 0x02, 0x80, 0xb5, 0x41, + 0x02, 0x80, 0xb4, 0x41, 0x02, 0x80, 0x47, 0x0e, 0x05, 0x0e, 0x65, 0x02, + 0x50, 0x99, 0xf7, 0x32, 0xf5, 0x57, 0xb5, 0x32, 0xfd, 0x57, 0x94, 0x32, + 0x15, 0x58, 0xf7, 0x45, 0x00, 0x6a, 0x00, 0x6a, 0x32, 0x36, 0x00, 0x00, + 0xf5, 0x45, 0x95, 0x04, 0xb2, 0x34, 0x02, 0x00, 0x31, 0x02, 0x3c, 0x3b, + 0x91, 0x0c, 0xd5, 0x06, 0xd4, 0x45, 0xa5, 0x00, 0x3c, 0x3b, 0x00, 0xe9, + 0x02, 0x6c, 0x70, 0xb6, 0xec, 0xff, 0x00, 0x0c, 0x40, 0x30, 0xae, 0x00, + 0x56, 0x38, 0x00, 0x00, 0x5c, 0x38, 0xca, 0x81, 0x1d, 0x23, 0x14, 0x50, + 0x0e, 0x47, 0x00, 0x0c, 0xe9, 0x4f, 0x52, 0x48, 0x59, 0x45, 0xb1, 0x41, + 0x00, 0xa5, 0x11, 0xfe, 0x44, 0x12, 0x46, 0xc8, 0x51, 0x48, 0x45, 0xc8, + 0x5d, 0x14, 0x40, 0x00, 0x44, 0xc8, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0xb9, 0xa2, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0xff, 0xff, 0x42, 0x30, + 0x00, 0x01, 0x82, 0x44, 0x10, 0x52, 0x00, 0x80, 0x11, 0xfa, 0x44, 0x12, + 0x19, 0x45, 0x0c, 0x47, 0x00, 0x31, 0x14, 0x00, 0x04, 0x01, 0x10, 0x40, + 0x06, 0xb4, 0x42, 0x00, 0x85, 0x49, 0x0e, 0xed, 0x45, 0x94, 0x08, 0x00, + 0xa0, 0x31, 0xb4, 0x09, 0xa5, 0x01, 0x00, 0x10, 0xad, 0x00, 0x50, 0x29, + 0xa5, 0x31, 0x67, 0x09, 0x5d, 0x14, 0x10, 0x00, 0x08, 0x01, 0x40, 0x08, + 0x0d, 0x01, 0xd0, 0x79, 0x44, 0x06, 0x44, 0x01, 0x00, 0x08, 0xca, 0x00, + 0x50, 0x51, 0x4a, 0x31, 0x10, 0x00, 0x4a, 0x01, 0x00, 0x10, 0x0d, 0x01, + 0x50, 0x41, 0xc0, 0x0c, 0x40, 0x0c, 0xc4, 0x0d, 0x47, 0x01, 0x50, 0x51, + 0x44, 0x26, 0x4e, 0x06, 0x24, 0xfd, 0x5c, 0x00, 0x64, 0xfc, 0x54, 0x00, + 0xaa, 0xfc, 0x00, 0x00, 0x8e, 0x0c, 0x69, 0x00, 0x50, 0x18, 0xdc, 0x06, + 0xa3, 0x00, 0x10, 0x1a, 0x60, 0x6f, 0xe3, 0x01, 0x90, 0x2b, 0x03, 0x01, + 0x90, 0x4b, 0x89, 0xae, 0x68, 0x00, 0x90, 0x5b, 0x0b, 0xb4, 0x07, 0x00, + 0xa3, 0x01, 0xd0, 0x19, 0x01, 0xed, 0x6c, 0xf8, 0x00, 0x00, 0xa9, 0x40, + 0xe1, 0xff, 0xbf, 0x45, 0x01, 0xed, 0x46, 0xb4, 0xc7, 0xff, 0xa0, 0x0d, + 0x45, 0xb0, 0xc5, 0x00, 0xa5, 0x01, 0x00, 0x10, 0x60, 0x30, 0x88, 0x13, + 0x20, 0x31, 0xa0, 0x0f, 0x49, 0x00, 0x58, 0x18, 0xad, 0x00, 0x50, 0x29, + 0xb9, 0xcf, 0x65, 0x00, 0x50, 0x69, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x79, 0x74, 0xc4, 0xc8, 0xa5, 0xc8, 0x86, 0xc8, + 0xe9, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xc4, 0x48, 0xa5, 0x48, 0x86, 0x48, + 0xe9, 0x4b, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0x71, 0x4f, 0x99, 0x45, + 0x15, 0x4c, 0x00, 0x0c, 0xd9, 0x4f, 0x05, 0xed, 0x4c, 0xc8, 0x08, 0xed, + 0x48, 0xc8, 0x01, 0xed, 0x5d, 0x22, 0x44, 0xd0, 0x86, 0xc8, 0x25, 0x0e, + 0x04, 0x0e, 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, + 0x0f, 0xc8, 0x9d, 0x8e, 0x45, 0xc8, 0x11, 0x6d, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0x83, 0xef, 0x18, 0xef, 0xa0, 0x0c, 0x42, 0x30, 0x2b, 0x11, + 0xc2, 0x45, 0x80, 0x30, 0x08, 0x10, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, + 0x42, 0x30, 0x1d, 0x0e, 0xe2, 0x45, 0x00, 0x0c, 0x5d, 0x22, 0x44, 0x50, + 0x14, 0x47, 0x19, 0x6d, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0x83, 0xef, + 0x18, 0xef, 0x42, 0x30, 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x08, 0x0a, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, + 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, 0x42, 0x30, 0x1d, 0x0e, 0xe2, 0x45, + 0x00, 0x0c, 0x5d, 0x22, 0x44, 0x50, 0x14, 0x47, 0xf1, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x79, 0xf2, 0x55, 0x45, 0x04, 0x0e, 0xe2, 0x45, + 0x25, 0x0e, 0xb9, 0x41, 0x04, 0x80, 0x98, 0x86, 0x39, 0x33, 0xf5, 0x56, + 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, 0x45, 0x90, 0xf4, 0x01, + 0x3e, 0x8d, 0xa2, 0x41, 0x00, 0xa4, 0x04, 0xb4, 0x7c, 0x00, 0x01, 0xed, + 0x45, 0x90, 0x0f, 0x00, 0x02, 0x94, 0xa7, 0x00, 0x40, 0x30, 0xf8, 0x00, + 0x0e, 0xed, 0x45, 0x94, 0xb0, 0x00, 0x00, 0x0c, 0xde, 0x6d, 0xb4, 0x26, + 0xba, 0x06, 0xa5, 0x30, 0x6c, 0x09, 0xd2, 0x25, 0x56, 0x26, 0x38, 0x06, + 0x5a, 0x25, 0x34, 0x05, 0x4a, 0x26, 0xc7, 0x05, 0x28, 0x26, 0xa2, 0x41, + 0x0f, 0x00, 0x42, 0x30, 0xe9, 0x0b, 0xa6, 0x05, 0xa2, 0x41, 0x19, 0x00, + 0x42, 0x30, 0x21, 0x03, 0x45, 0x05, 0x63, 0x00, 0x80, 0x68, 0x42, 0x00, + 0x80, 0x68, 0x1f, 0xee, 0xc3, 0x90, 0x20, 0x00, 0xa2, 0x90, 0x20, 0x00, + 0xc4, 0x00, 0x58, 0x18, 0xa4, 0x00, 0x58, 0x10, 0x82, 0x90, 0x00, 0x00, + 0xa3, 0x90, 0x00, 0x00, 0xa0, 0x00, 0x18, 0x18, 0x80, 0x00, 0x18, 0x10, + 0xb6, 0x25, 0x48, 0xcc, 0x26, 0x25, 0x42, 0x50, 0x30, 0x97, 0xa0, 0x6b, + 0xc2, 0xfc, 0x00, 0x06, 0x04, 0xb4, 0x59, 0x00, 0x52, 0x26, 0xd6, 0x25, + 0xc6, 0x05, 0xda, 0x26, 0x4a, 0x05, 0xba, 0x25, 0xb9, 0x05, 0xa8, 0x26, + 0xa4, 0x41, 0x0f, 0x00, 0xa2, 0x41, 0x19, 0x00, 0x84, 0x30, 0xe9, 0x0b, + 0x42, 0x30, 0x21, 0x03, 0xc6, 0x05, 0x55, 0x05, 0x63, 0x00, 0x80, 0x68, + 0x42, 0x00, 0x80, 0x68, 0x1f, 0xee, 0xa2, 0x90, 0x20, 0x00, 0x03, 0x91, + 0x20, 0x00, 0x04, 0x01, 0x58, 0x18, 0xa4, 0x00, 0x58, 0x10, 0x82, 0x90, + 0x00, 0x00, 0xa3, 0x90, 0x00, 0x00, 0x80, 0x00, 0x18, 0x10, 0xa0, 0x00, + 0x18, 0x18, 0xb6, 0x25, 0x26, 0x25, 0xe0, 0x00, 0xcc, 0x38, 0x63, 0x50, + 0x04, 0x00, 0xc0, 0x00, 0xcc, 0x38, 0x42, 0x50, 0x04, 0x00, 0xa4, 0x41, + 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, 0xdf, 0x44, 0xd6, 0x44, 0xc0, 0xe9, + 0x44, 0xf8, 0x00, 0x06, 0xbf, 0x45, 0x44, 0x94, 0x31, 0x00, 0x40, 0x30, + 0x88, 0x00, 0xe8, 0xed, 0xa4, 0x41, 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, + 0xc0, 0x6b, 0xc4, 0xfc, 0x00, 0x06, 0x63, 0x50, 0x04, 0x00, 0xe0, 0x00, + 0xcc, 0x38, 0xc0, 0x00, 0xcc, 0x38, 0x42, 0x50, 0x04, 0x00, 0xa4, 0x41, + 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, 0xdf, 0x44, 0xd6, 0x44, 0xc0, 0xe9, + 0x44, 0xf8, 0x00, 0x06, 0xbf, 0x45, 0xd4, 0x25, 0xd6, 0x05, 0x58, 0x25, + 0x54, 0x05, 0xba, 0x25, 0xbb, 0x05, 0x28, 0x26, 0xa5, 0x41, 0x0f, 0x00, + 0xa2, 0x41, 0x19, 0x00, 0xa5, 0x30, 0xe9, 0x0b, 0x42, 0x30, 0x21, 0x03, + 0xd6, 0x05, 0xa8, 0xcf, 0x45, 0x05, 0xd4, 0xcf, 0x60, 0x30, 0xc8, 0x00, + 0xd4, 0x25, 0x45, 0x90, 0xb2, 0x00, 0x0c, 0x8d, 0xd6, 0x05, 0x63, 0x30, + 0x88, 0x13, 0x34, 0x26, 0x38, 0x06, 0x5b, 0xcf, 0x38, 0x25, 0x40, 0x30, + 0xf8, 0x00, 0xc4, 0xcf, 0x60, 0x30, 0xb8, 0x00, 0x63, 0x30, 0xa0, 0x0f, + 0x38, 0x25, 0x34, 0x26, 0x34, 0x05, 0x38, 0x06, 0xa8, 0x26, 0x4a, 0x26, + 0xa2, 0x41, 0x19, 0x00, 0xc7, 0x05, 0x42, 0x30, 0x21, 0x03, 0xa4, 0x41, + 0x0f, 0x00, 0x55, 0x05, 0x84, 0x30, 0xe9, 0x0b, 0xc6, 0x05, 0x42, 0x00, + 0x80, 0x68, 0xa2, 0x90, 0x20, 0x00, 0x63, 0x00, 0x80, 0x68, 0x54, 0xcf, + 0x1f, 0xee, 0x00, 0x0c, 0xdd, 0x4f, 0xa2, 0x41, 0x03, 0x80, 0x3d, 0x22, + 0x40, 0xd0, 0x42, 0x30, 0x15, 0x8a, 0xe2, 0x45, 0x04, 0x0e, 0x50, 0x60, + 0x03, 0x00, 0x85, 0xed, 0x6c, 0xc8, 0x50, 0x60, 0x00, 0x10, 0x88, 0xed, + 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, 0x0f, 0xc8, + 0x1c, 0x8d, 0x68, 0xc8, 0x5c, 0xfc, 0x48, 0x81, 0x83, 0xef, 0x18, 0xef, + 0x46, 0xc8, 0x01, 0xed, 0x45, 0xc8, 0x11, 0x6d, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0xa0, 0x0c, 0x42, 0x30, 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, + 0x08, 0x10, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, + 0x9c, 0xfc, 0x48, 0x81, 0x3d, 0x22, 0x40, 0x50, 0x12, 0x47, 0x5c, 0xfc, + 0x48, 0x81, 0x83, 0xef, 0x18, 0xef, 0x46, 0xc8, 0x01, 0xed, 0x45, 0xc8, + 0x19, 0x6d, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xa0, 0x0c, 0x42, 0x30, + 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x08, 0x0a, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0x3d, 0x22, + 0x40, 0x50, 0x12, 0x47, 0xe5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0xdd, 0x22, + 0x1c, 0xd0, 0x04, 0x16, 0x3d, 0x00, 0x5d, 0x16, 0x48, 0x00, 0x93, 0x4a, + 0x34, 0x4a, 0x42, 0xfc, 0x1c, 0xaf, 0x10, 0x02, 0x00, 0xc8, 0x44, 0xca, + 0x85, 0xca, 0xa4, 0x0e, 0x67, 0x0e, 0xc2, 0x45, 0x10, 0x02, 0x80, 0xc8, + 0xf1, 0x40, 0x2f, 0x00, 0x11, 0x69, 0x2b, 0x2d, 0x62, 0x90, 0x20, 0x00, + 0xe3, 0x40, 0x24, 0x00, 0x74, 0x14, 0x00, 0x00, 0x43, 0x00, 0x50, 0x23, + 0xe4, 0x40, 0x05, 0x00, 0x14, 0x0a, 0x3b, 0x2d, 0x82, 0x00, 0x0c, 0x28, + 0x14, 0x8a, 0x52, 0xb2, 0x04, 0x00, 0xf2, 0x40, 0x0a, 0x00, 0xf3, 0x40, + 0x08, 0x00, 0x95, 0x14, 0x3c, 0x00, 0x94, 0x09, 0x45, 0x05, 0x2b, 0x2d, + 0x62, 0x00, 0x0c, 0x28, 0x94, 0x89, 0x02, 0x02, 0x50, 0x13, 0xe2, 0x40, + 0x04, 0x00, 0x14, 0x09, 0x50, 0x00, 0x0c, 0x28, 0x14, 0x89, 0xdd, 0x22, + 0x1c, 0x50, 0x0e, 0x47, 0x94, 0x09, 0x62, 0x00, 0x0c, 0x28, 0xe3, 0xcf, + 0x94, 0x89, 0x52, 0xb2, 0x04, 0x00, 0x12, 0x94, 0x04, 0x00, 0x54, 0x14, + 0x00, 0x00, 0xb3, 0x40, 0x09, 0x00, 0x42, 0x00, 0x3c, 0x2b, 0x02, 0x02, + 0x50, 0x13, 0xe2, 0x40, 0xea, 0xff, 0xe9, 0xcf, 0x14, 0x1a, 0x00, 0x00, + 0x75, 0x14, 0x3c, 0x00, 0x35, 0x05, 0x2d, 0x2d, 0xf2, 0xcf, 0x54, 0x18, + 0x00, 0x00, 0x00, 0x0c, 0xf1, 0x4f, 0x5c, 0xfc, 0x48, 0x81, 0xe7, 0xcb, + 0x80, 0x30, 0x64, 0x05, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xe0, 0x0c, + 0x01, 0xef, 0x42, 0x30, 0x37, 0x11, 0xe2, 0x45, 0x81, 0xee, 0x9c, 0xfc, + 0x48, 0x81, 0xe7, 0x4b, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, 0x1f, 0x17, + 0x99, 0x45, 0x11, 0x4c, 0xe9, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0x77, 0x45, + 0x05, 0x0e, 0x3d, 0x32, 0x16, 0x00, 0x42, 0x30, 0x8b, 0x17, 0x44, 0x0e, + 0x98, 0x86, 0xe2, 0x45, 0x66, 0x0e, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xe8, 0x02, 0xa4, 0x69, 0x63, 0x02, 0x50, 0x1b, 0xa3, 0x40, 0x7e, 0x00, + 0x10, 0xb2, 0x0f, 0x00, 0x10, 0xb2, 0x01, 0x00, 0x12, 0x02, 0x50, 0x81, + 0x70, 0x1c, 0x22, 0x00, 0x83, 0x00, 0xac, 0x38, 0x52, 0x14, 0x0f, 0x00, + 0x7d, 0x14, 0x16, 0x00, 0x03, 0xb4, 0x65, 0x00, 0x25, 0x25, 0xf2, 0x14, + 0x10, 0x00, 0x72, 0x14, 0x11, 0x00, 0xf5, 0x27, 0xb5, 0x25, 0x44, 0x05, + 0x2d, 0x2d, 0xce, 0x07, 0xc6, 0x05, 0xfd, 0x2f, 0xbd, 0x2d, 0x5c, 0x18, + 0x98, 0x81, 0x5c, 0x18, 0x99, 0x81, 0x5c, 0x18, 0x9a, 0x81, 0x5c, 0x18, + 0x9b, 0x81, 0x92, 0x30, 0x2a, 0x00, 0x89, 0x6e, 0x40, 0x09, 0xc2, 0x00, + 0x00, 0xe0, 0x42, 0x00, 0x3c, 0x2b, 0xc6, 0x00, 0x80, 0xe0, 0x42, 0x00, + 0x80, 0x20, 0x50, 0x8b, 0x51, 0x89, 0xa4, 0x4c, 0xb1, 0xb4, 0xf2, 0xff, + 0x40, 0x6e, 0x3d, 0x1d, 0x15, 0x00, 0x1d, 0x1d, 0x14, 0x00, 0xdd, 0x1c, + 0x13, 0x00, 0xbd, 0x1c, 0x12, 0x00, 0x9d, 0x1c, 0x11, 0x00, 0x5d, 0x1c, + 0x10, 0x00, 0xe9, 0x00, 0x50, 0x49, 0xe8, 0x00, 0x50, 0x41, 0x7c, 0x07, + 0xfa, 0x06, 0x78, 0x06, 0x74, 0x05, 0x23, 0x01, 0x50, 0x7b, 0x03, 0x01, + 0x50, 0x73, 0xc3, 0x00, 0x50, 0x6b, 0xa3, 0x00, 0x50, 0x63, 0x83, 0x00, + 0x50, 0x5b, 0x43, 0x00, 0x50, 0x53, 0xe3, 0x01, 0x18, 0x48, 0xc3, 0x01, + 0x18, 0x40, 0xa3, 0x01, 0x18, 0x30, 0x83, 0x01, 0x18, 0x28, 0x63, 0x01, + 0x18, 0x20, 0x43, 0x01, 0x18, 0x10, 0x7c, 0x18, 0x90, 0x81, 0x3c, 0x19, + 0x91, 0x81, 0x1c, 0x19, 0x92, 0x81, 0xdc, 0x18, 0x93, 0x81, 0xbc, 0x18, + 0x94, 0x81, 0x9c, 0x18, 0x95, 0x81, 0x5c, 0x18, 0x96, 0x81, 0xfc, 0x18, + 0x97, 0x81, 0x37, 0x45, 0x0c, 0x47, 0x72, 0x00, 0x50, 0x19, 0xe3, 0x14, + 0x11, 0x00, 0x63, 0x14, 0x14, 0x00, 0xf5, 0x27, 0x9a, 0xcf, 0xb5, 0x25, + 0x25, 0x6b, 0x66, 0x02, 0x50, 0x9b, 0x13, 0xb4, 0x87, 0xff, 0x80, 0x0c, + 0x50, 0xb0, 0x0f, 0x00, 0x42, 0xb0, 0x01, 0x00, 0x52, 0x00, 0x50, 0x11, + 0x62, 0x1c, 0x24, 0x00, 0x7d, 0xcf, 0x83, 0x00, 0xac, 0x38, 0x00, 0x0c, + 0xf5, 0x4f, 0x44, 0x45, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xa5, 0x4c, + 0xc2, 0x45, 0x1d, 0xfe, 0x34, 0x00, 0x50, 0x14, 0x89, 0x00, 0x90, 0x14, + 0x88, 0x00, 0xb9, 0x41, 0x03, 0x80, 0x20, 0x25, 0xe2, 0x44, 0x39, 0x33, + 0x65, 0xab, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0xbf, 0x45, 0x00, 0x0c, + 0xa3, 0x41, 0x00, 0xa5, 0xc3, 0xfc, 0x00, 0x10, 0x43, 0x30, 0xe0, 0x13, + 0x61, 0x27, 0x40, 0xeb, 0x83, 0x30, 0x00, 0x14, 0xa0, 0x69, 0x22, 0x6d, + 0xb1, 0x25, 0xd0, 0xe9, 0x82, 0xb4, 0xfa, 0xff, 0xd2, 0x6e, 0xbf, 0x45, + 0xa3, 0x41, 0x00, 0xa5, 0x40, 0x26, 0x83, 0xf8, 0x00, 0x10, 0x43, 0x30, + 0xe0, 0x13, 0x83, 0x30, 0x00, 0x14, 0xd0, 0x69, 0xd2, 0x6e, 0xb0, 0x25, + 0xa0, 0xe9, 0x22, 0x6d, 0x82, 0xb4, 0xf9, 0xff, 0xb9, 0x41, 0x03, 0x80, + 0x39, 0x33, 0x49, 0xa7, 0x99, 0x45, 0xa4, 0x41, 0x80, 0x00, 0x00, 0x0c, + 0xa3, 0x41, 0x00, 0xa5, 0x43, 0xfc, 0x00, 0x10, 0xb9, 0x41, 0x03, 0x80, + 0x80, 0x0c, 0x40, 0x00, 0x0c, 0x50, 0x42, 0x50, 0x00, 0x03, 0x39, 0x33, + 0x49, 0xa7, 0x43, 0xf8, 0x00, 0x10, 0xb9, 0x45, 0xa3, 0x41, 0x00, 0xa5, + 0x43, 0xfc, 0x00, 0x10, 0x40, 0x00, 0x0c, 0x38, 0x42, 0x50, 0x00, 0x30, + 0x43, 0xf8, 0x00, 0x10, 0xbf, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x00, 0xa5, + 0x84, 0x00, 0x00, 0xe8, 0xd0, 0x26, 0x82, 0xf8, 0x20, 0x11, 0xa2, 0xf8, + 0x24, 0x11, 0xbf, 0x45, 0x85, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0xfc, + 0xe0, 0x0d, 0x88, 0xed, 0x7d, 0x18, 0x96, 0x00, 0x86, 0xed, 0x7d, 0x18, + 0x98, 0x00, 0x1d, 0x18, 0x94, 0x00, 0x1d, 0x18, 0x95, 0x00, 0x1d, 0x18, + 0x97, 0x00, 0x2c, 0x0b, 0x3d, 0x23, 0xd0, 0xd0, 0x50, 0x09, 0x66, 0xb0, + 0x0f, 0x00, 0xc5, 0x0f, 0x63, 0x70, 0x01, 0x00, 0x81, 0xee, 0xe2, 0xb0, + 0x71, 0x00, 0x04, 0x0e, 0x1d, 0xf8, 0x8c, 0x00, 0x7d, 0xf8, 0x88, 0x00, + 0xdd, 0x18, 0x90, 0x00, 0xbd, 0x18, 0x91, 0x00, 0xbd, 0x18, 0x92, 0x00, + 0x07, 0x94, 0xc9, 0x00, 0xbd, 0x18, 0x93, 0x00, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0x30, 0xfc, 0x6c, 0x43, 0x00, 0x18, 0x11, 0xa2, 0x45, 0xa2, 0x41, + 0x03, 0x80, 0x80, 0x0c, 0x42, 0x30, 0x51, 0x97, 0xc2, 0x45, 0xb1, 0x41, + 0x01, 0xa5, 0x31, 0x52, 0xdc, 0xa8, 0x1d, 0x18, 0xb4, 0x00, 0x31, 0xfd, + 0x00, 0x00, 0x91, 0x69, 0x12, 0x69, 0xb2, 0x41, 0x09, 0x80, 0x52, 0x32, + 0xc0, 0xae, 0x42, 0x00, 0x40, 0xa8, 0x5d, 0x38, 0x26, 0x00, 0x5d, 0x14, + 0x98, 0x00, 0x40, 0x31, 0x00, 0x10, 0x9d, 0x20, 0x88, 0x10, 0x72, 0xfd, + 0x50, 0x00, 0xdd, 0x20, 0x90, 0x10, 0x63, 0x00, 0x40, 0xa8, 0x29, 0x01, + 0x40, 0xa8, 0x5d, 0x39, 0xb0, 0x00, 0x5d, 0x39, 0xb2, 0x00, 0x40, 0x31, + 0x02, 0x00, 0x7d, 0x38, 0x24, 0x00, 0x5d, 0x18, 0x10, 0x00, 0x3d, 0x39, + 0x22, 0x00, 0x1d, 0x18, 0xb6, 0x00, 0xcb, 0x45, 0x5d, 0x19, 0xb5, 0x00, + 0x51, 0xfc, 0x4c, 0x63, 0x71, 0xfc, 0x50, 0x63, 0x9e, 0x1c, 0x02, 0x00, + 0x21, 0x25, 0x42, 0x00, 0x3c, 0x2b, 0x63, 0x00, 0x2c, 0x3a, 0x29, 0x05, + 0xb0, 0x6d, 0x62, 0x00, 0x3c, 0xab, 0x03, 0x00, 0x3c, 0x70, 0x9d, 0x18, + 0x98, 0x00, 0x42, 0x46, 0x42, 0x00, 0x3c, 0x2b, 0x02, 0x40, 0x4b, 0x03, + 0xa2, 0x0c, 0x52, 0xfc, 0x3c, 0x00, 0x9d, 0xfc, 0x88, 0x00, 0xc2, 0x45, + 0xa5, 0x00, 0x3c, 0x2b, 0x3d, 0xfe, 0xac, 0x00, 0x2f, 0x6d, 0x44, 0xc8, + 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x99, 0x66, 0x00, 0x85, 0xa0, 0x30, + 0x80, 0x7e, 0xe2, 0x45, 0x91, 0x0c, 0x5a, 0x48, 0x22, 0x96, 0x0f, 0x00, + 0x7d, 0x34, 0xb2, 0x00, 0x8c, 0x8d, 0xbe, 0x6d, 0xbf, 0x2d, 0xb0, 0x6d, + 0xb4, 0x25, 0x91, 0x0c, 0xb4, 0x05, 0xc0, 0x6a, 0xa0, 0xea, 0x22, 0x6d, + 0x62, 0xb4, 0xfb, 0xff, 0x42, 0x6e, 0x5d, 0x14, 0xb6, 0x00, 0x02, 0x94, + 0x7e, 0x02, 0x01, 0xed, 0x5d, 0x18, 0xa2, 0x00, 0x5d, 0x18, 0xa3, 0x00, + 0x5d, 0x18, 0xa4, 0x00, 0x5d, 0x18, 0xa6, 0x00, 0x5d, 0x18, 0xa7, 0x00, + 0x5d, 0x18, 0xa8, 0x00, 0x01, 0xed, 0x5d, 0xf8, 0x9c, 0x00, 0x02, 0xed, + 0x1d, 0x18, 0xa5, 0x00, 0x1d, 0x18, 0xa9, 0x00, 0x1d, 0x18, 0xaa, 0x00, + 0x5d, 0x18, 0xa1, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0xf5, 0xb1, + 0xe2, 0x45, 0x4f, 0x6e, 0xa4, 0x41, 0x01, 0xa5, 0x44, 0xfc, 0x10, 0x3d, + 0xa3, 0x41, 0xff, 0x3f, 0x63, 0x50, 0x00, 0xff, 0x93, 0x44, 0xa3, 0x41, + 0x00, 0x40, 0xd3, 0x44, 0x44, 0xf8, 0x10, 0x3d, 0xa2, 0x41, 0x03, 0x80, + 0x42, 0x30, 0x49, 0xac, 0x57, 0x6f, 0x8f, 0x6e, 0xe2, 0x45, 0x45, 0x6e, + 0x5d, 0x14, 0xb4, 0x00, 0x10, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0xad, 0x64, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x0d, 0x96, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, + 0x08, 0x80, 0xbe, 0x0c, 0x42, 0x30, 0x31, 0x17, 0xe2, 0x45, 0x90, 0x0c, + 0x3d, 0x23, 0xd0, 0x50, 0x9f, 0x45, 0x7d, 0x4c, 0xa4, 0x41, 0x01, 0xa5, + 0x44, 0xfc, 0x10, 0x3d, 0xa3, 0x41, 0xff, 0x3f, 0x63, 0x50, 0x00, 0xff, + 0x93, 0x44, 0x44, 0xf8, 0x10, 0x3d, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xad, 0x64, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0x9d, 0xac, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0x0d, 0x96, 0xe2, 0x45, 0x00, 0x0c, 0xd9, 0xcf, 0xa2, 0x41, 0x08, 0x80, + 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0x51, 0x97, 0xe2, 0x45, 0x80, 0x0c, + 0x5e, 0x14, 0x02, 0x00, 0x9e, 0x14, 0x01, 0x00, 0x7e, 0x14, 0x04, 0x00, + 0x20, 0x25, 0xd4, 0x44, 0xde, 0x14, 0x03, 0x00, 0xbe, 0x14, 0x00, 0x00, + 0x7d, 0x18, 0x96, 0x00, 0x5d, 0x38, 0xa0, 0x00, 0xa3, 0x41, 0x00, 0xb0, + 0x40, 0x30, 0x00, 0x02, 0x01, 0xee, 0x63, 0x30, 0x00, 0x60, 0x5d, 0x38, + 0xa2, 0x00, 0x02, 0xed, 0xdd, 0x18, 0x97, 0x00, 0x9d, 0x18, 0xa4, 0x00, + 0x7d, 0xf8, 0x9c, 0x00, 0x05, 0x94, 0x6b, 0x02, 0x5d, 0x18, 0xa5, 0x00, + 0x9d, 0x18, 0xa6, 0x00, 0xb1, 0x41, 0x09, 0x80, 0x31, 0x32, 0xc0, 0xae, + 0x51, 0xfc, 0x4c, 0x00, 0xe2, 0x45, 0x45, 0x6e, 0x5e, 0x14, 0x00, 0x00, + 0x62, 0xb0, 0x02, 0x00, 0x03, 0xb4, 0x78, 0x02, 0x82, 0xed, 0x62, 0xb4, + 0x39, 0x02, 0x5d, 0x32, 0x9c, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x21, 0x65, 0x92, 0x0c, 0xc2, 0x45, 0x1d, 0x38, 0xa2, 0x00, 0x5e, 0x14, + 0x00, 0x00, 0x42, 0xb0, 0x02, 0x00, 0x02, 0x94, 0x29, 0x02, 0x9d, 0x14, + 0x88, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x09, 0x12, 0xe2, 0x45, + 0x81, 0xee, 0x00, 0x94, 0x21, 0x02, 0xa2, 0x41, 0x03, 0x80, 0x5e, 0x14, + 0x03, 0x00, 0x02, 0x94, 0x04, 0x02, 0xa4, 0x41, 0x01, 0xa5, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x51, 0x97, 0xe2, 0x45, 0x80, 0x0c, 0xb1, 0x41, + 0x00, 0xb7, 0x2f, 0x6d, 0x31, 0x32, 0xd0, 0x54, 0x44, 0xc8, 0xa2, 0x41, + 0x01, 0x80, 0x00, 0x85, 0x91, 0x0c, 0xa0, 0x30, 0x80, 0x7e, 0x42, 0x30, + 0x99, 0x66, 0xc2, 0x45, 0x3d, 0xfa, 0xac, 0x00, 0x40, 0x30, 0x00, 0x10, + 0x5d, 0x38, 0xb0, 0x00, 0x40, 0x30, 0x00, 0x08, 0x5d, 0x38, 0xb2, 0x00, + 0xa2, 0x41, 0x03, 0x80, 0x80, 0x0c, 0x42, 0x30, 0xed, 0xb4, 0xc2, 0x45, + 0x1d, 0x18, 0xb4, 0x00, 0x5e, 0x1c, 0x01, 0x00, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0xc8, 0x36, 0x42, 0x00, 0x00, 0xd0, 0x9e, 0x14, 0x02, 0x00, + 0x62, 0x00, 0x3c, 0xab, 0x03, 0x00, 0x3c, 0x70, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0x64, 0x35, 0xc2, 0x60, 0x41, 0x00, 0xa2, 0x60, 0x45, 0x00, + 0x62, 0x60, 0x49, 0x00, 0xc2, 0x60, 0x3e, 0x10, 0xa2, 0x60, 0x42, 0x10, + 0x62, 0x60, 0x46, 0x10, 0x42, 0x35, 0x4a, 0x00, 0x40, 0x30, 0xff, 0x00, + 0x5d, 0x38, 0x18, 0x00, 0x5d, 0x38, 0x1a, 0x00, 0xb1, 0x41, 0x01, 0xa5, + 0x31, 0x52, 0xdc, 0xa8, 0x9d, 0x18, 0x98, 0x00, 0xb2, 0x41, 0x09, 0x80, + 0x01, 0xee, 0x52, 0x32, 0xc0, 0xae, 0x9d, 0x18, 0xb6, 0x00, 0x1d, 0x18, + 0xb5, 0x00, 0x45, 0x6e, 0x42, 0x46, 0x47, 0xc8, 0x31, 0xfd, 0x00, 0x00, + 0x91, 0x6b, 0x12, 0x69, 0x29, 0x01, 0x40, 0xa8, 0xe7, 0x00, 0x40, 0xa8, + 0x42, 0x00, 0x40, 0xa8, 0xb4, 0xc8, 0x75, 0xc8, 0x3d, 0x39, 0x22, 0x00, + 0xfd, 0x38, 0x24, 0x00, 0xd3, 0xc8, 0x5d, 0x39, 0x58, 0x00, 0x5d, 0x38, + 0x26, 0x00, 0x52, 0xfc, 0x50, 0x00, 0xe2, 0x45, 0x00, 0x0c, 0x91, 0xfc, + 0x4c, 0x63, 0x71, 0xfc, 0x50, 0x63, 0x5d, 0x1c, 0x98, 0x00, 0x41, 0x26, + 0x84, 0x00, 0x3c, 0x2b, 0x63, 0x00, 0x2c, 0x3a, 0x45, 0x05, 0xb0, 0x6d, + 0x62, 0x00, 0x3c, 0xab, 0x03, 0x00, 0x3c, 0x70, 0x42, 0x46, 0x42, 0x00, + 0x3c, 0x2b, 0x02, 0x40, 0xe8, 0x01, 0xa2, 0x0c, 0x52, 0xfc, 0x3c, 0x00, + 0x9d, 0xfc, 0x88, 0x00, 0xc2, 0x45, 0xa5, 0x00, 0x3c, 0x2b, 0x9d, 0x3c, + 0x18, 0x00, 0x7d, 0x3c, 0x1a, 0x00, 0x5d, 0x34, 0xb2, 0x00, 0x84, 0x00, + 0x00, 0x60, 0xe3, 0x44, 0x0d, 0x8d, 0x84, 0x00, 0x2c, 0xb8, 0xae, 0x6d, + 0xbf, 0x2d, 0x5a, 0x48, 0xb0, 0x6d, 0xb4, 0x25, 0xb4, 0x05, 0x20, 0xea, + 0x22, 0x6d, 0x62, 0xb4, 0xfc, 0xff, 0x00, 0x0c, 0xa4, 0x41, 0x01, 0xa5, + 0x44, 0xfc, 0x10, 0x3d, 0xa3, 0x41, 0xff, 0x3f, 0x63, 0x50, 0x00, 0xff, + 0x93, 0x44, 0xa3, 0x41, 0x00, 0x40, 0xd3, 0x44, 0x44, 0xf8, 0x10, 0x3d, + 0xa2, 0x41, 0x03, 0x80, 0x57, 0x6f, 0x8f, 0x6e, 0x42, 0x30, 0x49, 0xac, + 0xe2, 0x45, 0x45, 0x6e, 0xb4, 0xce, 0xa2, 0x41, 0x08, 0x80, 0x5e, 0x14, + 0x01, 0x00, 0x02, 0x94, 0x5e, 0x01, 0xa3, 0x41, 0x01, 0xa5, 0xa2, 0x41, + 0x01, 0xa5, 0x42, 0x50, 0x04, 0xa8, 0xa0, 0x69, 0x80, 0x30, 0x00, 0xdf, + 0x9c, 0x44, 0xa0, 0xe9, 0xa2, 0xce, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x29, 0x43, 0xc2, 0x45, 0xb2, 0x41, 0x08, 0x80, + 0x9d, 0x14, 0x88, 0x00, 0x52, 0x32, 0x09, 0x12, 0xf2, 0x45, 0xa0, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0xde, 0x14, 0x02, 0x00, 0xbe, 0x14, 0x01, 0x00, + 0x9d, 0xfc, 0x88, 0x00, 0x42, 0xfc, 0x00, 0xaf, 0xc2, 0x45, 0xb1, 0x41, + 0x00, 0xa5, 0xa2, 0x41, 0x00, 0xc0, 0x71, 0xfe, 0xf8, 0x3c, 0x62, 0x30, + 0x00, 0x01, 0x51, 0xf8, 0xf8, 0x3c, 0xa2, 0x41, 0x08, 0x80, 0x71, 0xf8, + 0xf8, 0x3c, 0x42, 0x30, 0xad, 0x13, 0xc2, 0x45, 0x80, 0x30, 0xe8, 0x03, + 0x71, 0xfc, 0xa0, 0x3c, 0x9d, 0x14, 0x88, 0x00, 0x53, 0x0c, 0x40, 0x00, + 0x0c, 0x38, 0x63, 0x00, 0x2c, 0x15, 0x7e, 0x18, 0x03, 0x00, 0x81, 0xee, + 0x11, 0xf8, 0xf8, 0x3c, 0x51, 0xf8, 0xf8, 0x3c, 0xf2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x11, 0x43, 0xe2, 0x45, 0x00, 0x0c, + 0x5c, 0xce, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x19, 0x67, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xef, 0x10, 0xe2, 0x45, 0x5d, 0x6e, 0x7d, 0xfc, 0xb8, 0x00, 0x7e, 0x60, + 0x04, 0x80, 0x7e, 0x60, 0x01, 0x90, 0x5e, 0x60, 0x08, 0x80, 0x43, 0xce, + 0x5e, 0x60, 0x05, 0x90, 0x7e, 0x14, 0x01, 0x00, 0xa2, 0x41, 0x00, 0xa4, + 0x42, 0x50, 0x24, 0x93, 0xa0, 0xe9, 0x3b, 0xce, 0xa2, 0x41, 0x08, 0x80, + 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0x51, 0x97, 0xe2, 0x45, 0x80, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0xaf, 0x6e, 0x42, 0x30, 0xc1, 0x5b, 0xe2, 0x45, + 0x57, 0x6e, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x15, 0x5c, 0xc2, 0x45, + 0x5d, 0x32, 0x9c, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x35, 0x5c, + 0xc2, 0x45, 0x00, 0x00, 0x90, 0xba, 0xa2, 0x41, 0x04, 0x80, 0xa0, 0x0c, + 0x42, 0x30, 0x4d, 0x5c, 0xe2, 0x45, 0x05, 0xee, 0x0d, 0x6d, 0x9c, 0xfc, + 0x8c, 0x81, 0x44, 0xc8, 0x08, 0xed, 0x5d, 0x18, 0x96, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0xc0, 0x0c, 0xe0, 0x0c, 0xa0, 0x30, 0x00, 0x08, 0x42, 0x30, + 0x6b, 0x10, 0xc2, 0x45, 0x1d, 0x18, 0x97, 0x00, 0xa6, 0x41, 0x08, 0x80, + 0xc6, 0x30, 0x09, 0x12, 0xe6, 0x0c, 0x9d, 0x14, 0x88, 0x00, 0xc9, 0x48, + 0x81, 0xed, 0x40, 0x30, 0x00, 0x02, 0xa0, 0x0c, 0xdd, 0xf8, 0x9c, 0x00, + 0x5d, 0x38, 0xa0, 0x00, 0x5d, 0x38, 0xa2, 0x00, 0x7d, 0x18, 0xa4, 0x00, + 0x7d, 0x18, 0xa6, 0x00, 0xfd, 0xf8, 0xcc, 0x00, 0xc7, 0x45, 0x1d, 0x18, + 0xa5, 0x00, 0xdd, 0xfc, 0x88, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xb2, 0x0c, + 0x42, 0x30, 0xe1, 0x68, 0xe2, 0x45, 0x45, 0x6e, 0x2e, 0x8d, 0xb6, 0x41, + 0x04, 0x80, 0x9d, 0x14, 0x88, 0x00, 0x5d, 0xfc, 0xcc, 0x00, 0xe2, 0x45, + 0x81, 0xee, 0x9d, 0xfc, 0xac, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xaf, 0x6e, + 0x42, 0x30, 0xe5, 0x5b, 0xc2, 0x45, 0xfe, 0x1a, 0x01, 0x00, 0x00, 0x94, + 0xcc, 0xfd, 0xa2, 0x41, 0x08, 0x80, 0x1d, 0xf8, 0x9c, 0x00, 0x1d, 0x18, + 0xa1, 0x00, 0x5d, 0x18, 0xa2, 0x00, 0x5d, 0x18, 0xa3, 0x00, 0x5d, 0x18, + 0xa4, 0x00, 0x5d, 0x18, 0xa5, 0x00, 0x5d, 0x18, 0xa6, 0x00, 0x5d, 0x18, + 0xa7, 0x00, 0x5d, 0x18, 0xa8, 0x00, 0x5d, 0x18, 0xa9, 0x00, 0x00, 0x94, + 0x85, 0xfd, 0x1d, 0x18, 0xaa, 0x00, 0x02, 0xed, 0xb3, 0x41, 0x08, 0x80, + 0x5d, 0xf8, 0xc8, 0x00, 0x56, 0x30, 0x8d, 0x67, 0xa0, 0x32, 0x08, 0x00, + 0x80, 0x32, 0x0f, 0x00, 0xe0, 0x32, 0x04, 0x00, 0x73, 0x32, 0xfd, 0x11, + 0x1d, 0xf8, 0xc4, 0x00, 0x5d, 0xf8, 0xc0, 0x00, 0x20, 0x32, 0xff, 0x00, + 0x0b, 0xcc, 0xc0, 0x0e, 0xcd, 0x2c, 0xfd, 0xfa, 0xc4, 0x00, 0xc2, 0x4e, + 0xd4, 0x02, 0x90, 0x13, 0x02, 0xb4, 0x53, 0x00, 0xb7, 0x02, 0x50, 0xb9, + 0xd3, 0x45, 0x97, 0xd0, 0xff, 0x00, 0x5d, 0xfc, 0xc0, 0x00, 0xe2, 0x45, + 0x92, 0x0c, 0x82, 0x30, 0x80, 0xff, 0xe4, 0x00, 0x80, 0xf8, 0x87, 0x00, + 0x10, 0x1b, 0xf7, 0x05, 0x71, 0x00, 0x50, 0x1b, 0xa3, 0x40, 0xe7, 0xff, + 0x44, 0x40, 0xe2, 0xff, 0x60, 0x30, 0x80, 0xff, 0x27, 0x05, 0xad, 0x2c, + 0xe0, 0xcf, 0xfd, 0xfa, 0xc4, 0x00, 0x44, 0xfc, 0x10, 0x3d, 0xa3, 0x41, + 0xff, 0x3f, 0x63, 0x50, 0x00, 0xff, 0x93, 0x44, 0x44, 0xf8, 0x10, 0x3d, + 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0x9d, 0xac, 0xe2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0xed, 0xb4, 0xe2, 0x45, 0x50, 0xee, + 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0x0d, 0x96, 0xe2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x08, 0x80, 0xbe, 0x0c, 0x42, 0x30, 0x31, 0x17, 0xe2, 0x45, + 0x90, 0x0c, 0x3d, 0x23, 0xd0, 0x50, 0x9f, 0x45, 0x7d, 0x4c, 0x63, 0x50, + 0x04, 0xa8, 0x30, 0x69, 0x40, 0x00, 0x0c, 0x38, 0x42, 0x50, 0x00, 0x20, + 0x30, 0xe9, 0x00, 0x94, 0x46, 0xfd, 0xa2, 0x41, 0x08, 0x80, 0x00, 0x94, + 0x97, 0xfd, 0x1d, 0x18, 0xa6, 0x00, 0x5d, 0xfc, 0xc8, 0x00, 0x7d, 0xfc, + 0xc4, 0x00, 0x80, 0x32, 0x08, 0x00, 0x2e, 0x6d, 0xa0, 0x32, 0x01, 0x00, + 0xe3, 0x32, 0xfc, 0xff, 0x02, 0xb4, 0x94, 0xff, 0x5d, 0xf8, 0xc8, 0x00, + 0x5d, 0xfc, 0xc4, 0x00, 0xe2, 0xd2, 0xff, 0x00, 0xf3, 0x45, 0x97, 0x0c, + 0x4e, 0xcf, 0x9d, 0x14, 0x88, 0x00, 0x00, 0x94, 0xb4, 0xfc, 0xa0, 0x0c, + 0x9d, 0x14, 0x88, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x09, 0x12, + 0xe2, 0x45, 0xa0, 0x0c, 0xdd, 0x14, 0x96, 0x00, 0xbd, 0x14, 0x97, 0x00, + 0x51, 0xfc, 0x40, 0x00, 0x9d, 0xfc, 0x88, 0x00, 0xc2, 0x45, 0x5d, 0x32, + 0x9c, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0xf9, 0xab, 0xe2, 0x45, + 0x92, 0x0c, 0x5e, 0x14, 0x00, 0x00, 0x82, 0xed, 0x62, 0xb4, 0x79, 0xfd, + 0x00, 0x0c, 0x00, 0x94, 0x6e, 0xfd, 0xa2, 0x41, 0x04, 0x80, 0x18, 0xce, + 0xa0, 0x0c, 0x00, 0x0c, 0x59, 0x06, 0x60, 0x6f, 0xc4, 0x00, 0x3c, 0xab, + 0x06, 0x00, 0x3c, 0x70, 0x44, 0x46, 0x84, 0x00, 0x3c, 0x2b, 0x04, 0x40, + 0x04, 0x00, 0x44, 0x0c, 0x9f, 0x45, 0x42, 0x00, 0x3c, 0x2b, 0x40, 0x0c, + 0x9f, 0x45, 0x42, 0x00, 0x3c, 0x2b, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x2d, 0x44, 0x44, 0x45, 0xe2, 0x45, 0x04, 0x0e, + 0xa4, 0x25, 0x26, 0x05, 0x02, 0x02, 0x10, 0x12, 0x04, 0x45, 0x42, 0x00, + 0x80, 0x20, 0x06, 0x47, 0xa3, 0x41, 0x02, 0xa5, 0x43, 0xfc, 0x28, 0x0c, + 0x21, 0x25, 0x40, 0x89, 0x43, 0xfc, 0x2c, 0x0c, 0x21, 0x25, 0x9f, 0x45, + 0x50, 0x89, 0x00, 0x0c, 0xed, 0x4f, 0x01, 0xed, 0x44, 0xc8, 0x5d, 0x18, + 0x16, 0x00, 0x5d, 0x18, 0x18, 0x00, 0x5d, 0x18, 0x1a, 0x00, 0xa2, 0x41, + 0x03, 0x80, 0x82, 0xed, 0xe9, 0xcb, 0x09, 0x6e, 0x42, 0x30, 0xf5, 0xb1, + 0x1d, 0x18, 0x14, 0x00, 0x7d, 0x18, 0x15, 0x00, 0x1d, 0x18, 0x17, 0x00, + 0x1d, 0x18, 0x19, 0x00, 0x1d, 0x18, 0x1b, 0x00, 0x1d, 0x18, 0x1c, 0x00, + 0x1d, 0x18, 0x1d, 0x00, 0xc2, 0x45, 0x1d, 0x18, 0x1e, 0x00, 0xe9, 0x4b, + 0x0a, 0x47, 0x00, 0x0c, 0xa3, 0x41, 0x01, 0xa5, 0x63, 0x50, 0x04, 0xa8, + 0x30, 0x69, 0x40, 0x00, 0x0c, 0x38, 0x42, 0x50, 0x00, 0x20, 0x30, 0xe9, + 0xbf, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x01, 0xa5, 0x42, 0x50, 0x04, 0xa8, + 0xa0, 0x69, 0x80, 0x30, 0x00, 0xdf, 0x9c, 0x44, 0xa0, 0xe9, 0xbf, 0x45, + 0xed, 0x4f, 0x48, 0x45, 0xc4, 0x60, 0x03, 0x00, 0xc7, 0x09, 0x24, 0x15, + 0x06, 0x00, 0xc5, 0x0a, 0x44, 0x15, 0x04, 0x00, 0x44, 0x0c, 0x04, 0x15, + 0x08, 0x00, 0xc2, 0x60, 0x00, 0x10, 0xa9, 0x0b, 0x30, 0x25, 0x22, 0x01, + 0x90, 0x12, 0xd0, 0x26, 0x4a, 0x0a, 0x45, 0x01, 0x90, 0x1a, 0xb0, 0x41, + 0x00, 0xa5, 0x5d, 0x38, 0x14, 0x00, 0x40, 0x30, 0x00, 0x03, 0xc4, 0xc8, + 0x7d, 0x38, 0x16, 0x00, 0x1d, 0x19, 0x18, 0x00, 0xe7, 0xc8, 0x50, 0xf8, + 0x04, 0x34, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0xad, 0xaa, 0xe2, 0x45, + 0x00, 0x0c, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0xb9, 0x97, 0xe2, 0x45, + 0x00, 0x0c, 0xa2, 0x41, 0x00, 0x80, 0x50, 0xf8, 0x28, 0x10, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x11, 0x43, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0xc1, 0x94, 0xe2, 0x45, 0x00, 0x0c, 0x50, 0xfc, + 0xac, 0x38, 0x42, 0x00, 0x2c, 0x02, 0x08, 0xad, 0xa3, 0x41, 0x00, 0xa5, + 0x43, 0xfc, 0xac, 0x38, 0x42, 0xd0, 0x00, 0x01, 0xe2, 0x40, 0xfa, 0xff, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x17, 0x13, 0xe2, 0x45, 0x09, 0x6e, + 0xa2, 0x41, 0x00, 0xa5, 0x02, 0xf8, 0x04, 0x34, 0xa2, 0x41, 0x03, 0x80, + 0x42, 0x30, 0xd1, 0x94, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0x29, 0x43, 0xe2, 0x45, 0x00, 0x0c, 0x08, 0x45, 0x0a, 0x47, + 0x87, 0xed, 0xa2, 0x41, 0x00, 0xa4, 0x62, 0xf8, 0x0c, 0x2c, 0xbf, 0x45, + 0xa5, 0x41, 0x00, 0xa4, 0x07, 0xed, 0xa3, 0x41, 0x04, 0x80, 0x45, 0xf8, + 0x0c, 0x2c, 0x63, 0x30, 0xec, 0x6e, 0x31, 0x69, 0xa9, 0x41, 0x03, 0x00, + 0x80, 0x31, 0x07, 0x00, 0x20, 0x6d, 0x31, 0xe9, 0x31, 0x6b, 0xa2, 0x41, + 0x01, 0xb7, 0x85, 0xf8, 0x14, 0x2c, 0xa7, 0x41, 0x02, 0xa5, 0x60, 0x31, + 0x00, 0x02, 0x29, 0x51, 0x00, 0xe8, 0x40, 0x31, 0x00, 0x03, 0xc2, 0xf8, + 0x00, 0x11, 0xc5, 0xfc, 0x04, 0x2c, 0x34, 0x69, 0x20, 0x6d, 0x34, 0xe9, + 0xe6, 0x40, 0xf9, 0xff, 0x85, 0xf9, 0x0c, 0x2c, 0x35, 0x6b, 0x60, 0x6f, + 0x35, 0xeb, 0x67, 0xf9, 0x0c, 0x28, 0x07, 0xf8, 0x28, 0x28, 0x27, 0xf9, + 0x20, 0x28, 0x47, 0xf9, 0x28, 0x28, 0x47, 0xfc, 0x24, 0x28, 0x21, 0x25, + 0xa2, 0x40, 0xfb, 0xff, 0x85, 0xf8, 0x14, 0x2c, 0xe4, 0xcf, 0x00, 0x0c, + 0xa2, 0x41, 0x00, 0xa4, 0xa2, 0xfc, 0x50, 0x2c, 0x80, 0x30, 0x83, 0x00, + 0x00, 0x31, 0x84, 0x00, 0xa5, 0x50, 0x80, 0x00, 0xa2, 0xf8, 0x50, 0x2c, + 0xe0, 0x30, 0x86, 0x00, 0xc0, 0x30, 0x85, 0x00, 0xa3, 0x41, 0x01, 0xa4, + 0x87, 0xee, 0xa2, 0xf8, 0x08, 0x2c, 0x63, 0x50, 0x90, 0x91, 0x02, 0xf8, + 0x10, 0x2c, 0x82, 0xf8, 0x80, 0x2c, 0x82, 0xf8, 0x84, 0x2c, 0x82, 0xf8, + 0x88, 0x2c, 0x02, 0xf9, 0x8c, 0x2c, 0x02, 0xf9, 0x90, 0x2c, 0xe2, 0xf8, + 0x94, 0x2c, 0xe2, 0xf8, 0x98, 0x2c, 0xc2, 0xf8, 0x80, 0x2d, 0xc2, 0xf8, + 0x84, 0x2d, 0x40, 0x30, 0xa6, 0x00, 0x30, 0xe8, 0x43, 0xf8, 0x04, 0xff, + 0x43, 0xed, 0x43, 0xf8, 0xf0, 0xfe, 0x40, 0x30, 0xa9, 0x00, 0x43, 0xf8, + 0x08, 0xff, 0x33, 0xed, 0x43, 0xf8, 0xf8, 0xfe, 0xbf, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x02, 0xa5, 0x40, 0x26, 0x60, 0x30, 0x00, 0x02, 0x62, 0xf8, + 0x0c, 0x28, 0x02, 0xf8, 0x28, 0x28, 0x82, 0xf8, 0x20, 0x28, 0x80, 0x30, + 0x00, 0x03, 0xa3, 0x41, 0x02, 0xa5, 0x82, 0xf8, 0x28, 0x28, 0x43, 0xfc, + 0x24, 0x28, 0x21, 0x25, 0xa2, 0x40, 0xfb, 0xff, 0xbf, 0x45, 0x00, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x47, 0x19, 0x44, 0x45, + 0xc2, 0x45, 0xb0, 0x41, 0x00, 0xa4, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x71, 0x66, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0x29, 0x96, 0xe2, 0x45, 0x00, 0x0c, 0x40, 0x30, 0xff, 0x00, 0x50, 0xf8, + 0x34, 0x2c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x2d, 0x18, 0xc2, 0x45, + 0x10, 0x52, 0xf0, 0xb0, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x6f, 0x15, + 0xe2, 0x45, 0x00, 0x0c, 0x80, 0x69, 0xa2, 0x41, 0x01, 0xa4, 0x42, 0x50, + 0x04, 0x90, 0x60, 0x00, 0x0c, 0x00, 0x80, 0xe9, 0xa0, 0x69, 0x80, 0x0c, + 0x60, 0x00, 0xcc, 0x18, 0xa0, 0xe9, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xf9, 0x65, 0xe2, 0x45, 0x00, 0x0c, 0x00, 0x0c, 0xbd, 0x33, 0x08, 0xf8, + 0x3d, 0x23, 0xd0, 0xd7, 0xbd, 0x33, 0xa8, 0xf7, 0xa2, 0x41, 0x03, 0x80, + 0x42, 0x30, 0xf9, 0xab, 0xe2, 0x45, 0x84, 0x0e, 0x94, 0x60, 0x03, 0x00, + 0x54, 0x14, 0x05, 0x00, 0xf4, 0x14, 0x04, 0x00, 0x94, 0x60, 0x00, 0x10, + 0x20, 0x25, 0xfa, 0x44, 0xa2, 0x41, 0x08, 0x80, 0xdd, 0x30, 0x20, 0x10, + 0x42, 0x30, 0xcd, 0x17, 0xbd, 0x30, 0x22, 0x10, 0xc2, 0x45, 0x1d, 0xf8, + 0x10, 0x00, 0x7d, 0x34, 0x22, 0x10, 0x5d, 0x34, 0x20, 0x10, 0x74, 0x62, + 0x03, 0x00, 0x62, 0x00, 0x90, 0x23, 0x74, 0x62, 0x00, 0x10, 0x83, 0x00, + 0x18, 0x10, 0x62, 0xb0, 0xff, 0x01, 0xb9, 0xad, 0xd3, 0x0c, 0x74, 0x14, + 0x05, 0x00, 0x94, 0x14, 0x04, 0x00, 0x42, 0xb0, 0xff, 0x03, 0xb0, 0x25, + 0xa2, 0xb2, 0x01, 0x00, 0x83, 0x00, 0x90, 0x12, 0x2c, 0x8d, 0xa2, 0x4e, + 0xb2, 0x41, 0x08, 0x80, 0xb1, 0x41, 0x08, 0x80, 0xc0, 0x0e, 0x52, 0x32, + 0x85, 0x17, 0x31, 0x32, 0xa3, 0x17, 0x93, 0xfc, 0x00, 0x00, 0xf2, 0x45, + 0xc2, 0x4e, 0x93, 0xfc, 0x00, 0x00, 0x55, 0x00, 0x90, 0x80, 0xd1, 0x45, + 0x10, 0x02, 0x00, 0xa0, 0x55, 0x00, 0x90, 0x10, 0x42, 0xd0, 0xff, 0x0f, + 0x10, 0x02, 0x80, 0x40, 0xc2, 0x44, 0x13, 0xfa, 0x00, 0x00, 0x54, 0x14, + 0x05, 0x00, 0x74, 0x14, 0x04, 0x00, 0x20, 0x25, 0xd3, 0x44, 0x56, 0x00, + 0x90, 0x13, 0x63, 0xad, 0x68, 0x4e, 0xd4, 0x60, 0x03, 0x00, 0xd4, 0x60, + 0x00, 0x10, 0x01, 0xed, 0x45, 0xc8, 0x40, 0x30, 0x00, 0x02, 0x44, 0xc8, + 0xa7, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x25, 0x58, + 0xe7, 0x30, 0xb8, 0xb1, 0x91, 0x6e, 0x9d, 0x30, 0x20, 0x08, 0x06, 0xc8, + 0x07, 0xc8, 0xc2, 0x45, 0xb5, 0x41, 0x03, 0x80, 0x11, 0x6d, 0x9d, 0x32, + 0x20, 0x08, 0x20, 0x0e, 0xc0, 0x0f, 0xe0, 0x0e, 0xb5, 0x32, 0x39, 0x8e, + 0xc0, 0x32, 0x00, 0x02, 0x62, 0x0e, 0x53, 0xfe, 0x00, 0x00, 0x94, 0xfc, + 0x00, 0x00, 0x68, 0x4e, 0x52, 0x02, 0x80, 0x48, 0xd5, 0x45, 0x84, 0x00, + 0x80, 0x48, 0x92, 0x0c, 0xf5, 0x45, 0x02, 0x0e, 0x20, 0x05, 0x57, 0x00, + 0x90, 0x1b, 0x71, 0x00, 0x18, 0xf0, 0x90, 0x6c, 0x62, 0x00, 0x18, 0xb8, + 0xd1, 0xb6, 0xe9, 0xff, 0x88, 0x4e, 0x5e, 0x0c, 0xbd, 0x33, 0x58, 0x08, + 0x3d, 0x23, 0xd0, 0x57, 0x9f, 0x45, 0xbd, 0x33, 0xf8, 0x07, 0x00, 0x0c, + 0xdd, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x0c, 0xaf, 0x3d, 0x23, + 0x20, 0xd0, 0xb5, 0x41, 0x08, 0x80, 0xb4, 0x41, 0x08, 0x80, 0xb3, 0x41, + 0x03, 0x80, 0xb2, 0x41, 0x08, 0x80, 0x25, 0x0e, 0xc6, 0x0e, 0x04, 0x1e, + 0x0e, 0x00, 0xe4, 0x16, 0x0f, 0x00, 0xc3, 0x45, 0xb5, 0x32, 0xf7, 0x11, + 0x94, 0x32, 0xad, 0x13, 0x73, 0x32, 0xf9, 0xab, 0x52, 0x32, 0xcd, 0x17, + 0xd0, 0xd3, 0xff, 0x00, 0xb7, 0x0c, 0xde, 0x0c, 0xf5, 0x45, 0x96, 0x0c, + 0xf4, 0x45, 0x0a, 0xee, 0xf3, 0x45, 0x91, 0x0c, 0x91, 0x60, 0x03, 0x00, + 0x04, 0xc8, 0xbd, 0x30, 0x1a, 0x00, 0x91, 0x60, 0x00, 0x10, 0xe0, 0x30, + 0x80, 0x00, 0xf2, 0x45, 0x0d, 0x6f, 0x7d, 0x34, 0x1a, 0x00, 0x5d, 0x34, + 0x18, 0x00, 0xbe, 0x30, 0x01, 0x00, 0x62, 0x00, 0x90, 0x23, 0x83, 0x00, + 0x18, 0x10, 0x62, 0xb0, 0x00, 0x01, 0x91, 0x8d, 0x42, 0xb0, 0x00, 0x02, + 0x05, 0x02, 0x3c, 0x2b, 0x10, 0x40, 0x15, 0x00, 0x57, 0xb0, 0x04, 0x00, + 0x50, 0x90, 0x19, 0x00, 0x55, 0xad, 0xd0, 0xd3, 0xff, 0x00, 0x01, 0xed, + 0x3d, 0x23, 0x20, 0x50, 0x12, 0x47, 0x0f, 0xad, 0xde, 0x4f, 0x1e, 0x02, + 0x3c, 0x2b, 0x50, 0x40, 0xf3, 0xff, 0x50, 0x90, 0x19, 0x00, 0x57, 0xb0, + 0x04, 0x00, 0x71, 0x8d, 0xe2, 0x4e, 0xf7, 0xd2, 0xff, 0x00, 0xbe, 0xcf, + 0x04, 0xec, 0x57, 0xb0, 0x04, 0x00, 0x70, 0x90, 0x19, 0x00, 0x42, 0x70, + 0x01, 0x00, 0x10, 0x92, 0x00, 0x00, 0x63, 0x70, 0x01, 0x00, 0x03, 0x02, + 0x58, 0x10, 0x3d, 0x23, 0x20, 0x50, 0x12, 0x47, 0xa5, 0x41, 0x04, 0x80, + 0x45, 0x1c, 0x68, 0x6f, 0x02, 0x94, 0x4f, 0x00, 0xa2, 0x41, 0x00, 0xa4, + 0xa2, 0x41, 0x04, 0x80, 0x62, 0x1c, 0x69, 0x6f, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x1c, 0x6a, 0x6f, 0xa4, 0x30, 0xd7, 0xff, 0xa5, 0xb0, 0x1e, 0x00, + 0xab, 0x8e, 0xa4, 0x90, 0x47, 0x00, 0x63, 0x30, 0x0a, 0x00, 0x42, 0x30, + 0x0b, 0x00, 0x63, 0x00, 0x3c, 0x2b, 0x42, 0x00, 0x3c, 0x2b, 0x03, 0x40, + 0x2c, 0x00, 0x83, 0x0c, 0x84, 0x00, 0x3c, 0x2b, 0x02, 0x40, 0x2d, 0x00, + 0x62, 0x0c, 0xa4, 0x90, 0x10, 0x00, 0x83, 0xae, 0x43, 0x00, 0x3c, 0x2b, + 0x0f, 0xee, 0xa3, 0x41, 0x00, 0xa4, 0x84, 0x00, 0x3c, 0x2b, 0x63, 0x50, + 0xd8, 0x99, 0xa2, 0x90, 0x10, 0x00, 0x30, 0xea, 0x83, 0xae, 0xa3, 0x41, + 0x00, 0xa4, 0x0f, 0xed, 0x42, 0x00, 0x3c, 0x2b, 0x63, 0x50, 0xd8, 0x9f, + 0x30, 0xe9, 0xbf, 0x45, 0xa5, 0x40, 0x2c, 0x00, 0x63, 0x30, 0x0d, 0x00, + 0x42, 0x30, 0x0f, 0x00, 0x63, 0x00, 0x3c, 0x2b, 0x42, 0x00, 0x3c, 0x2b, + 0x43, 0x40, 0xd6, 0xff, 0x83, 0x0c, 0x80, 0x0c, 0x84, 0x00, 0x3c, 0x2b, + 0x42, 0x40, 0xd5, 0xff, 0x62, 0x0c, 0xd3, 0xcf, 0x60, 0x0c, 0x42, 0x50, + 0xd8, 0x99, 0xa0, 0x69, 0xa6, 0x41, 0x04, 0x80, 0xb7, 0x2d, 0x70, 0x4c, + 0x63, 0x00, 0x3c, 0x2b, 0x66, 0x18, 0x69, 0x6f, 0x42, 0xfc, 0x00, 0x06, + 0x01, 0xef, 0xc5, 0x18, 0x68, 0x6f, 0x27, 0x2d, 0x50, 0x4c, 0x42, 0x00, + 0x3c, 0x2b, 0xa5, 0x41, 0x04, 0x80, 0xa4, 0xcf, 0x45, 0x18, 0x6a, 0x6f, + 0xa4, 0x30, 0x13, 0x00, 0xa5, 0xb0, 0x14, 0x00, 0xa5, 0x40, 0x0b, 0x00, + 0x84, 0x90, 0xed, 0xff, 0xe4, 0x40, 0x0e, 0x00, 0x6c, 0x4c, 0x4a, 0x4c, + 0x63, 0x00, 0x3c, 0x2b, 0xa2, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0x6e, 0x4c, + 0x4c, 0x4c, 0x63, 0x00, 0x3c, 0x2b, 0x9b, 0xcf, 0x42, 0x00, 0x3c, 0x2b, + 0xb4, 0x6d, 0x24, 0x6d, 0x63, 0x00, 0x3c, 0x2b, 0x94, 0xcf, 0x42, 0x00, + 0x3c, 0x2b, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x14, 0x04, 0x6f, + 0x02, 0xb4, 0x4c, 0x00, 0xa4, 0x41, 0x04, 0x80, 0x44, 0x1c, 0x6d, 0x6f, + 0x1e, 0xad, 0xa5, 0x41, 0x04, 0x80, 0xa3, 0x41, 0x00, 0xa4, 0x63, 0x50, + 0x04, 0x9f, 0x30, 0x69, 0xa5, 0x41, 0x03, 0x80, 0xa5, 0xfc, 0x84, 0xea, + 0x2d, 0x2d, 0x55, 0x05, 0xa5, 0x41, 0x04, 0x80, 0x45, 0xf8, 0x70, 0x6f, + 0x01, 0xed, 0x44, 0x18, 0x6d, 0x6f, 0x43, 0xfc, 0x00, 0xfa, 0xa3, 0x41, + 0x04, 0x80, 0x2d, 0x2d, 0x52, 0x4c, 0x43, 0xf8, 0x74, 0x6f, 0xa5, 0x41, + 0x04, 0x80, 0x45, 0x1c, 0x68, 0x6f, 0x26, 0xad, 0xa2, 0x41, 0x00, 0xa4, + 0x42, 0x50, 0xd8, 0x99, 0x20, 0x6a, 0x62, 0xfc, 0x00, 0x06, 0xa6, 0x41, + 0x04, 0x80, 0x47, 0x2e, 0x90, 0x4c, 0xb7, 0x2d, 0x86, 0x18, 0x69, 0x6f, + 0x70, 0x4c, 0xa4, 0x41, 0x04, 0x80, 0x64, 0x18, 0x6a, 0x6f, 0x62, 0xfc, + 0xfc, 0xff, 0x42, 0xfc, 0xfc, 0x05, 0xa4, 0x41, 0x04, 0x80, 0xb7, 0x2d, + 0x70, 0x4c, 0x27, 0x2d, 0x50, 0x4c, 0x64, 0x18, 0x6b, 0x6f, 0xa3, 0x41, + 0x04, 0x80, 0x43, 0x18, 0x6c, 0x6f, 0x01, 0xed, 0x45, 0x18, 0x68, 0x6f, + 0xbf, 0x45, 0x00, 0x0c, 0xf1, 0x4f, 0x5d, 0x14, 0x30, 0x00, 0x46, 0x45, + 0x44, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x5d, 0xf0, 0xe2, 0x45, + 0x06, 0x0e, 0x17, 0x8c, 0xa2, 0x41, 0x00, 0xa4, 0x42, 0x50, 0x04, 0x9f, + 0xa4, 0x41, 0x04, 0x80, 0xa0, 0x69, 0x84, 0xfc, 0x70, 0x6f, 0x9f, 0xee, + 0x06, 0x45, 0x46, 0x06, 0x64, 0x90, 0x20, 0x00, 0x64, 0x00, 0x18, 0x28, + 0x65, 0x0c, 0x85, 0x90, 0x00, 0x00, 0x80, 0x00, 0x18, 0x18, 0xa0, 0xe9, + 0x08, 0x47, 0xa2, 0x41, 0x04, 0x80, 0x42, 0xfc, 0x74, 0x6f, 0x1f, 0xee, + 0x06, 0x45, 0x62, 0x30, 0x07, 0x00, 0x43, 0x90, 0x20, 0x00, 0x43, 0x00, + 0x18, 0x20, 0x64, 0x90, 0x00, 0x00, 0x44, 0x0c, 0x60, 0x00, 0x18, 0x10, + 0xa3, 0x41, 0x00, 0xa4, 0x63, 0x50, 0x04, 0x99, 0x30, 0xe9, 0x08, 0x47, + 0xed, 0x4f, 0x5c, 0xfc, 0x44, 0x81, 0x66, 0x45, 0x04, 0x0e, 0x42, 0xfc, + 0x58, 0x00, 0x82, 0x94, 0x11, 0x00, 0x25, 0x0e, 0x01, 0xed, 0x44, 0x94, + 0x23, 0x00, 0xe0, 0x0c, 0x5c, 0xfc, 0x48, 0x81, 0x01, 0xef, 0xa0, 0x0c, + 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x37, 0x11, 0xc2, 0x45, + 0x80, 0x30, 0x04, 0x0d, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, + 0xc2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, + 0x42, 0x30, 0x49, 0xf3, 0xe2, 0x45, 0x00, 0x0c, 0xb9, 0x41, 0x04, 0x80, + 0x98, 0x86, 0x39, 0x33, 0xf5, 0x56, 0x26, 0x45, 0x99, 0x45, 0x15, 0x4c, + 0x5c, 0xfc, 0x48, 0x81, 0xb2, 0x41, 0x08, 0x80, 0x01, 0xef, 0x44, 0xc8, + 0x81, 0xee, 0x52, 0x32, 0x37, 0x11, 0xd2, 0x45, 0x80, 0x30, 0x04, 0x0d, + 0x5c, 0xfc, 0x48, 0x81, 0x83, 0xef, 0x08, 0xef, 0x81, 0xee, 0x80, 0x30, + 0x04, 0x0d, 0xd2, 0x45, 0x5d, 0xf8, 0x10, 0x00, 0xd5, 0xcf, 0xa2, 0x41, + 0x08, 0x80, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, 0x01, 0x80, 0x57, 0x45, + 0x42, 0x30, 0xdd, 0x02, 0x25, 0x0e, 0xe2, 0x45, 0x04, 0x0e, 0x98, 0xac, + 0xb9, 0x41, 0x08, 0x80, 0xb1, 0x41, 0x08, 0x80, 0xe0, 0x0c, 0x01, 0xef, + 0xa0, 0x0c, 0x80, 0x30, 0x04, 0x0d, 0x31, 0x32, 0x37, 0x11, 0xd1, 0x45, + 0x1d, 0xfa, 0x10, 0x00, 0x83, 0xef, 0x08, 0xef, 0xa0, 0x0c, 0x80, 0x30, + 0x04, 0x0d, 0xd1, 0x45, 0x1d, 0xfa, 0x10, 0x00, 0xb9, 0x41, 0x08, 0x80, + 0x90, 0x0c, 0x39, 0x33, 0x1f, 0x17, 0x17, 0x45, 0x99, 0x45, 0x15, 0x4c, + 0x4b, 0x40, 0x04, 0x80, 0x1f, 0x40, 0x04, 0x80, 0x7f, 0x40, 0x04, 0x80, + 0xcb, 0x40, 0x04, 0x80, 0x83, 0x41, 0x04, 0x80, 0x07, 0x41, 0x04, 0x80, + 0x55, 0x41, 0x04, 0x80, 0x53, 0x40, 0x04, 0x80, 0x9d, 0x5e, 0x04, 0x80, + 0x9d, 0x5e, 0x04, 0x80, 0x9d, 0x5e, 0x04, 0x80, 0x4f, 0x5f, 0x04, 0x80, + 0xe7, 0x60, 0x04, 0x80, 0x0b, 0x61, 0x04, 0x80, 0x97, 0x61, 0x04, 0x80, + 0xa3, 0x61, 0x04, 0x80, 0xc5, 0x61, 0x04, 0x80, 0xd9, 0x61, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0xc7, 0x5c, 0x04, 0x80, + 0x5d, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, 0x47, 0x5e, 0x04, 0x80, + 0x47, 0x5e, 0x04, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x6d, 0x65, 0x61, 0x73, + 0x75, 0x72, 0x65, 0x20, 0x74, 0x65, 0x6d, 0x70, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, 0x20, 0x70, 0x6f, 0x77, + 0x65, 0x72, 0x20, 0x73, 0x61, 0x76, 0x65, 0x00, 0x63, 0x68, 0x61, 0x6e, + 0x6e, 0x65, 0x6c, 0x20, 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x00, + 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x20, 0x64, 0x6f, 0x6e, 0x65, 0x20, 0x00, 0x00, 0x00, 0x00, + 0x76, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x6e, 0x65, 0x63, 0x74, 0x65, + 0x64, 0x20, 0x65, 0x78 +}; + +#elif CONFIG_NRF700X_SCAN_ONLY_MODE +const unsigned char __aligned(4) nrf_wifi_umac_patch_pri_bimg[] = { + 0xba, 0xda, 0xba, 0xab, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x93, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xa6, 0x70, 0x00, 0x00, 0x04, 0xd4, 0x7c, 0x6f, 0xe8, 0x22, 0x10, 0x80, + 0x01, 0x00, 0xbf, 0x22, 0x04, 0xd4, 0xbc, 0x6a, 0xa8, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x4e, 0x53, 0x04, 0xd4, 0x4e, 0x69, 0xf8, 0x24, 0x10, 0x80, + 0x01, 0x00, 0xe1, 0x9d, 0x04, 0xd4, 0x40, 0x65, 0xbe, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x3b, 0x1c, 0x04, 0xd4, 0x20, 0x6f, 0x26, 0x21, 0x10, 0x80, + 0x01, 0x00, 0x2d, 0x28, 0x04, 0xd4, 0x0e, 0x6e, 0xac, 0x22, 0x10, 0x80, + 0x01, 0x00, 0xc5, 0xc9, 0x04, 0xd4, 0xea, 0x6b, 0x40, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x39, 0x28, 0x04, 0xd4, 0x64, 0x6f, 0x54, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x89, 0x98, 0x04, 0xd4, 0x72, 0x68, 0x76, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0x79, 0xc6, 0x04, 0xd4, 0xec, 0x64, 0x6e, 0x24, 0x10, 0x80, + 0x01, 0x00, 0xe1, 0x3d, 0x04, 0xd4, 0xec, 0x66, 0xfa, 0x19, 0x10, 0x80, + 0x01, 0x00, 0x93, 0xb8, 0x04, 0xd4, 0xda, 0x72, 0x8e, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0x81, 0x06, 0x04, 0xd4, 0xa8, 0x6a, 0x90, 0x14, 0x10, 0x80, + 0x01, 0x00, 0x25, 0xeb, 0x04, 0xd4, 0xdc, 0x6e, 0x58, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x9b, 0xe7, 0x04, 0xd4, 0xb6, 0x65, 0xc6, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x60, 0x97, 0x04, 0xd4, 0xb4, 0x6e, 0x78, 0x23, 0x10, 0x80, + 0x01, 0x00, 0xa0, 0xeb, 0x04, 0xd4, 0x74, 0x65, 0xc2, 0x1b, 0x10, 0x80, + 0x01, 0x00, 0xb3, 0xd8, 0x04, 0xd4, 0xb2, 0x64, 0x10, 0x10, 0x10, 0x80, + 0x01, 0x00, 0x43, 0x28, 0x04, 0xd4, 0x1e, 0x6a, 0x34, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x85, 0x91, 0x04, 0xd4, 0xf6, 0x68, 0x08, 0x21, 0x10, 0x80, + 0x01, 0x00, 0xec, 0x32, 0x04, 0xd4, 0xe6, 0x62, 0xf0, 0x20, 0x10, 0x80, + 0x01, 0x00, 0xb9, 0xca, 0x04, 0xd4, 0xda, 0x62, 0xc4, 0x25, 0x10, 0x80, + 0x01, 0x00, 0xa8, 0x97, 0x04, 0xd4, 0x5e, 0x71, 0xee, 0x25, 0x10, 0x80, + 0x01, 0x00, 0xb7, 0x39, 0x04, 0xd4, 0x2a, 0x73, 0xae, 0x14, 0x10, 0x80, + 0x01, 0x00, 0x9a, 0x2a, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0xba, 0x3e +}; + +const unsigned char __aligned(4) nrf_wifi_umac_patch_sec_bin[] = { + 0xf5, 0x4f, 0xa5, 0x41, 0x06, 0x80, 0xa5, 0x30, 0x2c, 0xae, 0x58, 0x09, + 0x44, 0x45, 0xb0, 0x41, 0x09, 0x80, 0x22, 0x27, 0x2c, 0x07, 0x6a, 0x27, + 0xa2, 0x41, 0x01, 0x80, 0x90, 0x30, 0x50, 0xe8, 0x42, 0x30, 0xbd, 0xa4, + 0xe2, 0x45, 0x68, 0x6f, 0xa3, 0x41, 0x59, 0x00, 0x50, 0x30, 0x50, 0xe8, + 0x83, 0x30, 0xf8, 0x08, 0x63, 0x50, 0x58, 0xf3, 0x62, 0xf8, 0xb4, 0x02, + 0x60, 0x50, 0x40, 0x9c, 0x62, 0xf8, 0xb8, 0x02, 0x60, 0x30, 0x8c, 0x0a, + 0x62, 0xf8, 0xc0, 0x02, 0x60, 0x30, 0x88, 0x08, 0x82, 0xf8, 0xb0, 0x02, + 0x02, 0xf8, 0xbc, 0x02, 0x62, 0xf8, 0x04, 0x03, 0x04, 0x45, 0x06, 0x47, + 0x5c, 0xfc, 0x28, 0x82, 0xa3, 0x41, 0x02, 0x01, 0x63, 0x30, 0x63, 0x08, + 0x62, 0x60, 0x07, 0x80, 0x62, 0x60, 0x04, 0x90, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x50, 0xe8, 0xa3, 0x41, 0x13, 0x80, 0x43, 0xf8, 0x8c, 0x1e, + 0xa2, 0x41, 0x09, 0x80, 0xa4, 0x41, 0x13, 0x80, 0x42, 0x30, 0x6d, 0xdb, + 0x7c, 0xfc, 0xb0, 0x81, 0x44, 0xf8, 0xa0, 0x5d, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0xc1, 0xc2, 0xa4, 0x41, 0x13, 0x80, 0x83, 0x8d, 0x44, 0xf8, + 0x48, 0x63, 0xbf, 0x45, 0xf5, 0x4f, 0xa4, 0x41, 0x09, 0x80, 0x44, 0x30, + 0x18, 0xe8, 0xe5, 0xcb, 0x04, 0xf8, 0x18, 0xe8, 0x2b, 0xe8, 0x2a, 0xe8, + 0x29, 0xe8, 0x28, 0xe8, 0x27, 0xe8, 0x26, 0xe8, 0x25, 0xe8, 0x24, 0xe8, + 0x23, 0xe8, 0x22, 0xe8, 0x21, 0xe8, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x41, + 0x09, 0x80, 0x02, 0x18, 0x00, 0xe8, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x30, + 0x04, 0xe8, 0x02, 0xf8, 0xb4, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x03, 0xf8, + 0x04, 0xe8, 0x42, 0x30, 0x01, 0xc0, 0xe2, 0x45, 0x52, 0xa8, 0xe5, 0x4b, + 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x4c, 0xe8, 0x06, 0x47, 0x00, 0x0c, + 0x64, 0x30, 0x94, 0xf6, 0x63, 0xb0, 0x49, 0x00, 0x85, 0x8d, 0x40, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0xa4, 0xe7, 0x64, 0x30, 0xd8, 0xeb, + 0x63, 0xb0, 0xb5, 0x00, 0x86, 0x8d, 0x64, 0x30, 0x98, 0xea, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0xa5, 0xe7, 0x63, 0xb0, 0xf1, 0x00, 0xe3, 0x40, + 0x04, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0xa6, 0xe7, 0x84, 0x30, + 0x8f, 0xe9, 0x84, 0xb0, 0x8d, 0x00, 0xe4, 0x40, 0x04, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0xa7, 0xe7, 0xbf, 0x45, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0x24, 0x9b, 0x24, 0x31, 0xf6, 0xff, 0x43, 0x15, 0x08, 0x00, + 0x0a, 0x94, 0x25, 0x00, 0x84, 0x30, 0x0a, 0x00, 0xa8, 0x41, 0x62, 0x10, + 0xb8, 0x6d, 0xc0, 0x0c, 0x08, 0x31, 0xd3, 0x4d, 0x30, 0x69, 0xb1, 0x6a, + 0x60, 0x6f, 0x02, 0x01, 0x3c, 0x9b, 0x02, 0x46, 0x2d, 0x25, 0x49, 0x00, + 0x90, 0x3b, 0x90, 0xaf, 0x63, 0x30, 0x60, 0x00, 0x05, 0x01, 0x3c, 0x9b, + 0x05, 0x46, 0xdd, 0x26, 0x85, 0x00, 0x90, 0x3b, 0xa7, 0x40, 0x06, 0x00, + 0x49, 0x94, 0x09, 0x00, 0x00, 0x0c, 0xa4, 0x94, 0x08, 0x00, 0x00, 0x0c, + 0x46, 0xb5, 0xe4, 0xff, 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, 0x9f, 0x45, + 0x01, 0xed, 0x9f, 0x45, 0x02, 0xed, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0xe5, 0xcb, 0x42, 0x30, 0x59, 0xc1, 0xe2, 0x45, 0x64, 0x0d, + 0x10, 0x8d, 0x6b, 0x30, 0x94, 0xf6, 0x63, 0xb0, 0x49, 0x00, 0x8d, 0x8d, + 0x6b, 0x30, 0xd8, 0xeb, 0x81, 0xed, 0x62, 0x94, 0x24, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0xa9, 0xe7, 0xe5, 0x4b, + 0x06, 0x47, 0x63, 0xb0, 0x51, 0x00, 0x91, 0xad, 0x81, 0xed, 0x6b, 0x30, + 0x74, 0xeb, 0x63, 0xb0, 0x51, 0x00, 0x96, 0x8d, 0x6b, 0x30, 0x98, 0xea, + 0x81, 0xed, 0x62, 0x94, 0x30, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0xec, 0xcf, 0x42, 0x14, 0xad, 0xe7, 0x62, 0x94, 0x23, 0x00, 0xe5, 0x4b, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0xab, 0xe7, 0x06, 0x47, 0xe1, 0xcf, + 0x42, 0x14, 0xa8, 0xe7, 0x63, 0xb0, 0xf1, 0x00, 0x8f, 0xad, 0x81, 0xed, + 0x6b, 0x30, 0x8f, 0xe9, 0x63, 0xb0, 0x51, 0x00, 0x9b, 0x8d, 0x81, 0xed, + 0x62, 0x94, 0x2d, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xcf, 0xcf, + 0x42, 0x14, 0xb1, 0xe7, 0x62, 0x94, 0x1e, 0x00, 0x00, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0xc7, 0xcf, 0x42, 0x14, 0xaf, 0xe7, 0xa2, 0x41, 0x09, 0x80, + 0xc2, 0xcf, 0x42, 0x14, 0xaa, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xbd, 0xcf, + 0x42, 0x14, 0xac, 0xe7, 0x6b, 0x31, 0x2b, 0xe9, 0x6b, 0xb1, 0x29, 0x00, + 0xeb, 0x40, 0x0d, 0x00, 0x62, 0x94, 0x12, 0x00, 0x00, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0xaf, 0xcf, 0x42, 0x14, 0xb3, 0xe7, 0xa2, 0x41, 0x09, 0x80, + 0xaa, 0xcf, 0x42, 0x14, 0xae, 0xe7, 0xa7, 0xcf, 0x40, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0xa3, 0xcf, 0x42, 0x14, 0xb0, 0xe7, 0xa2, 0x41, 0x09, 0x80, + 0x9e, 0xcf, 0x42, 0x14, 0xb2, 0xe7, 0x00, 0x0c, 0xdd, 0x4f, 0x3d, 0x23, + 0x20, 0xd0, 0x4f, 0x68, 0xa2, 0x41, 0x10, 0x80, 0x25, 0x0e, 0x90, 0x32, + 0x18, 0x00, 0x42, 0x30, 0x0b, 0x1f, 0x44, 0x0e, 0xe2, 0x45, 0x94, 0x0c, + 0x1a, 0x2d, 0x02, 0x94, 0x50, 0x00, 0x1c, 0x2d, 0x52, 0xfc, 0x04, 0x00, + 0x0a, 0xe9, 0x52, 0xfc, 0x14, 0x00, 0x21, 0x6a, 0x44, 0x30, 0x94, 0xf6, + 0x42, 0xb0, 0x49, 0x00, 0x05, 0x8d, 0x80, 0x0d, 0xa2, 0x41, 0x09, 0x80, + 0x82, 0x15, 0xa4, 0xe7, 0x44, 0x30, 0xd8, 0xeb, 0x42, 0xb0, 0xb5, 0x00, + 0x08, 0x8d, 0x44, 0x30, 0x98, 0xea, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, + 0xa5, 0xe7, 0x44, 0x30, 0x98, 0xea, 0x42, 0xb0, 0xf1, 0x00, 0x08, 0x8d, + 0x44, 0x30, 0x8f, 0xe9, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0xa6, 0xe7, + 0x44, 0x30, 0x8f, 0xe9, 0x42, 0xb0, 0x8d, 0x00, 0x08, 0x8d, 0xa2, 0x41, + 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0xa7, 0xe7, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0xc5, 0xc1, 0xe2, 0x45, 0x00, 0x0c, 0x0a, 0x6a, + 0x84, 0x01, 0xd0, 0x21, 0x29, 0x06, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xb9, 0xd7, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x94, 0xca, 0x00, 0xa3, 0x41, + 0x10, 0x80, 0x94, 0x0c, 0x63, 0x30, 0x1d, 0x1f, 0xc3, 0x45, 0x5d, 0xf8, + 0x18, 0x00, 0x3d, 0x23, 0x20, 0x50, 0x46, 0x48, 0x12, 0x47, 0x02, 0x94, + 0x67, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x52, 0xfc, 0x04, 0x00, 0x0a, 0xe9, + 0x52, 0xfc, 0x14, 0x00, 0x21, 0x6a, 0x44, 0x30, 0x94, 0xf6, 0x42, 0xb0, + 0x49, 0x00, 0x05, 0x8d, 0x80, 0x0d, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, + 0xa4, 0xe7, 0x44, 0x30, 0xd8, 0xeb, 0x42, 0xb0, 0xb5, 0x00, 0x08, 0x8d, + 0x44, 0x30, 0x98, 0xea, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0xa5, 0xe7, + 0x44, 0x30, 0x98, 0xea, 0x42, 0xb0, 0xf1, 0x00, 0x08, 0x8d, 0x44, 0x30, + 0x8f, 0xe9, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0xa6, 0xe7, 0x44, 0x30, + 0x8f, 0xe9, 0x42, 0xb0, 0x8d, 0x00, 0x08, 0x8d, 0xa2, 0x41, 0x09, 0x80, + 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0xa7, 0xe7, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0xc5, 0xc1, 0xe2, 0x45, 0x00, 0x0c, 0x0a, 0x6a, 0x84, 0x01, + 0xd0, 0x21, 0x29, 0x06, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xb9, 0xd7, + 0xe2, 0x45, 0x00, 0x0c, 0x02, 0xb4, 0xaf, 0xff, 0xa3, 0x41, 0x10, 0x80, + 0x52, 0xfc, 0x14, 0x00, 0x72, 0xfe, 0x1c, 0x00, 0xd2, 0xfe, 0x18, 0x00, + 0x21, 0x6a, 0xe2, 0xfe, 0x00, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xe9, 0x16, 0xc2, 0x45, 0xb2, 0xfe, 0x20, 0x00, 0xe4, 0x86, 0xa2, 0x41, + 0x10, 0x80, 0xf6, 0x0c, 0xd5, 0x0c, 0x42, 0x30, 0x8f, 0x22, 0xc2, 0x45, + 0xfd, 0xfa, 0x10, 0x00, 0x02, 0xb4, 0x91, 0xff, 0xa3, 0x41, 0x10, 0x80, + 0xa2, 0x41, 0x04, 0x80, 0xd1, 0xd3, 0x10, 0x00, 0x60, 0x0e, 0xe0, 0x32, + 0x01, 0x00, 0xa7, 0x41, 0x09, 0x80, 0xc2, 0x32, 0xc5, 0xdf, 0xa0, 0x32, + 0x02, 0x00, 0x1e, 0x94, 0x0a, 0x00, 0xf3, 0x02, 0x10, 0x10, 0x85, 0x69, + 0x93, 0x44, 0xa2, 0x40, 0x25, 0x00, 0x62, 0x4e, 0xb3, 0xb6, 0xf5, 0xff, + 0x00, 0x0c, 0x12, 0x2d, 0xe2, 0x40, 0x07, 0x00, 0x05, 0x69, 0xa1, 0x2d, + 0x03, 0xb4, 0x7d, 0x00, 0x22, 0x2d, 0xa2, 0x40, 0x3a, 0x00, 0x90, 0x2c, + 0x89, 0x8c, 0x40, 0x0c, 0x05, 0x69, 0xa1, 0x2d, 0x03, 0xb4, 0x59, 0x00, + 0x22, 0x2d, 0xa2, 0x40, 0x3e, 0x00, 0x40, 0x0c, 0xa3, 0x41, 0x10, 0x80, + 0x94, 0x0c, 0x63, 0x30, 0x1d, 0x1f, 0xc3, 0x45, 0x5d, 0xf8, 0x18, 0x00, + 0x3d, 0x23, 0x20, 0x50, 0x46, 0x48, 0x12, 0x47, 0x50, 0x14, 0x94, 0x00, + 0x58, 0xad, 0x47, 0xfc, 0xac, 0x9b, 0xc2, 0xfc, 0x38, 0x01, 0xa6, 0x40, + 0xd2, 0xff, 0x52, 0xfc, 0x00, 0x00, 0x22, 0x2d, 0xe2, 0x40, 0x67, 0x00, + 0x01, 0xef, 0xf0, 0xfa, 0x48, 0x0b, 0x53, 0x30, 0xd2, 0x02, 0x24, 0x25, + 0x20, 0x05, 0xa1, 0x6a, 0x93, 0x0c, 0xe6, 0xc8, 0xd6, 0x45, 0xa5, 0x30, + 0x48, 0x01, 0xbf, 0xcf, 0xe6, 0x48, 0x1c, 0x2d, 0xe2, 0x40, 0xa6, 0xff, + 0x89, 0xcf, 0x52, 0xfc, 0x14, 0x00, 0xb0, 0xfc, 0x50, 0x0b, 0xd2, 0x14, + 0x30, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xa5, 0x30, 0x48, 0x01, 0x42, 0x30, + 0x71, 0xec, 0xe2, 0x45, 0x01, 0xee, 0xba, 0xcf, 0x90, 0x2c, 0x10, 0xfe, + 0x50, 0x0b, 0xd2, 0x14, 0x10, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x10, 0x32, + 0x48, 0x01, 0xb0, 0x0c, 0x42, 0x30, 0x95, 0xe7, 0xe2, 0x45, 0x01, 0xee, + 0xd2, 0x14, 0x0f, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xb0, 0x0c, 0x42, 0x30, + 0x55, 0xe7, 0xe2, 0x45, 0x01, 0xee, 0xac, 0xcf, 0x40, 0x0c, 0x30, 0xfe, + 0x4c, 0x0b, 0xa2, 0x41, 0x04, 0x80, 0x31, 0x32, 0x48, 0x01, 0x90, 0x86, + 0x42, 0x30, 0x95, 0xe7, 0xc2, 0x45, 0xd2, 0x14, 0x10, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0x90, 0x86, 0x42, 0x30, 0x55, 0xe7, 0xc2, 0x45, 0xd2, 0x14, + 0x0f, 0x00, 0x05, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0x92, 0xff, 0xcf, 0xcf, + 0x00, 0x0c, 0xb0, 0xfc, 0x4c, 0x0b, 0xd2, 0x14, 0x30, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0xa5, 0x30, 0x48, 0x01, 0x42, 0x30, 0x71, 0xec, 0xe2, 0x45, + 0x80, 0x0c, 0x05, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0x76, 0xff, 0xaf, 0xcf, + 0x00, 0x0c, 0x9b, 0xcf, 0x10, 0xf8, 0x48, 0x0b, 0xb9, 0x41, 0x09, 0x80, + 0x39, 0x33, 0x61, 0xc0, 0xb9, 0x45, 0x00, 0x0c, 0xb9, 0x41, 0x09, 0x80, + 0x39, 0x33, 0x61, 0xc0, 0xb9, 0x45, 0x00, 0x0c, 0x45, 0xfc, 0x80, 0x00, + 0xa2, 0x40, 0x3c, 0x01, 0x45, 0xfc, 0x90, 0x00, 0xa2, 0x40, 0x38, 0x01, + 0xe1, 0x4f, 0xc5, 0xc8, 0x3d, 0x23, 0x18, 0xd0, 0x44, 0x14, 0x08, 0x02, + 0x64, 0x14, 0x07, 0x02, 0xa4, 0x16, 0x0b, 0x02, 0x20, 0x25, 0xd3, 0x44, + 0xa3, 0x41, 0x09, 0x80, 0x43, 0x38, 0x10, 0xe8, 0x44, 0x14, 0x0a, 0x02, + 0x64, 0x14, 0x09, 0x02, 0x84, 0x0e, 0x20, 0x25, 0xd3, 0x44, 0xa3, 0x41, + 0x09, 0x80, 0x43, 0x38, 0x12, 0xe8, 0x64, 0x14, 0x28, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x05, 0x0e, 0x25, 0x32, 0x20, 0x01, 0x15, 0x94, 0x7e, 0x01, + 0x62, 0x18, 0x14, 0xe8, 0x55, 0x0c, 0x54, 0x16, 0x70, 0x00, 0xf4, 0x60, + 0x1f, 0x00, 0xd4, 0x60, 0x23, 0x00, 0x74, 0x14, 0x6f, 0x00, 0xd4, 0x17, + 0x2a, 0x00, 0xf4, 0x60, 0x1c, 0x10, 0xd4, 0x60, 0x20, 0x10, 0x52, 0x02, + 0x00, 0x40, 0x72, 0x00, 0x90, 0x92, 0x7e, 0x00, 0x00, 0x28, 0xc3, 0x03, + 0x50, 0x99, 0xe2, 0x02, 0x00, 0x10, 0x92, 0x30, 0x80, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0xe2, 0xf8, 0xb0, 0x9a, 0xc2, 0xf8, 0xb4, 0x9a, 0x64, 0x02, + 0x50, 0x21, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, 0xd0, 0x00, 0x42, 0x30, + 0x51, 0x1e, 0xc2, 0x45, 0xe4, 0x02, 0x50, 0x21, 0x1e, 0x94, 0xe7, 0x00, + 0xc2, 0x0e, 0x57, 0x30, 0x7c, 0x00, 0x56, 0x00, 0x50, 0x11, 0x56, 0xf8, + 0x00, 0x00, 0x12, 0xb4, 0x4e, 0x01, 0xd6, 0xfb, 0x04, 0x00, 0xf0, 0x32, + 0xec, 0x01, 0x77, 0x0d, 0x80, 0x31, 0x01, 0x00, 0xa0, 0x0d, 0x40, 0x0d, + 0xc0, 0x31, 0x04, 0x00, 0xe0, 0x31, 0x01, 0x00, 0x2b, 0xfd, 0x00, 0x00, + 0xe9, 0x40, 0x3c, 0x00, 0x54, 0x14, 0x6e, 0x00, 0xe2, 0x40, 0x05, 0x00, + 0xed, 0x40, 0x48, 0x01, 0xed, 0x95, 0x3a, 0x01, 0x22, 0x2d, 0x49, 0xfc, + 0x0c, 0x00, 0x80, 0x87, 0x82, 0x40, 0x2e, 0x00, 0x00, 0x0c, 0xc9, 0xfc, + 0x00, 0x00, 0x7c, 0x07, 0x62, 0x69, 0x21, 0x2d, 0xa2, 0x40, 0x1e, 0x00, + 0x15, 0x94, 0xa0, 0x00, 0x4a, 0x30, 0x1e, 0x00, 0x54, 0x60, 0x10, 0x02, + 0x06, 0xfd, 0x04, 0x00, 0x54, 0x60, 0x0d, 0x12, 0x02, 0x95, 0x94, 0x00, + 0x60, 0x0c, 0x08, 0xcc, 0xb0, 0x6d, 0xa2, 0x60, 0x10, 0x00, 0xa2, 0x60, + 0x0d, 0x10, 0xa8, 0x94, 0x8b, 0x00, 0xb0, 0x6d, 0x43, 0x30, 0x80, 0x00, + 0x24, 0x25, 0xa3, 0x02, 0x50, 0x2b, 0xf3, 0xae, 0x54, 0x00, 0x50, 0x11, + 0x49, 0xfc, 0x0c, 0x00, 0x40, 0x6e, 0x44, 0x00, 0x50, 0x13, 0x55, 0xad, + 0xe7, 0x30, 0x34, 0x00, 0xcc, 0x95, 0x05, 0x00, 0x00, 0x0c, 0xa2, 0x4d, + 0x68, 0x4d, 0xba, 0xcf, 0x82, 0x4d, 0x1e, 0xb4, 0xb9, 0x00, 0x56, 0xf9, + 0x08, 0x00, 0xb5, 0x41, 0x01, 0x80, 0xb5, 0x32, 0xbd, 0xa4, 0x54, 0x14, + 0x70, 0x00, 0x74, 0x14, 0x6f, 0x00, 0x20, 0x25, 0xd3, 0x44, 0xa2, 0x40, + 0xd6, 0x00, 0x76, 0x30, 0x24, 0x00, 0x90, 0x30, 0xfc, 0x01, 0x81, 0xee, + 0x57, 0xfc, 0x00, 0x00, 0x06, 0x8d, 0xe8, 0x4e, 0x24, 0x69, 0xa2, 0x00, + 0x10, 0x10, 0x2e, 0x6d, 0x30, 0xe9, 0xe4, 0xb6, 0xf5, 0xff, 0xb2, 0x6d, + 0xb4, 0x30, 0x01, 0x02, 0x06, 0xef, 0xd5, 0x45, 0x96, 0x30, 0x38, 0x00, + 0x54, 0x14, 0x6d, 0x00, 0x56, 0xf8, 0x74, 0x00, 0x54, 0x60, 0x27, 0x00, + 0x54, 0x60, 0x24, 0x10, 0xb4, 0x41, 0x05, 0x80, 0x02, 0xb4, 0x61, 0x00, + 0x56, 0xf8, 0x78, 0x00, 0xb0, 0x32, 0x70, 0x00, 0x94, 0x32, 0x59, 0x5e, + 0xf4, 0x45, 0x95, 0x0c, 0x42, 0x0e, 0xf4, 0x45, 0x82, 0x0c, 0x55, 0x96, + 0x16, 0x00, 0xbe, 0x41, 0x05, 0x80, 0xb7, 0x41, 0x10, 0x80, 0x72, 0x0e, + 0xde, 0x33, 0x61, 0x5e, 0xf7, 0x32, 0x3f, 0x1e, 0x92, 0x0c, 0xde, 0x45, + 0x5d, 0xf8, 0x10, 0x00, 0xf7, 0x45, 0x93, 0x0c, 0x44, 0x48, 0x42, 0x0e, + 0xf4, 0x45, 0x82, 0x0c, 0x55, 0xb6, 0xf4, 0xff, 0x72, 0x0e, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, 0x65, 0x48, 0x90, 0x0c, 0x56, 0xf8, + 0x50, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x76, 0xf8, 0x34, 0x00, 0xa3, 0x0c, + 0x36, 0xfa, 0x4c, 0x00, 0x42, 0x30, 0x19, 0xd3, 0xc2, 0x45, 0xd0, 0xfa, + 0x80, 0x00, 0x02, 0x69, 0xb6, 0x0c, 0x91, 0x0c, 0x22, 0xff, 0x90, 0x00, + 0x3d, 0x23, 0x18, 0x50, 0x99, 0x45, 0x21, 0x4c, 0x4a, 0x30, 0x1e, 0x00, + 0x24, 0x25, 0x56, 0x00, 0x50, 0x11, 0x21, 0xeb, 0x2b, 0xfd, 0x00, 0x00, + 0x40, 0x6e, 0x42, 0x4d, 0x49, 0xfc, 0x0c, 0x00, 0x44, 0x00, 0x50, 0x13, + 0x02, 0xb4, 0x49, 0xff, 0xe7, 0x30, 0x34, 0x00, 0x73, 0xcf, 0x00, 0x0c, + 0x9f, 0x45, 0x40, 0x30, 0xf0, 0xff, 0x12, 0x94, 0x22, 0xff, 0x21, 0xe8, + 0x56, 0x30, 0x7c, 0x00, 0xe2, 0x02, 0x50, 0xb9, 0x1c, 0xcf, 0xf6, 0xfa, + 0x10, 0x00, 0xb0, 0x32, 0x78, 0x00, 0x94, 0x32, 0x59, 0x5e, 0xf4, 0x45, + 0x95, 0x0c, 0xe2, 0x0e, 0xf4, 0x45, 0x82, 0x0c, 0xf5, 0x96, 0x10, 0x00, + 0xb7, 0x0c, 0xb7, 0x41, 0x10, 0x80, 0x42, 0x0e, 0xf7, 0x32, 0x0b, 0x13, + 0xa5, 0x30, 0x48, 0x00, 0xf7, 0x45, 0x91, 0x0c, 0xf4, 0x45, 0x92, 0x0c, + 0xb2, 0x0c, 0xb5, 0xb4, 0xf7, 0xff, 0x42, 0x0e, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0x30, 0x04, 0xe8, 0x02, 0xf8, 0x04, 0xe8, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0x18, 0x00, 0xe8, 0x9c, 0xcf, 0x32, 0xa8, 0x74, 0x14, 0x2b, 0x00, + 0x56, 0xfc, 0x00, 0x00, 0xb5, 0x41, 0x01, 0x80, 0xb4, 0x30, 0x2c, 0x00, + 0x62, 0x18, 0x20, 0x00, 0xd4, 0x14, 0x2b, 0x00, 0xb5, 0x32, 0xbd, 0xa4, + 0xd5, 0x45, 0x96, 0xfc, 0x00, 0x00, 0x01, 0xed, 0x5e, 0x94, 0x39, 0xff, + 0xb4, 0x30, 0x4d, 0x00, 0x74, 0x14, 0x4c, 0x00, 0x56, 0xfc, 0x00, 0x00, + 0x62, 0x18, 0x41, 0x00, 0x96, 0xfc, 0x00, 0x00, 0xd4, 0x14, 0x4c, 0x00, + 0xd5, 0x45, 0x84, 0x30, 0x21, 0x00, 0x54, 0x14, 0x70, 0x00, 0x74, 0x14, + 0x6f, 0x00, 0x20, 0x25, 0xd3, 0x44, 0xe2, 0x40, 0x2a, 0xff, 0x96, 0xfc, + 0x10, 0x00, 0xd2, 0x0c, 0xb4, 0x30, 0x71, 0x00, 0xd5, 0x45, 0x56, 0xfa, + 0x14, 0x00, 0x23, 0xcf, 0x76, 0x30, 0x24, 0x00, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0x15, 0x26, 0xe2, 0x45, 0x91, 0x0c, 0x80, 0xce, 0x54, 0x16, + 0x70, 0x00, 0x62, 0x02, 0x50, 0x11, 0xb1, 0xce, 0x56, 0xf8, 0x10, 0x00, + 0xe2, 0x40, 0xfb, 0xfe, 0x49, 0xfc, 0x0c, 0x00, 0x80, 0x87, 0xc2, 0x40, + 0xc6, 0xfe, 0x00, 0x0c, 0xa2, 0x4d, 0x68, 0x4d, 0xaf, 0xce, 0x82, 0x4d, + 0x21, 0x2d, 0xa2, 0x40, 0xf3, 0xff, 0xa2, 0x4d, 0x68, 0x4d, 0xa8, 0xce, + 0x82, 0x4d, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, + 0x99, 0xff, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0x01, 0xed, + 0x5c, 0x18, 0x58, 0x82, 0x06, 0x47, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0x60, 0x9b, 0x68, 0x45, 0x04, 0x0e, 0x25, 0x0e, + 0x14, 0x8d, 0x46, 0x0e, 0xa4, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x01, 0x80, + 0xf8, 0x6e, 0x06, 0xef, 0x84, 0x30, 0x04, 0xe8, 0x42, 0x30, 0xbd, 0xa4, + 0xc2, 0x45, 0xfd, 0xf8, 0x18, 0x00, 0xe6, 0x48, 0x81, 0xed, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0x18, 0x00, 0xe8, 0x51, 0x48, 0x52, 0x84, 0x45, 0xc8, + 0x50, 0x48, 0x44, 0xc8, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x6d, 0x9f, + 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0x28, 0x45, 0x0c, 0x47, 0x00, 0x0c, + 0x43, 0x29, 0xc2, 0x2b, 0x44, 0x2b, 0x60, 0x50, 0xff, 0xff, 0x97, 0x44, + 0x96, 0x44, 0x62, 0x94, 0x3c, 0x00, 0xa9, 0x41, 0x09, 0x80, 0x44, 0x09, + 0x21, 0x2d, 0x3f, 0x8d, 0x29, 0x31, 0x18, 0xe8, 0x49, 0xfc, 0x14, 0x00, + 0x20, 0x6d, 0x49, 0xf8, 0x14, 0x00, 0x40, 0x29, 0x88, 0xed, 0x42, 0xd0, + 0x0c, 0x00, 0x62, 0x94, 0x06, 0x00, 0x00, 0x0c, 0xb9, 0x41, 0x04, 0x80, + 0x39, 0x33, 0x09, 0xf6, 0xb9, 0x45, 0x45, 0x60, 0x17, 0x00, 0x45, 0x60, + 0x14, 0x10, 0x76, 0x8d, 0xc0, 0x0c, 0xe9, 0xfc, 0x24, 0x00, 0x64, 0x25, + 0x64, 0x05, 0x22, 0x25, 0x2a, 0x05, 0x62, 0x14, 0x41, 0x00, 0x02, 0x15, + 0x40, 0x00, 0x60, 0x6f, 0x30, 0x25, 0x02, 0x01, 0x90, 0x12, 0xae, 0x07, + 0xe9, 0xf8, 0x24, 0x00, 0x45, 0x60, 0x17, 0x00, 0x45, 0x60, 0x14, 0x10, + 0x46, 0x00, 0x90, 0x13, 0x6b, 0xad, 0x64, 0x25, 0xb9, 0x41, 0x04, 0x80, + 0x39, 0x33, 0x09, 0xf6, 0xb9, 0x45, 0x29, 0x31, 0x18, 0xe8, 0x49, 0xfc, + 0x18, 0x00, 0x20, 0x6d, 0xca, 0xcf, 0x49, 0xf8, 0x18, 0x00, 0x49, 0xfc, + 0x10, 0x00, 0x20, 0x6d, 0xc4, 0xcf, 0x49, 0xf8, 0x10, 0x00, 0x00, 0x0c, + 0x49, 0x29, 0x48, 0x2b, 0xca, 0x2a, 0x60, 0x50, 0xff, 0xff, 0x96, 0x44, + 0x95, 0x44, 0x62, 0x94, 0x21, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x44, 0x14, + 0x10, 0x00, 0x21, 0x2d, 0x11, 0xad, 0xa2, 0x41, 0x09, 0x80, 0x44, 0x09, + 0x21, 0x2d, 0x07, 0xad, 0xa3, 0x41, 0x09, 0x80, 0x43, 0xfc, 0x18, 0xe8, + 0x20, 0x6d, 0x43, 0xf8, 0x18, 0xe8, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, + 0x41, 0xe0, 0xb9, 0x45, 0x42, 0x30, 0x18, 0xe8, 0xa1, 0x69, 0xb9, 0x41, + 0x04, 0x80, 0x39, 0x33, 0x41, 0xe0, 0xb0, 0x6d, 0x99, 0x45, 0xa1, 0xe9, + 0x42, 0x30, 0x18, 0xe8, 0xa2, 0x69, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, + 0x41, 0xe0, 0xb0, 0x6d, 0x99, 0x45, 0xa2, 0xe9, 0xf1, 0x4f, 0x55, 0x45, + 0x04, 0x0e, 0x40, 0x6a, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x8f, 0x1c, + 0xc2, 0x45, 0x24, 0xfe, 0x70, 0x00, 0x08, 0xee, 0x90, 0x29, 0x63, 0xd0, + 0x0c, 0x00, 0x83, 0x94, 0x0a, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0x59, 0x70, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0x15, 0x45, + 0x08, 0x47, 0xe2, 0x40, 0xf5, 0xff, 0x02, 0x15, 0x28, 0x00, 0x08, 0x94, + 0xf1, 0xff, 0xa9, 0x41, 0x09, 0x80, 0x29, 0x31, 0x18, 0xe8, 0xc9, 0xfc, + 0x0c, 0x00, 0xa0, 0x0c, 0xd2, 0x25, 0xd6, 0x05, 0xb2, 0x25, 0xb4, 0x05, + 0x83, 0x14, 0x2a, 0x00, 0xe3, 0x14, 0x29, 0x00, 0xd0, 0x6e, 0xc0, 0x25, + 0xdf, 0x44, 0x05, 0xb5, 0xf3, 0xff, 0x3c, 0x07, 0xa2, 0x41, 0x04, 0x80, + 0x90, 0x0c, 0x42, 0x30, 0x59, 0x70, 0xc2, 0x45, 0xc9, 0xf8, 0x0c, 0x00, + 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0x55, 0x45, 0xa0, 0x30, 0xd0, 0x00, 0x24, 0x0e, 0x42, 0x30, + 0x51, 0x1e, 0xc2, 0x45, 0x80, 0x30, 0x93, 0x02, 0x02, 0x94, 0x78, 0x00, + 0x02, 0x0e, 0x02, 0x60, 0x0b, 0x80, 0x02, 0x60, 0x08, 0x90, 0x40, 0x30, + 0x93, 0x02, 0x50, 0x60, 0x03, 0x80, 0x50, 0x60, 0x00, 0x90, 0x01, 0xed, + 0x50, 0x60, 0x07, 0x80, 0x50, 0x60, 0x04, 0x90, 0x82, 0xed, 0x70, 0x60, + 0x0f, 0x80, 0xa4, 0x41, 0x09, 0x80, 0x70, 0x60, 0x0c, 0x90, 0x40, 0x30, + 0x87, 0x02, 0x84, 0xfc, 0xac, 0x9b, 0x50, 0x60, 0x13, 0x80, 0x50, 0x60, + 0x10, 0x90, 0x44, 0xfc, 0x84, 0x01, 0x62, 0x94, 0x37, 0x00, 0x83, 0xed, + 0x62, 0x94, 0x3e, 0x00, 0x84, 0xed, 0x62, 0x94, 0x46, 0x00, 0x00, 0x0c, + 0x0d, 0x8d, 0xa2, 0x41, 0x02, 0x80, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, + 0x93, 0x02, 0x42, 0x30, 0x4f, 0x23, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, + 0x15, 0x45, 0x08, 0x47, 0x42, 0x30, 0xd9, 0xf9, 0xe2, 0x45, 0x0a, 0x6e, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x8b, 0x1d, 0xc2, 0x45, 0x90, 0x30, + 0xb2, 0x00, 0xa2, 0x41, 0x10, 0x80, 0xb1, 0x0c, 0x42, 0x30, 0x79, 0x1d, + 0xc2, 0x45, 0x90, 0x30, 0x26, 0x00, 0xa5, 0x41, 0x09, 0x80, 0xa2, 0x41, + 0x01, 0x80, 0x30, 0xef, 0xa5, 0x30, 0x18, 0xe8, 0x42, 0x30, 0xbd, 0xa4, + 0xc2, 0x45, 0x90, 0x30, 0x63, 0x02, 0xd7, 0xcf, 0xa2, 0x41, 0x10, 0x80, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x8b, 0x1d, 0xc2, 0x45, 0x90, 0x30, + 0xb2, 0x00, 0xeb, 0xcf, 0xa5, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x10, 0x80, + 0xb1, 0x0c, 0x42, 0x30, 0x79, 0x1d, 0xc2, 0x45, 0x90, 0x30, 0x26, 0x00, + 0xc2, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0xd9, 0xf9, 0xe2, 0x45, 0x0a, 0x6e, 0xb9, 0xcf, 0xa2, 0x41, 0x10, 0x80, + 0xbd, 0xcf, 0x7f, 0xed, 0xf1, 0x4f, 0x64, 0x45, 0x04, 0x0e, 0x8c, 0x48, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x55, 0x14, 0x45, 0x0e, 0xe2, 0x45, + 0x26, 0x0e, 0x50, 0x60, 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0x50, 0x62, + 0x03, 0x80, 0x50, 0x62, 0x00, 0x90, 0x30, 0x62, 0x07, 0x80, 0x30, 0x62, + 0x04, 0x90, 0x24, 0x45, 0x08, 0x47, 0x00, 0x0c, 0xed, 0x4f, 0x66, 0x69, + 0xbd, 0x22, 0x10, 0xd0, 0x85, 0x0e, 0x42, 0xd0, 0x00, 0x01, 0x0e, 0xad, + 0x00, 0x0e, 0x44, 0xfc, 0x40, 0x00, 0x42, 0x00, 0x2c, 0x01, 0xe2, 0x40, + 0x35, 0x00, 0x46, 0x1c, 0x26, 0x00, 0x22, 0x24, 0x20, 0x04, 0x06, 0x24, + 0x20, 0x04, 0x04, 0x24, 0x74, 0x32, 0x78, 0x00, 0xb2, 0x41, 0x05, 0x80, + 0x52, 0x32, 0x59, 0x5e, 0xf2, 0x45, 0x93, 0x0c, 0x53, 0x94, 0x07, 0x00, + 0x00, 0x0c, 0x42, 0xfc, 0x6c, 0x00, 0x02, 0x02, 0x50, 0x83, 0x1b, 0x8c, + 0x7f, 0xed, 0xf2, 0x45, 0x93, 0x0c, 0x22, 0x0e, 0xf2, 0x45, 0x82, 0x0c, + 0x33, 0x96, 0x12, 0x00, 0x94, 0x32, 0x20, 0x01, 0xb1, 0x0c, 0xb1, 0x41, + 0x10, 0x80, 0x02, 0x0e, 0x31, 0x32, 0x0b, 0x13, 0xa5, 0x30, 0x48, 0x00, + 0xf1, 0x45, 0x94, 0x0c, 0xf2, 0x45, 0x90, 0x0c, 0xb0, 0x0c, 0xb3, 0xb4, + 0xf7, 0xff, 0x02, 0x0e, 0x40, 0x0c, 0xbd, 0x22, 0x10, 0x50, 0x0a, 0x47, + 0x04, 0xfe, 0x40, 0x00, 0x10, 0x02, 0xec, 0x00, 0x4f, 0x8c, 0x74, 0x32, + 0x78, 0x00, 0x66, 0x1c, 0x26, 0x00, 0x44, 0x1c, 0x64, 0x00, 0x32, 0x24, + 0x30, 0x04, 0x06, 0x24, 0x30, 0x04, 0x04, 0x24, 0x50, 0x00, 0x3c, 0xab, + 0x02, 0x00, 0x3c, 0x70, 0xbf, 0xcf, 0x50, 0x46, 0x44, 0x60, 0x27, 0x00, + 0x44, 0x60, 0x24, 0x10, 0x24, 0x2d, 0x05, 0x8d, 0x81, 0xed, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0x18, 0x4c, 0xe8, 0xb9, 0x41, 0x03, 0x80, 0x39, 0x33, + 0x09, 0xb5, 0xb9, 0x45, 0xf5, 0x4f, 0x44, 0x45, 0x05, 0xfe, 0xb0, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x24, 0x9b, 0x16, 0x8c, 0x40, 0x0c, + 0x45, 0x14, 0x0b, 0x01, 0x11, 0x8d, 0xa2, 0x41, 0x01, 0x80, 0x02, 0xef, + 0xa3, 0x30, 0x09, 0x00, 0x42, 0x30, 0xa1, 0xa4, 0xe2, 0x45, 0x90, 0x0c, + 0x07, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x4c, 0xe8, 0x05, 0x8d, + 0xa2, 0x41, 0x10, 0x80, 0x40, 0x0c, 0x04, 0x45, 0x06, 0x47, 0x88, 0x86, + 0x42, 0x30, 0x47, 0x22, 0xe2, 0x45, 0x00, 0x0c, 0x40, 0x0c, 0x04, 0x45, + 0x06, 0x47, 0x00, 0x0c, 0x35, 0x4f, 0x3d, 0x23, 0x70, 0xd1, 0xa4, 0xfe, + 0x34, 0x00, 0x15, 0x94, 0x10, 0x01, 0xe5, 0xfe, 0x70, 0x00, 0x45, 0xfc, + 0x48, 0x00, 0x42, 0xb0, 0x18, 0x00, 0x0e, 0xad, 0xc4, 0x0f, 0x57, 0x34, + 0x00, 0x00, 0x50, 0xee, 0x42, 0xd0, 0xfc, 0x00, 0x82, 0x94, 0x0a, 0x00, + 0x05, 0x0e, 0x80, 0x30, 0x80, 0x00, 0x82, 0x94, 0x29, 0x00, 0x00, 0x0c, + 0x3d, 0x23, 0x70, 0x51, 0x9f, 0x45, 0xcd, 0x4c, 0x5e, 0xfe, 0xa0, 0x06, + 0x9e, 0xfe, 0x84, 0x06, 0xf2, 0x40, 0x24, 0x01, 0x7e, 0xfe, 0x34, 0x06, + 0x5e, 0xfc, 0x88, 0x06, 0x13, 0x94, 0x03, 0x00, 0xa0, 0x0c, 0xb3, 0xfc, + 0x20, 0x00, 0xe2, 0x40, 0x51, 0x01, 0x2a, 0x69, 0x5d, 0xf8, 0x50, 0x01, + 0xd7, 0x32, 0x04, 0x00, 0xb1, 0x41, 0x04, 0x80, 0xd6, 0x0c, 0x31, 0x32, + 0xe1, 0x9c, 0xf1, 0x45, 0x92, 0x0c, 0x02, 0x94, 0xde, 0x00, 0xbd, 0xfc, + 0x50, 0x01, 0x0b, 0xcc, 0x9e, 0xfc, 0x34, 0x00, 0x5e, 0xfe, 0xa0, 0x06, + 0x5e, 0xfc, 0x84, 0x06, 0xf2, 0x40, 0xfc, 0x00, 0x7e, 0xfe, 0x34, 0x06, + 0x95, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xf5, 0x16, 0xc2, 0x45, + 0xb0, 0x34, 0x30, 0x00, 0x47, 0x8d, 0xc2, 0x0e, 0x22, 0x69, 0x21, 0x2d, + 0x43, 0xad, 0x0a, 0x6d, 0xf5, 0xfc, 0x60, 0xff, 0x5d, 0xf8, 0x50, 0x01, + 0x71, 0x69, 0xe2, 0x40, 0x74, 0x00, 0x70, 0x69, 0x42, 0x14, 0x20, 0x00, + 0x02, 0x94, 0xbf, 0x00, 0x57, 0x30, 0x24, 0x00, 0x22, 0x0e, 0xa2, 0x41, + 0x10, 0x80, 0x82, 0x84, 0x24, 0xef, 0x80, 0x0c, 0x42, 0x30, 0xf7, 0x11, + 0x04, 0xc8, 0x05, 0xc8, 0xc2, 0x45, 0x3d, 0xfa, 0x68, 0x01, 0xaa, 0x41, + 0x09, 0x80, 0x82, 0x0e, 0x4a, 0x30, 0x60, 0x9b, 0x25, 0xe8, 0x26, 0xe8, + 0x27, 0xe8, 0x28, 0xe8, 0x29, 0xe8, 0x2a, 0xe8, 0x2b, 0xe8, 0x2c, 0xe8, + 0x2d, 0xe8, 0xb0, 0xfc, 0x48, 0x00, 0x97, 0x30, 0x10, 0x00, 0x00, 0x85, + 0x0a, 0xf8, 0x60, 0x9b, 0xdd, 0x20, 0x10, 0x90, 0x87, 0xc8, 0x88, 0xc8, + 0x06, 0xc8, 0x24, 0xe8, 0x23, 0xe8, 0x22, 0xe8, 0x21, 0xe8, 0xa2, 0x41, + 0x10, 0x80, 0x95, 0x6f, 0xa5, 0x30, 0xdc, 0xff, 0x42, 0x30, 0x7d, 0x1c, + 0xe2, 0x45, 0x91, 0x0c, 0xf5, 0xfc, 0x60, 0xff, 0x47, 0xfd, 0x04, 0x00, + 0x8a, 0x40, 0xac, 0x00, 0x54, 0x30, 0x02, 0x00, 0x5d, 0xf8, 0x60, 0x01, + 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xa1, 0xa4, 0x20, 0x0e, 0x87, 0xfd, + 0x00, 0x00, 0x09, 0xcc, 0x5d, 0xf8, 0x64, 0x01, 0x90, 0x6c, 0x9d, 0x2c, + 0x51, 0x01, 0x50, 0x13, 0x02, 0x94, 0x99, 0x00, 0x4e, 0x48, 0x9a, 0x26, + 0x9a, 0x06, 0xac, 0x00, 0x50, 0x29, 0x45, 0x14, 0x20, 0x00, 0xe2, 0x40, + 0xf1, 0xff, 0xd4, 0x14, 0x01, 0x00, 0x46, 0xb4, 0xed, 0xff, 0x9d, 0xfc, + 0x60, 0x01, 0x5d, 0xfc, 0x64, 0x01, 0x5d, 0xf9, 0x54, 0x01, 0x9d, 0xf9, + 0x58, 0x01, 0xc2, 0x45, 0xfd, 0xf8, 0x5c, 0x01, 0x5d, 0xfd, 0x54, 0x01, + 0x9d, 0xfd, 0x58, 0x01, 0x5d, 0xad, 0xfd, 0xfc, 0x5c, 0x01, 0x53, 0xfc, + 0x78, 0x00, 0xe2, 0x40, 0x51, 0x00, 0x70, 0x69, 0x42, 0x14, 0x20, 0x00, + 0x1c, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x47, 0x34, 0x38, 0x00, 0xa7, 0x34, + 0x3a, 0x00, 0x87, 0x34, 0x3c, 0x00, 0xd5, 0x44, 0xd4, 0x44, 0x2f, 0x2d, + 0x02, 0x94, 0x90, 0x00, 0x04, 0xed, 0xa2, 0x41, 0x01, 0x80, 0x06, 0xef, + 0xa7, 0x30, 0x38, 0x00, 0x42, 0x30, 0xa1, 0xa4, 0xc2, 0x45, 0x97, 0x30, + 0x10, 0x00, 0x02, 0xb4, 0x25, 0xff, 0xa2, 0x41, 0x09, 0x80, 0x97, 0x0c, + 0x42, 0x30, 0x85, 0xcd, 0xe2, 0x45, 0x95, 0x6e, 0xf0, 0xfc, 0x48, 0x00, + 0xbd, 0xfc, 0x50, 0x01, 0xa2, 0x41, 0x10, 0x80, 0xd7, 0x0c, 0x9e, 0x0c, + 0x42, 0x30, 0x7b, 0x15, 0xc4, 0xca, 0xc2, 0x45, 0x1d, 0xf8, 0x14, 0x00, + 0xe2, 0x40, 0x0e, 0xff, 0xa2, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x5f, 0x19, 0xe2, 0x45, 0x9e, 0x0c, 0x06, 0xcf, 0x00, 0x0c, 0x5c, 0xfc, + 0xe4, 0x81, 0x20, 0x6d, 0xee, 0xce, 0x5c, 0xf8, 0xe4, 0x81, 0xd6, 0x0c, + 0xf1, 0x45, 0x94, 0x0c, 0xe2, 0x40, 0xfa, 0xfe, 0x2a, 0xcf, 0x9e, 0xfc, + 0x34, 0x00, 0x53, 0xfc, 0x78, 0x00, 0x51, 0xad, 0xa2, 0x41, 0x09, 0x80, + 0xf0, 0xfc, 0x48, 0x00, 0xbd, 0xfc, 0x50, 0x01, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x41, 0x25, 0xd7, 0x0c, 0x9e, 0x0c, 0xc2, 0x45, 0xdd, 0xfa, + 0x10, 0x00, 0x57, 0x34, 0x22, 0x00, 0x21, 0x2d, 0x02, 0x94, 0xe0, 0xfe, + 0xa2, 0x41, 0x10, 0x80, 0x20, 0xef, 0xb6, 0x0c, 0x42, 0x30, 0x41, 0x22, + 0xe2, 0x45, 0x95, 0x0c, 0xd7, 0xce, 0x00, 0x0c, 0xa2, 0x40, 0x02, 0xff, + 0xd3, 0xce, 0x00, 0x0c, 0xf4, 0x40, 0xd0, 0xfe, 0xd9, 0xce, 0x00, 0x0c, + 0x4e, 0x48, 0xe2, 0x40, 0xcb, 0xfe, 0x22, 0x09, 0x2c, 0x2d, 0x02, 0x94, + 0xc7, 0xfe, 0x5d, 0xfc, 0x20, 0x01, 0x02, 0x94, 0xc3, 0xfe, 0x15, 0x6d, + 0xf0, 0xfc, 0x48, 0x00, 0xbd, 0xfc, 0x68, 0x01, 0x44, 0xc8, 0xa2, 0x41, + 0x10, 0x80, 0xd7, 0x0c, 0x95, 0x30, 0xe0, 0xfe, 0x42, 0x30, 0x1d, 0x13, + 0xc2, 0x45, 0xe7, 0x30, 0xdc, 0xff, 0x02, 0x94, 0xb1, 0xfe, 0xdd, 0xfc, + 0x50, 0x01, 0xa2, 0x41, 0x09, 0x80, 0xf7, 0x0c, 0xb2, 0x0c, 0x9e, 0x0c, + 0x04, 0xca, 0x42, 0x30, 0x81, 0xc9, 0xc2, 0x45, 0xdd, 0xfa, 0x14, 0x00, + 0xa3, 0xce, 0x00, 0x0c, 0x75, 0xfc, 0x6c, 0xff, 0x43, 0xb4, 0x7b, 0xff, + 0xa2, 0x41, 0x09, 0x80, 0x9b, 0xce, 0x00, 0x0c, 0xb1, 0xce, 0x1d, 0xf8, + 0x50, 0x01, 0x00, 0x0c, 0xe5, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0xdd, 0x22, + 0x1c, 0xd0, 0x46, 0x32, 0x2c, 0x00, 0x24, 0x0e, 0x85, 0x0e, 0x92, 0x0c, + 0x42, 0x30, 0x0b, 0x1f, 0x66, 0x0e, 0xc2, 0x45, 0xb4, 0x32, 0x58, 0x00, + 0xa2, 0x41, 0x05, 0x80, 0xff, 0xee, 0x42, 0x30, 0xf1, 0x4b, 0xe2, 0x45, + 0x95, 0x0c, 0x11, 0x62, 0x27, 0x00, 0x11, 0x62, 0x24, 0x10, 0x35, 0xac, + 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0x41, 0x5e, 0xc2, 0x45, 0x94, 0x30, + 0x70, 0x00, 0x3e, 0x8d, 0xa2, 0x41, 0x03, 0x80, 0x40, 0x30, 0x45, 0x02, + 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x89, 0x6e, 0x42, 0x30, 0xb7, 0x24, + 0xe2, 0x45, 0x02, 0xee, 0x38, 0x8d, 0x22, 0x0e, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x55, 0x14, 0xe2, 0x45, 0x7d, 0xee, 0x51, 0x60, 0x0b, 0x80, + 0x51, 0x60, 0x08, 0x90, 0x11, 0x60, 0x07, 0x80, 0xa2, 0x41, 0x03, 0x80, + 0xe2, 0x86, 0x42, 0x30, 0x85, 0xbc, 0xc2, 0x45, 0x11, 0x60, 0x04, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, 0x45, 0x02, 0x42, 0x30, 0x19, 0x1d, + 0xe2, 0x45, 0x91, 0x0c, 0x05, 0xcc, 0xa2, 0x41, 0x05, 0x80, 0x00, 0x0e, + 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xf9, 0x4b, 0xe2, 0x45, 0x95, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x1d, 0x1f, 0xe2, 0x45, 0x92, 0x0c, + 0x50, 0x0c, 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, 0x6e, 0x84, 0x42, 0x30, + 0x29, 0xc0, 0xe2, 0x45, 0x91, 0x0c, 0xea, 0xcf, 0x02, 0x0e, 0xf4, 0xcf, + 0x00, 0x32, 0x97, 0xff, 0x01, 0xed, 0x45, 0x94, 0x0e, 0x00, 0x06, 0xed, + 0x45, 0x94, 0x0e, 0x00, 0x07, 0xed, 0x08, 0xed, 0x45, 0x94, 0x03, 0x00, + 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, 0x04, 0xed, 0x4e, 0xe9, 0x9f, 0x45, + 0x40, 0x0c, 0x4e, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x4e, 0xe9, 0x9f, 0x45, + 0x40, 0x0c, 0x00, 0x0c, 0x55, 0x09, 0x82, 0xed, 0x62, 0x94, 0x09, 0x00, + 0x62, 0xb0, 0x03, 0x00, 0x03, 0xb4, 0x46, 0x00, 0x84, 0xed, 0x62, 0xb4, + 0x22, 0x00, 0x85, 0xed, 0x03, 0xed, 0x4e, 0xe9, 0x56, 0x09, 0x01, 0xef, + 0x44, 0x4c, 0x24, 0x25, 0x2d, 0x2d, 0xaa, 0x05, 0xb0, 0x09, 0x44, 0x4c, + 0xb4, 0x25, 0x26, 0x05, 0x2d, 0x2d, 0xaa, 0x06, 0xdf, 0x09, 0x04, 0x18, + 0x49, 0x00, 0x50, 0x09, 0x2d, 0x25, 0x44, 0x18, 0x49, 0x00, 0xc3, 0x94, + 0x25, 0x00, 0x06, 0xed, 0x43, 0x94, 0x2e, 0x00, 0x07, 0xed, 0x08, 0xed, + 0x43, 0x94, 0x21, 0x00, 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, 0x62, 0xb4, + 0x23, 0x00, 0x00, 0x0c, 0x01, 0xed, 0x4e, 0xe9, 0x56, 0x09, 0x01, 0xef, + 0x44, 0x4c, 0x24, 0x25, 0x2d, 0x2d, 0xaa, 0x05, 0xb0, 0x09, 0x44, 0x4c, + 0xb4, 0x25, 0x26, 0x05, 0x2d, 0x2d, 0xaa, 0x06, 0xdf, 0x09, 0x04, 0x18, + 0x49, 0x00, 0x50, 0x09, 0x2d, 0x25, 0x44, 0x18, 0x49, 0x00, 0xc3, 0xb4, + 0xdd, 0xff, 0x06, 0xed, 0x4e, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x04, 0xed, + 0xfc, 0xcf, 0x4e, 0xe9, 0x81, 0xed, 0x62, 0x94, 0xdf, 0xff, 0x00, 0x0c, + 0xbb, 0xcf, 0x4e, 0xe8, 0x4e, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, + 0xe5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xf1, 0xa5, 0x3d, 0x23, + 0x10, 0xd0, 0xc2, 0x45, 0xb7, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0xb8, 0xe7, 0xa2, 0x41, 0x00, 0xb0, 0x62, 0xf8, 0xdc, 0x4f, + 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0xbc, 0xe7, 0x62, 0xf8, 0xd8, 0x4f, + 0x57, 0xfc, 0x58, 0xbf, 0x02, 0x94, 0xa3, 0x00, 0xb1, 0x41, 0x05, 0x80, + 0xa4, 0x41, 0x09, 0x80, 0x31, 0x32, 0xe9, 0x4b, 0xd1, 0x45, 0x84, 0x30, + 0xc4, 0x9b, 0x17, 0xfe, 0x58, 0xbf, 0xb4, 0x41, 0x05, 0x80, 0x94, 0x32, + 0x59, 0x5e, 0xd1, 0x45, 0x90, 0x30, 0x3c, 0x00, 0xd1, 0x45, 0x90, 0x30, + 0x58, 0x00, 0xd1, 0x45, 0x90, 0x30, 0x64, 0x00, 0x97, 0xfc, 0x58, 0xbf, + 0xd4, 0x45, 0x84, 0x30, 0x20, 0x02, 0xa2, 0x0e, 0x57, 0xfc, 0x58, 0xbf, + 0x42, 0x30, 0x20, 0x02, 0x55, 0x94, 0x7f, 0x00, 0xb6, 0x41, 0x10, 0x80, + 0xd6, 0x32, 0x17, 0x1f, 0x40, 0x32, 0x10, 0x00, 0xd1, 0x45, 0x95, 0x30, + 0x20, 0x00, 0xd1, 0x45, 0x95, 0x30, 0x2c, 0x00, 0xd1, 0x45, 0x95, 0x30, + 0x8c, 0x00, 0xd5, 0xff, 0x10, 0x00, 0xd1, 0x45, 0x9e, 0x30, 0xb8, 0x00, + 0x7e, 0xfe, 0x50, 0x02, 0xd1, 0x45, 0x93, 0x30, 0xf4, 0x03, 0xd1, 0x45, + 0x93, 0x30, 0x60, 0x04, 0xd1, 0x45, 0x93, 0x30, 0x54, 0x04, 0xd1, 0x45, + 0x93, 0x30, 0xe4, 0x05, 0xd1, 0x45, 0x93, 0x30, 0xf0, 0x05, 0xd1, 0x45, + 0x93, 0x30, 0xfc, 0x05, 0xd1, 0x45, 0x93, 0x30, 0xc8, 0x06, 0xd1, 0x45, + 0x93, 0x30, 0xb4, 0x07, 0x13, 0xfe, 0x3c, 0x00, 0x73, 0x32, 0x70, 0x04, + 0xf1, 0x45, 0x0c, 0x6e, 0xd1, 0x45, 0x90, 0x30, 0x90, 0x0c, 0xd1, 0x45, + 0x90, 0x30, 0x78, 0x0c, 0xd1, 0x45, 0x90, 0x30, 0x84, 0x0c, 0x90, 0x30, + 0x3c, 0x0b, 0xf6, 0x45, 0xa0, 0x0c, 0x90, 0x30, 0x30, 0x0b, 0xf6, 0x45, + 0xa0, 0x0c, 0x90, 0x30, 0x18, 0x0b, 0xf6, 0x45, 0xa0, 0x0c, 0xa0, 0x0c, + 0xd6, 0x45, 0x90, 0x30, 0x24, 0x0b, 0xd1, 0x45, 0x9e, 0x30, 0x98, 0x06, + 0xf4, 0x45, 0x93, 0x0c, 0x53, 0x94, 0x21, 0x00, 0x02, 0x0e, 0xd1, 0x45, + 0x90, 0x30, 0x54, 0x00, 0xd1, 0x45, 0x90, 0x30, 0x60, 0x00, 0xd1, 0x45, + 0x90, 0x30, 0x7c, 0x00, 0xd1, 0x45, 0x90, 0x30, 0xac, 0x04, 0xc0, 0x0f, + 0x5e, 0x30, 0x2c, 0x01, 0x24, 0x25, 0x20, 0x05, 0x22, 0x69, 0xc2, 0x4f, + 0x03, 0x8d, 0x24, 0x6e, 0xf1, 0x45, 0x00, 0x0c, 0x5e, 0xb6, 0xf6, 0xff, + 0x5e, 0x30, 0x2c, 0x01, 0xf4, 0x45, 0x90, 0x0c, 0x53, 0xb4, 0xe1, 0xff, + 0x02, 0x0e, 0xf4, 0x45, 0x95, 0x0c, 0xa2, 0x0e, 0x57, 0xfc, 0x58, 0xbf, + 0x42, 0x30, 0x20, 0x02, 0x55, 0xb4, 0x88, 0xff, 0x00, 0x0c, 0x3d, 0x23, + 0x10, 0x50, 0x0e, 0x47, 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, + 0x30, 0xea, 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, + 0xfc, 0xff, 0x34, 0x69, 0xbf, 0x45, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0x7d, 0xa4, 0xe9, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xa6, 0x41, 0x01, 0xa4, 0xc6, 0x50, 0x10, 0xb8, 0x89, 0x6e, 0x40, 0xee, + 0x66, 0x30, 0xf4, 0xff, 0xc4, 0xef, 0x60, 0xea, 0x30, 0x69, 0x22, 0x2d, + 0xe2, 0x40, 0xfc, 0xff, 0x34, 0x69, 0x40, 0x6e, 0x50, 0xe9, 0xe4, 0xb4, + 0xf6, 0xff, 0xd2, 0x6e, 0x44, 0x48, 0xff, 0xed, 0x62, 0x94, 0x58, 0x00, + 0x00, 0x0c, 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, 0x55, 0xed, + 0x30, 0xe9, 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, + 0xfc, 0xff, 0xb4, 0x69, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xf8, 0xb8, 0xe7, + 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, 0x1d, 0xed, 0x30, 0xe9, + 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0x7d, 0x8d, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0x5c, 0xbf, 0x34, 0x6b, 0x2f, 0x6a, 0xa3, 0x41, + 0xfa, 0x50, 0xa5, 0x41, 0x09, 0x80, 0x63, 0x30, 0xfa, 0x50, 0x64, 0x94, + 0x03, 0x00, 0xc5, 0xf8, 0xbc, 0xe7, 0x2f, 0xe8, 0xa3, 0x41, 0x01, 0xa4, + 0x63, 0x50, 0x10, 0xb8, 0x56, 0xed, 0x30, 0xe9, 0x63, 0x30, 0xf4, 0xff, + 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0xfc, 0xff, 0xb4, 0x69, 0xa6, 0x41, + 0x01, 0xa4, 0xc6, 0x50, 0x10, 0xb8, 0xa2, 0x41, 0x09, 0x80, 0xa5, 0x41, + 0x09, 0x80, 0x62, 0xf8, 0xc0, 0xe7, 0xa5, 0x30, 0xc4, 0xe7, 0x57, 0xee, + 0x66, 0x30, 0xf4, 0xff, 0xe6, 0xef, 0x60, 0xea, 0x30, 0x69, 0x22, 0x2d, + 0xe2, 0x40, 0xfc, 0xff, 0x34, 0x69, 0x40, 0x6e, 0x50, 0xe9, 0xe4, 0xb4, + 0xf6, 0xff, 0xd2, 0x6e, 0xe9, 0x4b, 0x0a, 0x47, 0x85, 0x48, 0x44, 0xb4, + 0xa8, 0xff, 0xa3, 0x41, 0x01, 0xa4, 0x66, 0x48, 0x83, 0xb4, 0xa1, 0xff, + 0x47, 0x48, 0x62, 0xb4, 0xa0, 0xff, 0xa3, 0x41, 0x01, 0xa4, 0xa3, 0x41, + 0x09, 0x80, 0xaa, 0xcf, 0x43, 0xf8, 0xb8, 0xe7, 0x84, 0x30, 0xcc, 0xff, + 0x64, 0xb0, 0x06, 0x00, 0x87, 0x8d, 0x7f, 0xed, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x88, 0xe7, 0x82, 0x00, 0x18, 0x11, 0xbf, 0x45, 0x00, 0x0c, + 0xb9, 0x41, 0x10, 0x80, 0x39, 0x33, 0x47, 0x22, 0x99, 0x45, 0xa0, 0x0c, + 0xed, 0x4f, 0x57, 0x45, 0x04, 0x0e, 0x44, 0x34, 0x24, 0x00, 0x84, 0x34, + 0x26, 0x00, 0x70, 0x34, 0x28, 0x00, 0xd4, 0x44, 0xd3, 0x44, 0x2f, 0x2d, + 0x14, 0xad, 0xa5, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x04, 0x80, 0x06, 0xef, + 0xa5, 0x30, 0x78, 0xe7, 0x42, 0x30, 0x31, 0x26, 0xe2, 0x45, 0x09, 0x6e, + 0xa2, 0x41, 0x01, 0x80, 0x06, 0xef, 0x89, 0x6e, 0x42, 0x30, 0xbd, 0xa4, + 0xc2, 0x45, 0x90, 0x30, 0x24, 0x00, 0x50, 0x60, 0x34, 0x01, 0xa3, 0x41, + 0x09, 0x80, 0x50, 0x60, 0x31, 0x11, 0x43, 0xf8, 0xb4, 0xe7, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x09, 0xf6, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x90, 0x30, 0x2f, 0x01, 0x42, 0x30, 0x47, 0x22, 0xe2, 0x45, + 0xa0, 0x0c, 0x30, 0x16, 0x35, 0x01, 0x30, 0x17, 0x36, 0x01, 0x10, 0x17, + 0x37, 0x01, 0xa2, 0x41, 0x09, 0x80, 0xf0, 0x15, 0x38, 0x01, 0x22, 0x1a, + 0xa4, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xd0, 0x15, 0x39, 0x01, 0x22, 0x1b, + 0xa5, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xb0, 0x15, 0x3a, 0x01, 0x02, 0x1b, + 0xa6, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x90, 0x15, 0x3b, 0x01, 0xe2, 0x19, + 0xa7, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x70, 0x15, 0x3c, 0x01, 0xc2, 0x19, + 0xa8, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x50, 0x15, 0x3d, 0x01, 0xa2, 0x19, + 0xa9, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x30, 0x15, 0x3e, 0x01, 0x82, 0x19, + 0xaa, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x10, 0x15, 0x3f, 0x01, 0x62, 0x19, + 0xab, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xf0, 0x14, 0x40, 0x01, 0x42, 0x19, + 0xac, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xd0, 0x14, 0x41, 0x01, 0x22, 0x19, + 0xad, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xb0, 0x14, 0x42, 0x01, 0x02, 0x19, + 0xae, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x90, 0x14, 0x43, 0x01, 0xe2, 0x18, + 0xaf, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x70, 0x14, 0x44, 0x01, 0xc2, 0x18, + 0xb0, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x18, 0xb1, 0xe7, 0xa2, 0x41, + 0x09, 0x80, 0x82, 0x18, 0xb2, 0xe7, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x18, + 0xb3, 0xe7, 0x40, 0x0c, 0x17, 0x45, 0x0a, 0x47, 0x64, 0xfc, 0x40, 0x00, + 0x02, 0xed, 0x43, 0x94, 0x09, 0x00, 0x00, 0x0c, 0x83, 0xee, 0xa3, 0x94, + 0x02, 0x00, 0x40, 0x0c, 0xbf, 0x45, 0x9f, 0x45, 0x44, 0x14, 0x44, 0x00, + 0x9f, 0x45, 0x44, 0xfc, 0x44, 0x00, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, + 0x05, 0x80, 0xdd, 0x22, 0x14, 0xd0, 0x04, 0x32, 0x70, 0x00, 0x90, 0x0c, + 0x42, 0x30, 0x41, 0x5e, 0xe2, 0x45, 0xa5, 0x0e, 0x02, 0xb4, 0x4d, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xe5, 0xe6, 0xe2, 0x45, 0x90, 0x0c, + 0x82, 0xfc, 0x40, 0x00, 0x82, 0xed, 0x64, 0x94, 0x58, 0x00, 0x83, 0xee, + 0xa4, 0x94, 0x63, 0x00, 0x60, 0x0c, 0x55, 0xfc, 0x40, 0x00, 0x02, 0xee, + 0x82, 0x94, 0x57, 0x00, 0x03, 0xee, 0x82, 0x94, 0x57, 0x00, 0x20, 0x0e, + 0x23, 0x02, 0x50, 0x1b, 0xbd, 0x8d, 0xb2, 0x41, 0x05, 0x80, 0x52, 0x32, + 0x59, 0x5e, 0xf2, 0x45, 0x90, 0x0c, 0x60, 0x32, 0x02, 0x00, 0x50, 0xb4, + 0x10, 0x00, 0x80, 0x32, 0x03, 0x00, 0x1f, 0xcc, 0x40, 0x0c, 0x84, 0x96, + 0x1f, 0x00, 0x00, 0x0c, 0x71, 0x00, 0x50, 0x1b, 0x91, 0x8d, 0x82, 0x0c, + 0xf2, 0x45, 0x00, 0x0c, 0x50, 0x94, 0x12, 0x00, 0x00, 0x0c, 0x82, 0xfc, + 0x40, 0x00, 0x64, 0xb6, 0xf0, 0xff, 0x60, 0x0c, 0x62, 0xfc, 0x44, 0x00, + 0x71, 0x00, 0x50, 0x1b, 0xf1, 0xad, 0x82, 0x0c, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0x71, 0x5e, 0xe2, 0x45, 0xb5, 0x0c, 0x40, 0x0c, 0xdd, 0x22, + 0x14, 0x50, 0x0c, 0x47, 0xe1, 0xcf, 0x62, 0x14, 0x44, 0x00, 0xa2, 0x41, + 0x05, 0x80, 0xb5, 0x0c, 0x42, 0x30, 0x7d, 0x5e, 0xe2, 0x45, 0x90, 0x0c, + 0x40, 0x0c, 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0xa2, 0x41, 0x05, 0x80, + 0xb5, 0x0c, 0x42, 0x30, 0x31, 0x5e, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, + 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0x62, 0xfc, 0x44, 0x00, 0x55, 0xfc, + 0x40, 0x00, 0x02, 0xee, 0x82, 0xb4, 0xab, 0xff, 0x03, 0xee, 0xac, 0xcf, + 0x35, 0xfe, 0x44, 0x00, 0xa9, 0xcf, 0x35, 0x16, 0x44, 0x00, 0x9d, 0xcf, + 0x62, 0x14, 0x44, 0x00, 0x3d, 0x4f, 0x3d, 0x23, 0x60, 0xd1, 0x44, 0xfe, + 0x34, 0x00, 0x47, 0x30, 0xdc, 0xff, 0x27, 0x0e, 0x5d, 0xf8, 0x50, 0x01, + 0x9d, 0x20, 0x88, 0x91, 0x12, 0x94, 0x58, 0x01, 0xdd, 0xf8, 0x90, 0x01, + 0x5d, 0xfc, 0x8c, 0x01, 0xa4, 0x41, 0x00, 0x1c, 0xa3, 0x41, 0x00, 0x04, + 0x27, 0x69, 0x94, 0x44, 0x62, 0x94, 0x1b, 0x01, 0xa3, 0x41, 0x00, 0xf8, + 0x34, 0x05, 0x42, 0xb0, 0x01, 0x00, 0x7d, 0xfc, 0x90, 0x01, 0xfd, 0xfc, + 0x98, 0x01, 0x44, 0xc8, 0x63, 0x30, 0x24, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0xa3, 0x0c, 0xd1, 0x30, 0xdc, 0xff, 0x92, 0x0c, 0x42, 0x30, 0x03, 0x12, + 0xc2, 0x45, 0x7d, 0xf8, 0x54, 0x01, 0x02, 0x0e, 0x52, 0xfc, 0x60, 0xff, + 0xa2, 0x6a, 0xe5, 0x40, 0x11, 0x00, 0x62, 0xfc, 0x7c, 0x00, 0x03, 0x96, + 0x11, 0x00, 0x42, 0x30, 0x80, 0x00, 0x06, 0xcc, 0x60, 0x0c, 0x82, 0xfc, + 0xfc, 0xff, 0x90, 0x94, 0x09, 0x00, 0x00, 0x0c, 0xb0, 0x6d, 0x65, 0xb4, + 0xf8, 0xff, 0x22, 0x6d, 0x3d, 0x23, 0x60, 0x51, 0x9f, 0x45, 0xc5, 0x4c, + 0x31, 0xb2, 0x24, 0x00, 0xf9, 0xac, 0xd2, 0x32, 0x50, 0xff, 0xb3, 0x41, + 0x05, 0x80, 0x73, 0x32, 0x59, 0x5e, 0xf3, 0x45, 0x96, 0x0c, 0xc2, 0x0f, + 0x5d, 0xfc, 0x90, 0x01, 0xd6, 0x97, 0xdb, 0x00, 0x82, 0x32, 0x10, 0x00, + 0xb5, 0x41, 0x01, 0x80, 0xfe, 0x0e, 0x08, 0xcc, 0xb5, 0x32, 0xa1, 0xa4, + 0xf3, 0x45, 0x00, 0x0c, 0xc2, 0x0f, 0x56, 0x94, 0xce, 0x00, 0xe2, 0x0e, + 0x3e, 0x32, 0x29, 0x00, 0x94, 0x0c, 0x06, 0xef, 0xf5, 0x45, 0xb1, 0x0c, + 0x22, 0x0d, 0x72, 0xad, 0x9e, 0x0c, 0x60, 0x32, 0x01, 0x00, 0xb5, 0x41, + 0x01, 0x80, 0xf2, 0x86, 0x06, 0xef, 0xb5, 0x32, 0xbd, 0xa4, 0xd5, 0x45, + 0x3d, 0xf9, 0x58, 0x01, 0x60, 0x0c, 0x40, 0x0c, 0xbd, 0xfc, 0x50, 0x01, + 0x9d, 0xfc, 0x54, 0x01, 0x5d, 0x20, 0x10, 0x90, 0xa2, 0x41, 0x10, 0x80, + 0x95, 0x6f, 0xc0, 0x0c, 0x06, 0xc8, 0x87, 0xca, 0x42, 0x30, 0x7d, 0x1c, + 0xc2, 0x45, 0x3d, 0xfa, 0x20, 0x00, 0xdd, 0x14, 0x25, 0x01, 0xaf, 0x48, + 0xd5, 0x45, 0x97, 0x30, 0x09, 0x00, 0x5d, 0x14, 0x25, 0x01, 0x57, 0x18, + 0x08, 0x00, 0x00, 0x69, 0x57, 0x60, 0x32, 0x80, 0x57, 0x60, 0x2f, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe9, 0x16, 0xe2, 0x45, 0x01, 0x6a, + 0x57, 0x60, 0x36, 0x80, 0x62, 0xb0, 0x24, 0x00, 0x57, 0x60, 0x33, 0x90, + 0x03, 0xb4, 0xb3, 0x00, 0x3d, 0xfd, 0x58, 0x01, 0x01, 0xed, 0x57, 0x18, + 0x37, 0x00, 0x01, 0xed, 0x17, 0xf8, 0x38, 0x00, 0x7e, 0x48, 0x03, 0x94, + 0xfb, 0x00, 0x7f, 0x48, 0x42, 0x50, 0x20, 0x00, 0x57, 0x18, 0x37, 0x00, + 0x7e, 0x48, 0xb0, 0x09, 0xb4, 0x2d, 0x85, 0x8d, 0x7b, 0x48, 0x81, 0xed, + 0x77, 0x18, 0x48, 0x00, 0x7b, 0x48, 0x03, 0x94, 0xd6, 0x00, 0x7c, 0x48, + 0x42, 0x50, 0x10, 0x00, 0x57, 0x18, 0x37, 0x00, 0x79, 0x48, 0x03, 0x94, + 0xc7, 0x00, 0x7a, 0x48, 0x42, 0x50, 0x08, 0x00, 0x57, 0x18, 0x37, 0x00, + 0x7d, 0xfc, 0x90, 0x01, 0x63, 0x34, 0x20, 0x00, 0x77, 0x38, 0x3c, 0x00, + 0x7d, 0xfc, 0x90, 0x01, 0x63, 0x34, 0x22, 0x00, 0x77, 0x38, 0x3e, 0x00, + 0x84, 0xed, 0x62, 0x94, 0x87, 0x00, 0x81, 0xed, 0x62, 0x94, 0x84, 0x00, + 0x00, 0x0c, 0xb4, 0x48, 0x05, 0x94, 0x8f, 0x00, 0xdd, 0x14, 0x29, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0x97, 0x0c, 0x42, 0x30, 0x09, 0x21, 0xc2, 0x45, + 0x3d, 0xf9, 0x58, 0x01, 0x3d, 0xfd, 0x58, 0x01, 0x5d, 0xfc, 0x14, 0x01, + 0x03, 0x8d, 0x05, 0xed, 0x57, 0xf8, 0x38, 0x00, 0xb3, 0x40, 0x48, 0xff, + 0x52, 0xfc, 0x3c, 0x00, 0x81, 0xed, 0x62, 0x94, 0x8d, 0x00, 0x82, 0xed, + 0x62, 0xb4, 0x07, 0x00, 0x4e, 0x48, 0x03, 0xed, 0x57, 0xf8, 0x40, 0x00, + 0x37, 0x19, 0x44, 0x00, 0x4e, 0x48, 0x1a, 0x8d, 0x52, 0x32, 0xe0, 0xfe, + 0x22, 0x09, 0x2c, 0x2d, 0x17, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x5d, 0xfc, + 0x20, 0x01, 0x10, 0x8d, 0x15, 0x6d, 0xfd, 0xfc, 0x50, 0x01, 0xdd, 0xfc, + 0x54, 0x01, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xb7, 0x0c, 0x92, 0x0c, + 0x85, 0xca, 0x42, 0x30, 0xb9, 0x25, 0xc2, 0x45, 0x3d, 0xfa, 0x18, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0xb7, 0x0c, 0x42, 0x30, 0xd1, 0xd6, 0xe2, 0x45, + 0x92, 0x0c, 0x3d, 0x23, 0x60, 0x51, 0x9f, 0x45, 0xc5, 0x4c, 0xe9, 0xce, + 0x02, 0xed, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, 0xd0, 0x00, 0x42, 0x30, + 0x51, 0x1e, 0xe2, 0x45, 0x4c, 0xee, 0xe2, 0x0e, 0x5d, 0xfc, 0x8c, 0x01, + 0x26, 0x69, 0x42, 0xd0, 0x00, 0x01, 0x02, 0xb4, 0x48, 0x00, 0x37, 0x32, + 0x29, 0x00, 0x5d, 0xfc, 0x88, 0x01, 0x62, 0xfe, 0x40, 0x00, 0x73, 0x02, + 0x2c, 0x01, 0x13, 0xb4, 0x53, 0x00, 0x5d, 0xfc, 0x8c, 0x01, 0x5d, 0xfc, + 0x88, 0x01, 0x22, 0xfd, 0x40, 0x00, 0x29, 0x01, 0xec, 0x00, 0x09, 0xb4, + 0x5e, 0x00, 0x5d, 0xfc, 0x8c, 0x01, 0x37, 0x32, 0x29, 0x00, 0x15, 0xcf, + 0x69, 0x0e, 0x04, 0xed, 0x57, 0x18, 0x37, 0x00, 0x4f, 0xcf, 0x04, 0xed, + 0x5c, 0xfc, 0xe4, 0x81, 0x20, 0x6d, 0xa6, 0xce, 0x5c, 0xf8, 0xe4, 0x81, + 0x57, 0x34, 0x3e, 0x00, 0x28, 0x2d, 0x02, 0x94, 0x79, 0xff, 0xb4, 0x48, + 0x59, 0x48, 0x03, 0x8d, 0x5a, 0x48, 0xa2, 0x40, 0x73, 0xff, 0x01, 0xed, + 0x70, 0xcf, 0x57, 0xf8, 0x38, 0x00, 0x5d, 0xfc, 0x18, 0x01, 0x02, 0x94, + 0x79, 0xff, 0x02, 0xed, 0x57, 0xf8, 0x38, 0x00, 0x7d, 0xfc, 0x18, 0x01, + 0x01, 0xed, 0x63, 0x14, 0x19, 0x00, 0x43, 0xb4, 0x71, 0xff, 0x5d, 0xfc, + 0x14, 0x01, 0x06, 0xed, 0x6b, 0xcf, 0x57, 0xf8, 0x38, 0x00, 0x60, 0x0e, + 0xe4, 0xce, 0x20, 0x0d, 0x02, 0xed, 0x57, 0xf8, 0x40, 0x00, 0x78, 0xcf, + 0x37, 0xf9, 0x44, 0x00, 0x03, 0xb4, 0x38, 0xff, 0x7d, 0xfc, 0x90, 0x01, + 0x3d, 0xcf, 0x63, 0x34, 0x20, 0x00, 0x03, 0xb4, 0x29, 0xff, 0x79, 0x48, + 0x2c, 0xcf, 0x00, 0x0c, 0x37, 0x32, 0x29, 0x00, 0x60, 0x0e, 0x42, 0x1c, + 0x26, 0x00, 0x22, 0x01, 0x00, 0x08, 0x49, 0x00, 0x50, 0x49, 0x29, 0x01, + 0x00, 0x18, 0x49, 0x00, 0x50, 0x49, 0xc3, 0xce, 0x29, 0x01, 0x00, 0x10, + 0x03, 0xb4, 0x04, 0xff, 0x7b, 0x48, 0x0f, 0xcf, 0x00, 0x0c, 0x37, 0x32, + 0x29, 0x00, 0x62, 0x1c, 0x26, 0x00, 0x5d, 0xfc, 0x88, 0x01, 0x22, 0x1d, + 0x64, 0x00, 0x32, 0x25, 0x34, 0x05, 0x26, 0x25, 0x34, 0x05, 0x24, 0x25, + 0x22, 0x01, 0x3c, 0xab, 0x09, 0x00, 0x3c, 0x70, 0xaa, 0xce, 0x49, 0x46, + 0xed, 0x4f, 0x75, 0x45, 0x44, 0xfc, 0x58, 0x02, 0x21, 0x2d, 0x24, 0xad, + 0x64, 0x30, 0x20, 0x01, 0x05, 0x32, 0x02, 0x00, 0xa2, 0x41, 0x02, 0x80, + 0x24, 0x0e, 0xc6, 0x86, 0x42, 0x30, 0x69, 0xc1, 0xe2, 0x45, 0x01, 0xef, + 0x14, 0xad, 0x42, 0x0e, 0xb3, 0x41, 0x01, 0x80, 0xb0, 0x0c, 0x91, 0x30, + 0xd4, 0x00, 0x73, 0x32, 0xbd, 0xa4, 0xf3, 0x45, 0x06, 0xef, 0xb0, 0x0c, + 0x91, 0x30, 0x96, 0x00, 0xf3, 0x45, 0x06, 0xef, 0x06, 0xef, 0xb0, 0x0c, + 0xd3, 0x45, 0x91, 0x30, 0x68, 0x08, 0x52, 0x0c, 0x35, 0x45, 0x0a, 0x47, + 0xfc, 0xcf, 0x40, 0x32, 0xf0, 0xff, 0x00, 0x0c, 0xc9, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0xfb, 0xcb, 0x09, 0x6e, 0x58, 0xef, 0x42, 0x30, 0x51, 0xa8, + 0xe2, 0x45, 0xa0, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0xbc, 0xe7, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xc0, 0xe7, 0xa5, 0x41, 0x09, 0x80, + 0x3c, 0xef, 0x4a, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0xa5, 0x30, 0xc4, 0xe7, + 0x17, 0x6e, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x7d, 0xf8, 0x24, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x20, 0xef, 0xd8, 0xee, 0x42, 0x30, 0xf5, 0x22, + 0xe2, 0x45, 0x09, 0x6e, 0xfb, 0x4b, 0x1c, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xd8, 0x9b, 0x02, 0x94, 0x9a, 0x00, 0x7c, 0xfc, 0xd4, 0x81, + 0x39, 0x4f, 0x7d, 0x22, 0x80, 0xd1, 0x42, 0xfe, 0x04, 0x00, 0xa2, 0x41, + 0x01, 0x80, 0x24, 0x0e, 0x05, 0x0e, 0xc0, 0x30, 0x6c, 0x01, 0xa0, 0x0c, + 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, 0x09, 0x6e, 0x11, 0x94, 0x72, 0x00, + 0x29, 0xca, 0xb0, 0x41, 0x01, 0x80, 0x10, 0x32, 0xbd, 0xa4, 0xa2, 0x41, + 0x09, 0x80, 0x22, 0xfd, 0x58, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xfd, + 0x5c, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0xe2, 0xfc, 0x60, 0x9a, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0xfc, 0x64, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, + 0x54, 0x9a, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, 0x74, 0x9a, + 0x9d, 0x30, 0x0c, 0x01, 0x7d, 0xf8, 0x08, 0x01, 0x3d, 0xf9, 0xfc, 0x00, + 0x1d, 0xf9, 0x00, 0x01, 0xfd, 0xf8, 0x04, 0x01, 0xd0, 0x45, 0x5d, 0xf8, + 0xf8, 0x00, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, 0x78, 0x9a, + 0xd0, 0x45, 0x9d, 0x30, 0x10, 0x01, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, + 0xa5, 0x30, 0x7c, 0x9a, 0xd0, 0x45, 0x9d, 0x30, 0x14, 0x01, 0xa5, 0x41, + 0x09, 0x80, 0xb2, 0x41, 0x09, 0x80, 0x24, 0xef, 0xa5, 0x30, 0x80, 0x9a, + 0xd0, 0x45, 0x9d, 0x30, 0x18, 0x01, 0xb2, 0x30, 0x5c, 0xbf, 0x9d, 0x30, + 0x3c, 0x01, 0x3c, 0xef, 0xd0, 0x45, 0x52, 0x32, 0x5c, 0xbf, 0x72, 0xfc, + 0x3c, 0x00, 0xa2, 0x41, 0xfa, 0x50, 0x42, 0x30, 0xfa, 0x50, 0x01, 0xee, + 0x53, 0x44, 0x43, 0x00, 0x18, 0x20, 0x8f, 0x8c, 0x9d, 0xf8, 0x78, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0xc0, 0x0c, 0xa0, 0x30, 0x6c, 0x01, 0x42, 0x30, + 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0x7d, 0x22, 0x80, 0x51, 0x9f, 0x45, + 0xc9, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc9, 0xdb, 0xe2, 0x45, + 0x00, 0x0c, 0x42, 0x40, 0xeb, 0xff, 0x7f, 0xed, 0xf2, 0xcf, 0x00, 0x0c, + 0xb2, 0xfc, 0x0c, 0x0b, 0x1d, 0xfa, 0xf0, 0x00, 0xb0, 0x41, 0x01, 0x80, + 0x45, 0xfc, 0xe0, 0x00, 0xc0, 0x30, 0xc8, 0x00, 0x15, 0x6e, 0x10, 0x32, + 0xbd, 0xa4, 0xdc, 0x6e, 0xd0, 0x45, 0x5d, 0xf8, 0xf4, 0x00, 0x83, 0xcf, + 0xa2, 0x41, 0x09, 0x80, 0x7f, 0xed, 0xb0, 0x6d, 0x9f, 0x45, 0x7c, 0xf8, + 0xd4, 0x81, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xed, 0x0f, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0xa3, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc8, 0x9e, 0x63, 0x30, 0x78, 0xa4, + 0x28, 0xee, 0x20, 0xea, 0x42, 0x30, 0x34, 0x00, 0x62, 0xb4, 0xfb, 0xff, + 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xf0, 0x9b, 0x63, 0x30, 0xc8, 0x9e, 0x28, 0xee, 0x20, 0xea, 0x42, 0x30, + 0x34, 0x00, 0x43, 0xb4, 0xfb, 0xff, 0xe5, 0x4b, 0x06, 0x47, 0x00, 0x0c, + 0xe9, 0x4f, 0xdd, 0x22, 0x14, 0xd0, 0xb2, 0x41, 0x09, 0x80, 0x52, 0xfc, + 0x24, 0x9b, 0xb0, 0x41, 0x09, 0x80, 0x10, 0x32, 0x50, 0xe8, 0x84, 0x0e, + 0xa5, 0x0e, 0x02, 0x96, 0x2e, 0x00, 0xa4, 0x41, 0x13, 0x80, 0xa3, 0x41, + 0x06, 0x80, 0x63, 0x30, 0x2c, 0xae, 0x62, 0x94, 0x2a, 0x00, 0x04, 0xf8, + 0x8c, 0x1e, 0x02, 0x02, 0x10, 0x1b, 0x60, 0x00, 0x58, 0x10, 0xb1, 0x41, + 0x03, 0x80, 0x82, 0x0c, 0x31, 0x32, 0x2d, 0x33, 0xd1, 0x45, 0xb3, 0x41, + 0x13, 0x80, 0xd1, 0x45, 0x93, 0xfc, 0x8c, 0x1e, 0x13, 0xfa, 0x8c, 0x1e, + 0xb2, 0xfa, 0x24, 0x9b, 0x14, 0xb4, 0x05, 0x00, 0xb9, 0x41, 0x10, 0x80, + 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0xa4, 0x41, 0x13, 0x80, 0x84, 0x30, + 0xfc, 0x5f, 0x39, 0x33, 0x23, 0x22, 0xdd, 0x22, 0x14, 0x50, 0x99, 0x45, + 0x19, 0x4c, 0x40, 0x0c, 0xde, 0xcf, 0x04, 0xf8, 0x8c, 0x1e, 0xdb, 0xcf, + 0x40, 0x0c, 0x00, 0x0c, 0xed, 0x4f, 0x30, 0xed, 0xd5, 0xed, 0x5d, 0x18, + 0x10, 0x00, 0x5d, 0x18, 0x11, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x7d, 0x18, + 0x14, 0x00, 0x42, 0x30, 0x8d, 0x36, 0xd3, 0xed, 0x66, 0x45, 0xc2, 0x45, + 0x7d, 0x18, 0x15, 0x00, 0xb1, 0x41, 0x01, 0x80, 0x42, 0x32, 0x09, 0x00, + 0x31, 0x32, 0xa1, 0xa4, 0x02, 0xef, 0x8b, 0x6e, 0x92, 0x0c, 0xf1, 0x45, + 0x02, 0x0e, 0x07, 0xad, 0x02, 0xef, 0xa2, 0x41, 0x59, 0x00, 0x42, 0x30, + 0xf8, 0x08, 0x50, 0xf8, 0xf0, 0x01, 0x89, 0x6e, 0xf1, 0x45, 0x92, 0x0c, + 0x18, 0xad, 0xa2, 0x41, 0x59, 0x00, 0x62, 0x30, 0xf8, 0x08, 0x42, 0x50, + 0x58, 0xf3, 0x50, 0xf8, 0xb4, 0x02, 0x40, 0x50, 0x40, 0x9c, 0x50, 0xf8, + 0xb8, 0x02, 0x40, 0x30, 0x8c, 0x0a, 0x50, 0xf8, 0xc0, 0x02, 0x40, 0x30, + 0x88, 0x08, 0x70, 0xf8, 0xb0, 0x02, 0x10, 0xf8, 0xbc, 0x02, 0x50, 0xf8, + 0x04, 0x03, 0x50, 0x0c, 0x26, 0x45, 0x0a, 0x47, 0xf5, 0x4f, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x69, 0xcb, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xa3, 0x41, 0x09, 0x80, 0x83, 0xfc, 0xb4, 0xe7, 0x81, 0xed, 0x64, 0xb4, + 0x08, 0x00, 0xe5, 0x4b, 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0xac, 0x9b, + 0x03, 0xf8, 0xec, 0x00, 0xe5, 0x4b, 0x06, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xd8, 0x9b, 0x02, 0x94, 0xca, 0x01, 0x7c, 0xfc, 0xd4, 0x81, + 0xd5, 0x4f, 0x3d, 0x23, 0x30, 0xd0, 0xb1, 0x41, 0x10, 0x80, 0x65, 0x0e, + 0x04, 0x0e, 0xa0, 0x30, 0xd0, 0x00, 0x80, 0x30, 0x84, 0x01, 0x31, 0x32, + 0x4b, 0x1e, 0xd1, 0x45, 0x42, 0xfe, 0x04, 0x00, 0x02, 0x94, 0xbb, 0x01, + 0xc2, 0x0f, 0x93, 0xfc, 0x08, 0x00, 0xa0, 0x30, 0xd0, 0x00, 0xf1, 0x45, + 0x4c, 0x6e, 0x02, 0x94, 0xb5, 0x01, 0x4a, 0xc8, 0xa2, 0x41, 0x01, 0x80, + 0xa0, 0x0c, 0x9e, 0x0c, 0x42, 0x30, 0x51, 0xa8, 0xc2, 0x45, 0xc0, 0x30, + 0x84, 0x01, 0x1e, 0x62, 0x1b, 0x80, 0x1e, 0x62, 0x18, 0x90, 0x53, 0xfc, + 0x04, 0x00, 0xa3, 0x41, 0x09, 0x80, 0xa3, 0x34, 0x12, 0xe8, 0x5e, 0x60, + 0x29, 0x80, 0x5e, 0x60, 0x26, 0x90, 0x53, 0xfc, 0x00, 0x00, 0x68, 0xc8, + 0x5e, 0x60, 0x23, 0x80, 0x5e, 0x60, 0x20, 0x90, 0x92, 0xfc, 0x0c, 0x0b, + 0x84, 0xfc, 0x60, 0x01, 0x9e, 0x60, 0x1f, 0x80, 0x05, 0x94, 0x6b, 0x01, + 0x9e, 0x60, 0x1c, 0x90, 0x01, 0xee, 0xb2, 0xee, 0xbe, 0x18, 0x24, 0x00, + 0x1e, 0x18, 0x25, 0x00, 0x9e, 0x60, 0x17, 0x80, 0x9e, 0x60, 0x14, 0x90, + 0x02, 0x94, 0xc0, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x44, 0xc8, 0xa2, 0x41, + 0x09, 0x80, 0x45, 0xc8, 0xa2, 0x41, 0x09, 0x80, 0x46, 0xc8, 0xa2, 0x41, + 0x09, 0x80, 0xb2, 0x41, 0x10, 0x80, 0xb1, 0x41, 0x09, 0x80, 0x47, 0xc8, + 0xa2, 0x41, 0x09, 0x80, 0x80, 0x0e, 0x52, 0x32, 0xe9, 0x16, 0x31, 0x32, + 0xc5, 0xc1, 0xb7, 0x41, 0x09, 0x80, 0x2c, 0xcc, 0x49, 0xc8, 0x50, 0x14, + 0xa6, 0x01, 0x42, 0xd0, 0x0a, 0x00, 0x02, 0xb4, 0x72, 0x00, 0x68, 0x48, + 0x49, 0x48, 0xc2, 0x34, 0x10, 0xe8, 0x01, 0xed, 0x44, 0x60, 0x7b, 0x80, + 0x06, 0x94, 0x2d, 0x01, 0x44, 0x60, 0x78, 0x90, 0x61, 0x25, 0xc4, 0x18, + 0x7d, 0x00, 0x44, 0x18, 0x7e, 0x00, 0x5e, 0x60, 0x17, 0x00, 0x01, 0xee, + 0x5e, 0x60, 0x14, 0x10, 0x82, 0x94, 0x75, 0x00, 0x95, 0x02, 0x50, 0x41, + 0x5e, 0x60, 0x23, 0x00, 0xb4, 0x30, 0x01, 0x00, 0x85, 0xd2, 0xff, 0x00, + 0x5e, 0x60, 0x20, 0x10, 0x54, 0x00, 0x90, 0x13, 0xe2, 0x40, 0x7a, 0x00, + 0xd4, 0x00, 0x00, 0x08, 0xd3, 0x00, 0x50, 0xb1, 0x96, 0x34, 0x10, 0x01, + 0xb4, 0x02, 0x00, 0x18, 0xd2, 0x45, 0x93, 0x02, 0x50, 0x81, 0x95, 0x02, + 0x50, 0x21, 0x9e, 0x00, 0x50, 0x21, 0x44, 0x18, 0x76, 0x00, 0x50, 0x14, + 0x74, 0x01, 0x64, 0x48, 0x44, 0x18, 0x77, 0x00, 0x96, 0x34, 0x10, 0x01, + 0x45, 0x48, 0x43, 0x15, 0xa4, 0xe7, 0x84, 0x31, 0x94, 0xf6, 0x22, 0x15, + 0xa5, 0xe7, 0x46, 0x48, 0x8c, 0xb1, 0x49, 0x00, 0xc4, 0x30, 0xd8, 0xeb, + 0x67, 0x48, 0x80, 0x01, 0x58, 0x50, 0x42, 0x14, 0xa6, 0xe7, 0x8a, 0x0d, + 0xc6, 0xb0, 0xb5, 0x00, 0xc9, 0x00, 0x18, 0x60, 0xc4, 0x30, 0x98, 0xea, + 0xc6, 0xb0, 0xf1, 0x00, 0x23, 0x15, 0xa7, 0xe7, 0xc2, 0x00, 0x18, 0x60, + 0x44, 0x30, 0x8f, 0xe9, 0x42, 0xb0, 0x8d, 0x00, 0xd1, 0x45, 0x49, 0x00, + 0x18, 0x60, 0x95, 0x02, 0x50, 0x21, 0x9e, 0x00, 0x50, 0x21, 0xc4, 0x14, + 0x77, 0x00, 0x37, 0x15, 0x14, 0xe8, 0x4c, 0x00, 0x50, 0x11, 0x2d, 0x05, + 0x09, 0x94, 0x8b, 0xff, 0x44, 0x18, 0x77, 0x00, 0x68, 0x48, 0x95, 0x02, + 0x50, 0x11, 0x5e, 0x00, 0x50, 0x11, 0x83, 0x34, 0x12, 0xe8, 0x02, 0x60, + 0x7b, 0x80, 0x04, 0x94, 0xb3, 0x00, 0x02, 0x60, 0x78, 0x90, 0x41, 0x27, + 0x82, 0x18, 0x7d, 0x00, 0xc2, 0x18, 0x7e, 0x00, 0x5e, 0x60, 0x17, 0x00, + 0x01, 0xee, 0x5e, 0x60, 0x14, 0x10, 0x82, 0xb4, 0x8f, 0xff, 0x95, 0x02, + 0x50, 0x41, 0x02, 0xed, 0x1e, 0x01, 0x50, 0x41, 0x48, 0x18, 0x7c, 0x00, + 0x5e, 0x60, 0x23, 0x00, 0xb4, 0x30, 0x01, 0x00, 0x85, 0xd2, 0xff, 0x00, + 0x5e, 0x60, 0x20, 0x10, 0x54, 0x00, 0x90, 0x13, 0x02, 0xb4, 0x8a, 0xff, + 0xd4, 0x00, 0x00, 0x08, 0x53, 0xfc, 0x0c, 0x01, 0x6a, 0x48, 0x5e, 0x60, + 0x2d, 0x80, 0x5e, 0x60, 0x2a, 0x90, 0x53, 0xfc, 0x08, 0x00, 0x43, 0x60, + 0x17, 0x80, 0x43, 0x60, 0x14, 0x90, 0xd3, 0xfc, 0x08, 0x00, 0x06, 0xb4, + 0x95, 0x00, 0x4a, 0x48, 0x53, 0xfc, 0x04, 0x00, 0x82, 0x40, 0x9d, 0x00, + 0x00, 0x0c, 0x5e, 0x60, 0x29, 0x00, 0x5e, 0x60, 0x26, 0x10, 0x3f, 0x8d, + 0x00, 0x0e, 0xb1, 0x41, 0x01, 0x80, 0x0c, 0xcc, 0x31, 0x32, 0xbd, 0xa4, + 0x9e, 0x60, 0x29, 0x00, 0x00, 0x6c, 0x0d, 0x2c, 0x9e, 0x60, 0x26, 0x10, + 0x90, 0x00, 0x90, 0x13, 0xe2, 0x40, 0x25, 0x00, 0x8a, 0x26, 0x8a, 0x06, + 0xb3, 0x00, 0x50, 0x41, 0x06, 0x26, 0xc8, 0x14, 0xf8, 0x01, 0x08, 0x06, + 0x44, 0x26, 0x9e, 0x00, 0x50, 0x11, 0xc2, 0x60, 0x31, 0x80, 0x68, 0x8f, + 0xc2, 0x60, 0x2e, 0x90, 0xc8, 0x14, 0xf8, 0x01, 0xa5, 0x30, 0xd8, 0x01, + 0x84, 0x30, 0x32, 0x00, 0x9e, 0x00, 0x50, 0x21, 0xd1, 0x45, 0xb3, 0x00, + 0x50, 0x29, 0x9e, 0x60, 0x29, 0x00, 0x00, 0x6c, 0x0d, 0x2c, 0x9e, 0x60, + 0x26, 0x10, 0x90, 0x00, 0x90, 0x13, 0x5d, 0xad, 0x8a, 0x26, 0xe4, 0x40, + 0x08, 0x00, 0x40, 0x0c, 0x20, 0x6d, 0x2d, 0x2d, 0x82, 0x00, 0x90, 0x2b, + 0xfc, 0xae, 0x20, 0x6d, 0x2e, 0x6d, 0xbe, 0x60, 0x23, 0x00, 0xbe, 0x60, + 0x20, 0x10, 0x87, 0x8e, 0x40, 0x0c, 0x20, 0x6d, 0x2d, 0x2d, 0xa2, 0x00, + 0x90, 0x23, 0x7c, 0xae, 0x20, 0x6d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xc4, 0xbe, 0xa2, 0x60, 0x27, 0x00, 0x2a, 0x4a, 0xb0, 0x41, 0x10, 0x80, + 0xa2, 0x60, 0x24, 0x10, 0x10, 0x32, 0xf5, 0x22, 0x17, 0xef, 0xd0, 0x6e, + 0xa2, 0x60, 0x27, 0x80, 0xa2, 0x60, 0x24, 0x90, 0xb3, 0xfc, 0x08, 0x00, + 0x91, 0x0c, 0xf0, 0x45, 0xdc, 0x6e, 0x01, 0xef, 0xa0, 0x30, 0x84, 0x01, + 0xf0, 0x45, 0x9e, 0x0c, 0xb0, 0x41, 0x10, 0x80, 0x10, 0x32, 0x3f, 0x1e, + 0xf0, 0x45, 0x9e, 0x0c, 0xf0, 0x45, 0x91, 0x0c, 0x40, 0x0c, 0x3d, 0x23, + 0x30, 0x50, 0x16, 0x47, 0x80, 0x30, 0x82, 0xff, 0x82, 0x18, 0x7d, 0x00, + 0xdc, 0xce, 0x02, 0x18, 0x7e, 0x00, 0x32, 0xed, 0x44, 0x18, 0x7d, 0x00, + 0xd6, 0xce, 0x04, 0x18, 0x7e, 0x00, 0xa4, 0x41, 0x09, 0x80, 0x84, 0x34, + 0x10, 0xe8, 0x04, 0x94, 0x9b, 0xfe, 0x01, 0xee, 0x91, 0xce, 0xb2, 0xee, + 0x2c, 0x6e, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0xb3, 0x30, 0x0c, 0x00, 0x53, 0xfc, 0x04, 0x00, 0xc2, 0x40, 0x65, 0xff, + 0x00, 0x0c, 0x9e, 0x60, 0x29, 0x00, 0x9b, 0xcf, 0x9e, 0x60, 0x26, 0x10, + 0x7f, 0xed, 0xb0, 0x6d, 0x9f, 0x45, 0x7c, 0xf8, 0xd4, 0x81, 0xcf, 0xcf, + 0x40, 0x30, 0xf4, 0xff, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3f, 0x1e, + 0xe2, 0x45, 0x9e, 0x0c, 0xc6, 0xcf, 0x40, 0x30, 0xf4, 0xff, 0x00, 0x0c, + 0x0b, 0x8e, 0xb9, 0x41, 0x01, 0x80, 0x64, 0x30, 0xe0, 0xfe, 0xa2, 0x41, + 0x09, 0x80, 0x39, 0x33, 0xe9, 0x7e, 0x99, 0x45, 0x62, 0xf8, 0x58, 0xbf, + 0x5c, 0xfc, 0xe4, 0x81, 0x64, 0x30, 0xe0, 0xfe, 0x20, 0x6d, 0x5c, 0xf8, + 0xe4, 0x81, 0x39, 0x33, 0xe9, 0x7e, 0xa2, 0x41, 0x09, 0x80, 0x99, 0x45, + 0x62, 0xf8, 0x58, 0xbf, 0xa6, 0x41, 0x62, 0x10, 0xa2, 0x41, 0x09, 0x80, + 0x46, 0x31, 0xd3, 0x4d, 0xa6, 0x41, 0xeb, 0x51, 0x82, 0xfd, 0x24, 0x9b, + 0x84, 0x30, 0xec, 0x01, 0x81, 0xed, 0x40, 0x0c, 0x60, 0x0d, 0x84, 0xef, + 0x00, 0x31, 0x01, 0x00, 0xa0, 0x31, 0x0b, 0x00, 0x26, 0x51, 0x1f, 0x85, + 0x40, 0x6b, 0xe6, 0x40, 0x1b, 0x00, 0xed, 0x4f, 0x3d, 0x21, 0x04, 0xd0, + 0xe2, 0x40, 0x23, 0x00, 0x02, 0x95, 0xb4, 0x00, 0x00, 0x0c, 0xe3, 0x94, + 0x09, 0x00, 0x00, 0x0c, 0x42, 0x6e, 0x40, 0x6b, 0x20, 0x6d, 0x74, 0xaf, + 0xb0, 0x6d, 0xe3, 0xb4, 0xf9, 0xff, 0x00, 0x0c, 0x65, 0x61, 0x29, 0x80, + 0x40, 0x0c, 0x65, 0x61, 0x26, 0x90, 0x3d, 0x21, 0x04, 0x50, 0x0a, 0x47, + 0xe3, 0x94, 0x05, 0x00, 0x00, 0x0c, 0x20, 0x6d, 0x42, 0x6e, 0xdc, 0xcf, + 0xb0, 0x6d, 0x65, 0x61, 0x29, 0x80, 0x65, 0x61, 0x26, 0x90, 0x9f, 0x45, + 0x40, 0x0c, 0xc6, 0xfd, 0x0c, 0x00, 0x0e, 0x94, 0xdf, 0xff, 0xcb, 0x01, + 0x00, 0x08, 0x6e, 0x01, 0x50, 0x91, 0x52, 0x02, 0x00, 0x10, 0x72, 0x01, + 0xd0, 0x91, 0x52, 0x32, 0x32, 0x00, 0x45, 0x02, 0x50, 0x91, 0x60, 0x0e, + 0xa0, 0x0e, 0x06, 0xff, 0x00, 0x00, 0x6e, 0x01, 0x50, 0x79, 0xef, 0x01, + 0x00, 0x10, 0x78, 0x02, 0x50, 0x71, 0xce, 0xfd, 0x04, 0x00, 0x6f, 0x01, + 0xd0, 0x79, 0xe5, 0x01, 0x50, 0x79, 0xcf, 0x61, 0x2d, 0x80, 0xcf, 0x61, + 0x2a, 0x90, 0xc6, 0xfd, 0x00, 0x00, 0x6e, 0x02, 0x50, 0x71, 0x2e, 0xff, + 0x08, 0x00, 0x20, 0x03, 0xd0, 0x72, 0xce, 0xd1, 0x01, 0x00, 0x39, 0xd3, + 0x01, 0x00, 0x19, 0xb4, 0x52, 0x00, 0xd2, 0x19, 0x00, 0x00, 0xc6, 0xfd, + 0x00, 0x00, 0x0c, 0x16, 0x08, 0x00, 0x6e, 0x02, 0x50, 0x71, 0x2e, 0xfe, + 0x04, 0x00, 0x91, 0x32, 0xf6, 0xff, 0x10, 0x94, 0x44, 0x00, 0xd1, 0x32, + 0x0a, 0x00, 0x0c, 0x33, 0x10, 0x00, 0xd8, 0xfd, 0x00, 0x00, 0x4e, 0x01, + 0x3c, 0x9b, 0x0e, 0x46, 0xce, 0x01, 0x40, 0x30, 0x2e, 0x02, 0x90, 0xbb, + 0x17, 0x94, 0x2f, 0x00, 0x22, 0x4f, 0xf8, 0xfe, 0x04, 0x00, 0x57, 0x01, + 0x3c, 0x9b, 0x17, 0x46, 0xf7, 0x02, 0x40, 0x30, 0xf1, 0x02, 0x90, 0xf3, + 0x1e, 0x94, 0x23, 0x00, 0xd4, 0x01, 0x90, 0x73, 0x0e, 0xb4, 0x1f, 0x00, + 0xd7, 0x02, 0x90, 0xbb, 0x17, 0xb4, 0x1d, 0x00, 0x19, 0x02, 0x90, 0x73, + 0xd8, 0xfd, 0x10, 0x00, 0x2e, 0x01, 0x3c, 0x9b, 0x0e, 0x46, 0xce, 0x01, + 0x40, 0x28, 0xcf, 0x61, 0x31, 0x80, 0xcf, 0x61, 0x2e, 0x90, 0xd8, 0xfd, + 0x54, 0x00, 0xce, 0x01, 0xec, 0x01, 0xd2, 0x19, 0x01, 0x00, 0xd8, 0xfd, + 0x54, 0x00, 0xce, 0x01, 0x2c, 0x01, 0xd2, 0x19, 0x02, 0x00, 0x0c, 0x16, + 0x08, 0x00, 0x19, 0x02, 0x90, 0x73, 0x0e, 0xb4, 0xc2, 0xff, 0x18, 0x33, + 0x60, 0x00, 0xc6, 0xfd, 0x0c, 0x00, 0xa2, 0x4e, 0x62, 0x4d, 0xd5, 0x01, + 0x90, 0x73, 0x73, 0x32, 0x34, 0x00, 0x0e, 0x94, 0x55, 0xff, 0x52, 0x32, + 0x0b, 0x00, 0x81, 0xcf, 0xcb, 0x01, 0x00, 0x08, 0xc6, 0xfd, 0x0c, 0x00, + 0x0e, 0x94, 0x4c, 0xff, 0xab, 0x01, 0x10, 0x72, 0x60, 0x0e, 0x80, 0x0e, + 0xae, 0x00, 0x50, 0x91, 0x52, 0x32, 0x32, 0x00, 0xe6, 0xfd, 0x00, 0x00, + 0xcb, 0x01, 0x00, 0x08, 0x6e, 0x01, 0x50, 0x71, 0x6f, 0x02, 0x50, 0x79, + 0xef, 0xfd, 0x04, 0x00, 0xce, 0x01, 0x00, 0x10, 0x6e, 0x01, 0xd0, 0x71, + 0xc5, 0x01, 0x50, 0x71, 0xee, 0x61, 0x2d, 0x80, 0xee, 0x61, 0x2a, 0x90, + 0xe6, 0xfd, 0x00, 0x00, 0x6f, 0x02, 0x50, 0x79, 0x2f, 0xff, 0x08, 0x00, + 0x20, 0x03, 0xd0, 0x7a, 0xef, 0xd1, 0x01, 0x00, 0x39, 0xd3, 0x01, 0x00, + 0x19, 0xb4, 0x52, 0x00, 0xf2, 0x19, 0x00, 0x00, 0xe6, 0xfd, 0x00, 0x00, + 0x0c, 0x16, 0x08, 0x00, 0x6f, 0x02, 0x50, 0x79, 0x2f, 0xfe, 0x04, 0x00, + 0xb1, 0x32, 0xf6, 0xff, 0x10, 0x94, 0x44, 0x00, 0xd1, 0x32, 0x0a, 0x00, + 0x0c, 0x33, 0x10, 0x00, 0xf8, 0xfd, 0x00, 0x00, 0x4f, 0x01, 0x3c, 0x9b, + 0x0f, 0x46, 0xef, 0x01, 0x40, 0x30, 0x2f, 0x02, 0x90, 0xbb, 0x17, 0x94, + 0x2f, 0x00, 0x22, 0x4f, 0xf8, 0xfe, 0x04, 0x00, 0x57, 0x01, 0x3c, 0x9b, + 0x17, 0x46, 0xf7, 0x02, 0x40, 0x30, 0xf1, 0x02, 0x90, 0xf3, 0x1e, 0x94, + 0x23, 0x00, 0xf5, 0x01, 0x90, 0x7b, 0x0f, 0xb4, 0x1f, 0x00, 0xd7, 0x02, + 0x90, 0xbb, 0x17, 0xb4, 0x1d, 0x00, 0x19, 0x02, 0x90, 0x7b, 0xf8, 0xfd, + 0x10, 0x00, 0x2f, 0x01, 0x3c, 0x9b, 0x0f, 0x46, 0xef, 0x01, 0x40, 0x28, + 0xee, 0x61, 0x31, 0x80, 0xee, 0x61, 0x2e, 0x90, 0xf8, 0xfd, 0x54, 0x00, + 0xef, 0x01, 0xec, 0x01, 0xf2, 0x19, 0x01, 0x00, 0xf8, 0xfd, 0x54, 0x00, + 0xef, 0x01, 0x2c, 0x01, 0xf2, 0x19, 0x02, 0x00, 0x0c, 0x16, 0x08, 0x00, + 0x19, 0x02, 0x90, 0x7b, 0x0f, 0xb4, 0xc2, 0xff, 0x18, 0x33, 0x60, 0x00, + 0xc6, 0xfd, 0x0c, 0x00, 0x82, 0x4e, 0x62, 0x4d, 0xd4, 0x01, 0x90, 0x73, + 0x73, 0x32, 0x34, 0x00, 0x0e, 0xb4, 0x82, 0xff, 0x52, 0x32, 0x0b, 0x00, + 0xc4, 0xce, 0x42, 0x6e, 0xed, 0x4f, 0x66, 0x45, 0x44, 0x20, 0xec, 0x11, + 0xa5, 0x41, 0x09, 0x80, 0x25, 0xfe, 0x24, 0x9b, 0x23, 0x69, 0xb3, 0x69, + 0xb4, 0x05, 0x32, 0x25, 0x34, 0x05, 0x24, 0x25, 0x35, 0x05, 0x42, 0x30, + 0x2a, 0x00, 0xb7, 0x8c, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x44, 0x0e, + 0x89, 0x6e, 0x42, 0x30, 0xb7, 0x24, 0xe2, 0x45, 0x02, 0xee, 0x30, 0x8d, + 0x02, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x55, 0x14, 0xe2, 0x45, + 0x1f, 0xee, 0x50, 0x60, 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0x10, 0x60, + 0x03, 0x80, 0x10, 0x60, 0x00, 0x90, 0x10, 0x60, 0x07, 0x80, 0xa2, 0x41, + 0x01, 0x80, 0xb1, 0x30, 0x09, 0x00, 0x90, 0x30, 0x24, 0x00, 0x42, 0x30, + 0x55, 0xab, 0xc2, 0x45, 0x10, 0x60, 0x04, 0x90, 0xa2, 0x41, 0x09, 0x80, + 0xca, 0x86, 0x42, 0x30, 0xf1, 0xe2, 0xe2, 0x45, 0x00, 0x0c, 0xa4, 0x48, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, 0xe2, 0x45, 0x90, 0x0c, + 0x40, 0x0c, 0x26, 0x45, 0x0a, 0x47, 0xfd, 0xcf, 0x40, 0x30, 0xea, 0xff, + 0xfa, 0xcf, 0x40, 0x30, 0x97, 0xff, 0x00, 0x0c, 0x40, 0x30, 0x83, 0x00, + 0x45, 0x94, 0x02, 0x00, 0x40, 0x0c, 0xbf, 0x45, 0xed, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x48, 0x45, 0x06, 0xef, 0x04, 0x0e, 0xa4, 0x30, 0x24, 0x00, + 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x9d, 0x30, 0x12, 0x00, 0x4e, 0x48, + 0x8e, 0x48, 0x42, 0xfc, 0x80, 0x00, 0x26, 0x69, 0xe2, 0x45, 0x89, 0x6e, + 0x90, 0x60, 0x0b, 0x00, 0xa2, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x43, 0x23, 0xc2, 0x45, 0x90, 0x60, 0x08, 0x10, 0x01, 0xed, 0x08, 0x45, + 0x0a, 0x47, 0x00, 0x0c, 0x40, 0xea, 0x9f, 0x45, 0x41, 0xea, 0x00, 0x0c, + 0x40, 0x69, 0x51, 0xea, 0x50, 0xe9, 0x40, 0x69, 0xa1, 0xea, 0x9f, 0x45, + 0xc0, 0xea, 0x00, 0x0c, 0x41, 0x69, 0x50, 0xea, 0x51, 0xe9, 0x41, 0x69, + 0xa0, 0xea, 0x9f, 0x45, 0xc1, 0xea, 0x00, 0x0c, 0x40, 0x69, 0x54, 0x44, + 0x9f, 0x45, 0x42, 0xb0, 0x01, 0x00, 0x00, 0x0c, 0x40, 0x69, 0x62, 0x44, + 0x9f, 0x45, 0x80, 0x00, 0x58, 0x10, 0x00, 0x0c, 0x41, 0x69, 0x62, 0x44, + 0x9f, 0x45, 0x80, 0x00, 0x58, 0x10, 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x69, + 0x9f, 0x45, 0x41, 0x69, 0xc0, 0x69, 0x41, 0x69, 0x31, 0xe9, 0xa0, 0xe9, + 0x40, 0xea, 0x9f, 0x45, 0x41, 0xea, 0x00, 0x0c, 0x40, 0x69, 0x82, 0x94, + 0x08, 0x00, 0x00, 0x0c, 0x20, 0x6a, 0xa1, 0x69, 0xc1, 0xe9, 0x30, 0xea, + 0x21, 0xe9, 0x9f, 0x45, 0x20, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, + 0x40, 0x69, 0x82, 0x94, 0x09, 0x00, 0x00, 0x0c, 0x41, 0x69, 0xa1, 0x69, + 0x20, 0x6a, 0xc1, 0xe9, 0x30, 0xea, 0x21, 0xe9, 0x9f, 0x45, 0x20, 0xe9, + 0x9f, 0x45, 0x40, 0x0c, 0x41, 0x69, 0x50, 0xea, 0x51, 0xe9, 0xa0, 0xea, + 0x9f, 0x45, 0xc1, 0xea, 0x40, 0x69, 0x51, 0xea, 0x50, 0xe9, 0xa1, 0xea, + 0x9f, 0x45, 0xc0, 0xea, 0x40, 0x69, 0x82, 0x94, 0x0a, 0x00, 0x00, 0x0c, + 0xc1, 0x69, 0x45, 0x20, 0x00, 0x90, 0xa1, 0xea, 0x51, 0x69, 0xa0, 0xea, + 0x40, 0xea, 0x9f, 0x45, 0x41, 0xea, 0xd0, 0xea, 0x9f, 0x45, 0xd1, 0xea, + 0x46, 0x34, 0x43, 0x45, 0x33, 0x36, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, + 0x00, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, 0x84, 0x00, 0x00, 0x00, + 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, 0x87, 0x00, 0x00, 0x00, + 0x88, 0x00, 0x00, 0x00, 0xfc, 0xff, 0xff, 0xf3, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0xa0, 0x9d, 0x13, 0x80, 0x47, 0x43, 0x43, 0x3a, 0x20, 0x28, 0x43, 0x6f, + 0x64, 0x65, 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x47, 0x4e, 0x55, 0x20, + 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x20, 0x32, 0x30, 0x31, 0x37, 0x2e, 0x31, + 0x30, 0x2d, 0x30, 0x35, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4d, 0x49, 0x50, + 0x53, 0x20, 0x4d, 0x54, 0x49, 0x20, 0x42, 0x61, 0x72, 0x65, 0x20, 0x4d, + 0x65, 0x74, 0x61, 0x6c, 0x29, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x30, 0x00, + 0x47, 0x43, 0x43, 0x3a, 0x20, 0x28, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x63, + 0x61, 0x70, 0x65, 0x20, 0x47, 0x4e, 0x55, 0x20, 0x54, 0x6f, 0x6f, 0x6c, + 0x73, 0x20, 0x32, 0x30, 0x32, 0x30, 0x2e, 0x30, 0x36, 0x2d, 0x30, 0x31, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4d, 0x49, 0x50, 0x53, 0x20, 0x4d, 0x54, + 0x49, 0x20, 0x42, 0x61, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x6c, + 0x29, 0x20, 0x39, 0x2e, 0x33, 0x2e, 0x30, 0x00, 0x41, 0x0f, 0x00, 0x00, + 0x00, 0x67, 0x6e, 0x75, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x04, 0x03, + 0xdd, 0x76, 0x01, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, + 0xca, 0x10, 0x01, 0x00, 0x0c, 0xb7, 0x7a, 0x00, 0x00, 0xe8, 0x03, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, + 0xf7, 0xf3, 0x01, 0x00, 0x02, 0x01, 0x06, 0xd9, 0x0c, 0x02, 0x00, 0x03, + 0xaf, 0x10, 0x00, 0x00, 0x0a, 0x2b, 0x3a, 0x00, 0x00, 0x00, 0x02, 0x01, + 0x08, 0xc4, 0x40, 0x01, 0x00, 0x04, 0x3a, 0x00, 0x00, 0x00, 0x02, 0x02, + 0x05, 0x05, 0x84, 0x01, 0x00, 0x02, 0x02, 0x07, 0xbb, 0x40, 0x02, 0x00, + 0x03, 0x0b, 0x93, 0x00, 0x00, 0x0a, 0x4d, 0x5f, 0x00, 0x00, 0x00, 0x02, + 0x04, 0x05, 0x44, 0xf7, 0x01, 0x00, 0x03, 0x96, 0x76, 0x00, 0x00, 0x0a, + 0x4f, 0x71, 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, 0x84, 0xdd, 0x01, 0x00, + 0x05, 0x71, 0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0x00, 0x03, 0x69, + 0x2a, 0x00, 0x00, 0x0a, 0x67, 0x8d, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, + 0x48, 0x2a, 0x02, 0x00, 0x03, 0x10, 0x14, 0x00, 0x00, 0x0a, 0x69, 0x9f, + 0x00, 0x00, 0x00, 0x02, 0x08, 0x07, 0x27, 0x25, 0x01, 0x00, 0x03, 0x3b, + 0x71, 0x00, 0x00, 0x0a, 0xe8, 0x71, 0x00, 0x00, 0x00, 0x03, 0xb1, 0x10, + 0x00, 0x00, 0x0b, 0x18, 0x2f, 0x00, 0x00, 0x00, 0x03, 0x0d, 0x93, 0x00, + 0x00, 0x0b, 0x2c, 0x54, 0x00, 0x00, 0x00, 0x05, 0xbc, 0x00, 0x00, 0x00, + 0x03, 0x98, 0x76, 0x00, 0x00, 0x0b, 0x30, 0x66, 0x00, 0x00, 0x00, 0x05, + 0xcc, 0x00, 0x00, 0x00, 0x03, 0x6b, 0x2a, 0x00, 0x00, 0x0b, 0x38, 0x82, + 0x00, 0x00, 0x00, 0x03, 0x12, 0x14, 0x00, 0x00, 0x0b, 0x3c, 0x94, 0x00, + 0x00, 0x00, 0x03, 0x3d, 0x71, 0x00, 0x00, 0x0b, 0x52, 0xa6, 0x00, 0x00, + 0x00, 0x06, 0x04, 0x05, 0x69, 0x6e, 0x74, 0x00, 0x04, 0xfd, 0x00, 0x00, + 0x00, 0x03, 0xce, 0x0b, 0x02, 0x00, 0x0c, 0xd8, 0x71, 0x00, 0x00, 0x00, + 0x02, 0x08, 0x04, 0x65, 0x2c, 0x02, 0x00, 0x03, 0x7a, 0x13, 0x00, 0x00, + 0x0d, 0x07, 0xfd, 0x00, 0x00, 0x00, 0x03, 0xbc, 0x50, 0x00, 0x00, 0x0e, + 0x2c, 0x5f, 0x00, 0x00, 0x00, 0x03, 0xc7, 0xad, 0x00, 0x00, 0x0e, 0x72, + 0x5f, 0x00, 0x00, 0x00, 0x07, 0xe2, 0x9e, 0x01, 0x00, 0x0c, 0x65, 0x01, + 0x21, 0x00, 0x00, 0x00, 0x08, 0x04, 0x0e, 0xa6, 0x67, 0x01, 0x00, 0x00, + 0x09, 0xfb, 0x62, 0x00, 0x00, 0x0e, 0xa8, 0x3c, 0x01, 0x00, 0x00, 0x09, + 0x60, 0x39, 0x00, 0x00, 0x0e, 0xa9, 0x67, 0x01, 0x00, 0x00, 0x00, 0x0a, + 0x3a, 0x00, 0x00, 0x00, 0x77, 0x01, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, + 0x00, 0x03, 0x00, 0x02, 0x04, 0x07, 0xa4, 0xbe, 0x00, 0x00, 0x0c, 0x08, + 0x0e, 0xa3, 0x9f, 0x01, 0x00, 0x00, 0x0d, 0x98, 0x0c, 0x01, 0x00, 0x0e, + 0xa5, 0xfd, 0x00, 0x00, 0x00, 0x00, 0x0d, 0x6f, 0x60, 0x00, 0x00, 0x0e, + 0xaa, 0x48, 0x01, 0x00, 0x00, 0x04, 0x00, 0x03, 0xf6, 0xb3, 0x00, 0x00, + 0x0e, 0xab, 0x7e, 0x01, 0x00, 0x00, 0x03, 0x43, 0x50, 0x00, 0x00, 0x0e, + 0xaf, 0x1b, 0x01, 0x00, 0x00, 0x0e, 0x04, 0x03, 0x0e, 0x9d, 0x00, 0x00, + 0x0f, 0x16, 0x71, 0x00, 0x00, 0x00, 0x0f, 0xa6, 0x52, 0x00, 0x00, 0x18, + 0x0f, 0x2f, 0x15, 0x02, 0x00, 0x00, 0x0d, 0xb5, 0x24, 0x00, 0x00, 0x0f, + 0x31, 0x15, 0x02, 0x00, 0x00, 0x00, 0x10, 0x5f, 0x6b, 0x00, 0x0f, 0x32, + 0xfd, 0x00, 0x00, 0x00, 0x04, 0x0d, 0xb9, 0x01, 0x00, 0x00, 0x0f, 0x32, + 0xfd, 0x00, 0x00, 0x00, 0x08, 0x0d, 0x69, 0xd4, 0x00, 0x00, 0x0f, 0x32, + 0xfd, 0x00, 0x00, 0x00, 0x0c, 0x0d, 0xb6, 0x42, 0x00, 0x00, 0x0f, 0x32, + 0xfd, 0x00, 0x00, 0x00, 0x10, 0x10, 0x5f, 0x78, 0x00, 0x0f, 0x33, 0x1b, + 0x02, 0x00, 0x00, 0x14, 0x00, 0x11, 0x04, 0xc2, 0x01, 0x00, 0x00, 0x0a, + 0xb7, 0x01, 0x00, 0x00, 0x2b, 0x02, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, + 0x00, 0x00, 0x00, 0x0f, 0xa4, 0xa7, 0x00, 0x00, 0x24, 0x0f, 0x37, 0xa4, + 0x02, 0x00, 0x00, 0x0d, 0x0a, 0x2d, 0x00, 0x00, 0x0f, 0x39, 0xfd, 0x00, + 0x00, 0x00, 0x00, 0x0d, 0x00, 0x97, 0x00, 0x00, 0x0f, 0x3a, 0xfd, 0x00, + 0x00, 0x00, 0x04, 0x0d, 0xc7, 0x00, 0x01, 0x00, 0x0f, 0x3b, 0xfd, 0x00, + 0x00, 0x00, 0x08, 0x0d, 0xe0, 0xad, 0x00, 0x00, 0x0f, 0x3c, 0xfd, 0x00, + 0x00, 0x00, 0x0c, 0x0d, 0x42, 0x9e, 0x00, 0x00, 0x0f, 0x3d, 0xfd, 0x00, + 0x00, 0x00, 0x10, 0x0d, 0xb1, 0x3d, 0x00, 0x00, 0x0f, 0x3e, 0xfd, 0x00, + 0x00, 0x00, 0x14, 0x0d, 0xcf, 0x3e, 0x00, 0x00, 0x0f, 0x3f, 0xfd, 0x00, + 0x00, 0x00, 0x18, 0x0d, 0xfe, 0x0a, 0x01, 0x00, 0x0f, 0x40, 0xfd, 0x00, + 0x00, 0x00, 0x1c, 0x0d, 0xf1, 0x0f, 0x00, 0x00, 0x0f, 0x41, 0xfd, 0x00, + 0x00, 0x00, 0x20, 0x00, 0x12, 0x73, 0xdc, 0x00, 0x00, 0x08, 0x01, 0x0f, + 0x4a, 0xe4, 0x02, 0x00, 0x00, 0x0d, 0x31, 0x08, 0x00, 0x00, 0x0f, 0x4b, + 0xe4, 0x02, 0x00, 0x00, 0x00, 0x0d, 0xfd, 0x34, 0x00, 0x00, 0x0f, 0x4c, + 0xe4, 0x02, 0x00, 0x00, 0x80, 0x13, 0x5f, 0xd3, 0x00, 0x00, 0x0f, 0x4e, + 0xb7, 0x01, 0x00, 0x00, 0x00, 0x01, 0x13, 0x24, 0x99, 0x00, 0x00, 0x0f, + 0x51, 0xb7, 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0a, 0xb5, 0x01, 0x00, + 0x00, 0xf4, 0x02, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, 0x00, 0x1f, 0x00, + 0x12, 0x37, 0x1f, 0x00, 0x00, 0x90, 0x01, 0x0f, 0x5d, 0x32, 0x03, 0x00, + 0x00, 0x0d, 0xb5, 0x24, 0x00, 0x00, 0x0f, 0x5e, 0x32, 0x03, 0x00, 0x00, + 0x00, 0x0d, 0x6a, 0x54 +}; + +const unsigned char __aligned(4) nrf_wifi_lmac_patch_pri_bimg[] = { + 0xba, 0xda, 0xba, 0xab, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xcc, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x7d, 0xea, 0x00, 0x00, 0x02, 0xd4, 0x88, 0x22, 0x46, 0x19, 0x08, 0x80, + 0x01, 0x00, 0xf8, 0x3b, 0x02, 0xd4, 0x30, 0x24, 0x6a, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x48, 0x64, 0x02, 0xd4, 0x06, 0x2b, 0x84, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xf9, 0x44, 0x02, 0xd4, 0x92, 0x2c, 0xac, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xfe, 0x00, 0x02, 0xd4, 0x44, 0x2c, 0x60, 0x17, 0x08, 0x80, + 0x01, 0x00, 0xd7, 0x64, 0x02, 0xd4, 0xe2, 0x22, 0x3e, 0x15, 0x08, 0x80, + 0x01, 0x00, 0xc9, 0xe4, 0x02, 0xd4, 0x0a, 0x2d, 0x72, 0x17, 0x08, 0x80, + 0x01, 0x00, 0xb3, 0x25, 0x02, 0xd4, 0xb8, 0x2e, 0x66, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x6a, 0x18, 0x02, 0xd4, 0x06, 0x21, 0x10, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xe3, 0xd5, 0x02, 0xd4, 0x5e, 0x26, 0xb8, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x73, 0xf5, 0x02, 0xd4, 0x76, 0x2a, 0x0c, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xf6, 0x95, 0x02, 0xd4, 0xd4, 0x2d, 0x8e, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xcc, 0x70, 0x02, 0xd4, 0x3a, 0x2a, 0xe2, 0x13, 0x08, 0x80, + 0x01, 0x00, 0x89, 0x3d, 0x02, 0xd4, 0x94, 0x2a, 0x2c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x67, 0xd6, 0x02, 0xd4, 0xd8, 0x21, 0x1c, 0x19, 0x08, 0x80, + 0x01, 0x00, 0x88, 0xde, 0x02, 0xd4, 0x34, 0x28, 0xc4, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x40, 0x95, 0x02, 0xd4, 0x28, 0x2a, 0x1a, 0x12, 0x08, 0x80, + 0x01, 0x00, 0x34, 0xb9, 0x02, 0xd4, 0xa4, 0x20, 0x34, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x64, 0x57, 0x02, 0xd4, 0x8a, 0x28, 0xbe, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x92, 0x73, 0x02, 0xd4, 0x9c, 0x22, 0x66, 0x14, 0x08, 0x80, + 0x01, 0x00, 0x53, 0x1d, 0x02, 0xd4, 0xe2, 0x28, 0x3c, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x44, 0xd8, 0x02, 0xd4, 0x20, 0x20, 0x28, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xef, 0xb4, 0x02, 0xd4, 0xb8, 0x29, 0x96, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x6d, 0x7c, 0x02, 0xd4, 0x46, 0x22, 0x82, 0x19, 0x08, 0x80, + 0x01, 0x00, 0x29, 0x16, 0x02, 0xd4, 0x6c, 0x22, 0x5c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x01, 0x53, 0x02, 0xd4, 0xcc, 0x21, 0x7a, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x83, 0xb5, 0x02, 0xd4, 0x6e, 0x26, 0xd0, 0x13, 0x08, 0x80, + 0x01, 0x00, 0x27, 0x0f, 0x02, 0xd4, 0x50, 0x2b, 0x4e, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x64, 0x37, 0x02, 0xd4, 0x22, 0x22, 0x78, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x90, 0x6d, 0x02, 0xd4, 0xf2, 0x2e, 0x54, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x0a, 0xdb, 0x02, 0xd4, 0xb0, 0x2d, 0xb2, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x76, 0xd6, 0x02, 0xd4, 0xf0, 0x2a, 0xf0, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x66, 0xbf, 0x02, 0xd4, 0x9c, 0x27, 0xd4, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x49, 0xbe, 0x02, 0xd4, 0xb2, 0x21, 0xda, 0x15, 0x08, 0x80, + 0x01, 0x00, 0xb6, 0x7a, 0x02, 0xd4, 0x3c, 0x2f, 0x6c, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xe5, 0xd4, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0xba, 0x3e +}; + +const unsigned char __aligned(4) nrf_wifi_lmac_patch_sec_bin[] = { + 0xc0, 0x0a, 0x87, 0xed, 0x65, 0x94, 0x05, 0x00, 0xb9, 0x41, 0x01, 0x80, + 0x39, 0x33, 0x45, 0x1a, 0xb9, 0x45, 0x41, 0x69, 0x0c, 0x8d, 0x81, 0xed, + 0x62, 0xb4, 0x08, 0x00, 0xa3, 0x41, 0x00, 0xa4, 0x43, 0xfc, 0xc8, 0x2d, + 0x40, 0x00, 0x8c, 0x52, 0x43, 0xf8, 0xc8, 0x2d, 0xbf, 0x45, 0xa3, 0x41, + 0x00, 0xa4, 0x43, 0xfc, 0xc8, 0x2d, 0x42, 0x50, 0x00, 0x04, 0x43, 0xf8, + 0xc8, 0x2d, 0xbf, 0x45, 0x55, 0x4f, 0xa2, 0x41, 0x01, 0x80, 0x3d, 0x22, + 0x50, 0xd1, 0x42, 0x30, 0x39, 0x17, 0xe2, 0x45, 0x04, 0x0e, 0x10, 0xb4, + 0x6d, 0x00, 0xa4, 0x41, 0x01, 0xa4, 0xa2, 0x41, 0x04, 0x80, 0x84, 0x50, + 0x00, 0xbc, 0x81, 0xed, 0x42, 0x30, 0xc8, 0x5e, 0xbd, 0x30, 0x0c, 0x01, + 0xc0, 0xe9, 0x40, 0xe8, 0x65, 0x0c, 0x82, 0x30, 0x40, 0x00, 0x22, 0xfd, + 0x00, 0x00, 0x02, 0xfd, 0x04, 0x00, 0xa2, 0x6b, 0x23, 0x6b, 0x28, 0x6d, + 0x23, 0xf9, 0x00, 0x00, 0x03, 0xf9, 0x04, 0x00, 0xb2, 0xeb, 0x33, 0xeb, + 0x82, 0xb4, 0xf1, 0xff, 0xb8, 0x6d, 0xa6, 0x41, 0x01, 0xa4, 0xc6, 0x50, + 0x04, 0xbc, 0xfd, 0x30, 0x4c, 0x01, 0x45, 0x0c, 0x5d, 0x07, 0x20, 0x6a, + 0xac, 0x05, 0x22, 0x6d, 0x30, 0xea, 0xe2, 0xb4, 0xfa, 0xff, 0x89, 0x6d, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x08, 0x5f, 0x82, 0x30, 0xf0, 0x00, + 0x22, 0xfd, 0x00, 0x00, 0x02, 0xfd, 0x04, 0x00, 0xa2, 0x6b, 0x23, 0x6b, + 0x28, 0x6d, 0x23, 0xf9, 0x00, 0x00, 0x03, 0xf9, 0x04, 0x00, 0xb2, 0xeb, + 0x33, 0xeb, 0x82, 0xb4, 0xf1, 0xff, 0xb8, 0x6d, 0x21, 0x6b, 0x02, 0xfd, + 0x00, 0x00, 0x22, 0x6a, 0xa7, 0x41, 0x01, 0xa4, 0xe7, 0x50, 0x44, 0xbc, + 0x09, 0x6d, 0x31, 0xeb, 0x03, 0xf9, 0x00, 0x00, 0x32, 0xea, 0x2f, 0x07, + 0x20, 0x6a, 0xac, 0x05, 0x22, 0x6d, 0x30, 0xea, 0x45, 0xb4, 0xfa, 0xff, + 0xa3, 0x41, 0x00, 0xa5, 0x63, 0x50, 0x34, 0x9a, 0x30, 0x69, 0x40, 0x00, + 0x0c, 0x50, 0x42, 0x50, 0x00, 0x07, 0x30, 0xe9, 0x47, 0xfc, 0xbc, 0xff, + 0x47, 0xf8, 0xbc, 0xff, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xf5, 0x15, + 0xe2, 0x45, 0x00, 0x0c, 0xa3, 0x41, 0x00, 0xa4, 0x43, 0xfc, 0xc8, 0x2d, + 0x3d, 0x22, 0x50, 0x51, 0x42, 0x50, 0x00, 0x02, 0x43, 0xf8, 0xc8, 0x2d, + 0x9f, 0x45, 0xad, 0x4c, 0xf1, 0x4f, 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, + 0x00, 0xbc, 0x01, 0xed, 0xa8, 0x41, 0x04, 0x80, 0x30, 0xe9, 0xa8, 0x30, + 0x00, 0x00, 0xa6, 0x41, 0x04, 0x80, 0xa2, 0x41, 0x04, 0x80, 0xe3, 0x0c, + 0xc6, 0x30, 0x40, 0x01, 0xd7, 0x06, 0x30, 0xe8, 0x42, 0x30, 0x04, 0x00, + 0x20, 0x6a, 0xaa, 0x05, 0x22, 0x6d, 0x30, 0xea, 0xc2, 0xb4, 0xfa, 0xff, + 0xa4, 0x41, 0x00, 0xa5, 0xa8, 0xfc, 0x00, 0x00, 0x84, 0x50, 0x34, 0x9a, + 0xa3, 0x41, 0x02, 0xa5, 0xc4, 0x30, 0x20, 0x9a, 0xf0, 0xea, 0x43, 0x31, + 0x24, 0x0c, 0x84, 0x31, 0x04, 0x00, 0x64, 0x31, 0x08, 0x00, 0xb6, 0x6d, + 0x24, 0x31, 0x28, 0xff, 0x04, 0x31, 0x08, 0x9a, 0xc7, 0xc8, 0xa6, 0x41, + 0x04, 0x80, 0x80, 0xc8, 0x81, 0xc9, 0x62, 0xc9, 0x43, 0xc9, 0x64, 0xc8, + 0x25, 0xc9, 0x06, 0xc9, 0x83, 0x6e, 0x04, 0xcc, 0xc6, 0x30, 0x60, 0x01, + 0x50, 0x6a, 0xd2, 0x6e, 0xa0, 0x69, 0x22, 0x6d, 0xb0, 0x25, 0xc0, 0xe9, + 0xc2, 0xb4, 0xf8, 0xff, 0x00, 0x0c, 0x9f, 0x45, 0x11, 0x4c, 0x00, 0x0c, + 0xf5, 0x4f, 0x44, 0x45, 0xb0, 0x41, 0x01, 0xa4, 0x10, 0x52, 0x00, 0xbc, + 0x01, 0xed, 0x00, 0xe9, 0xa2, 0x41, 0x01, 0x80, 0x00, 0xe8, 0x42, 0x30, + 0xfd, 0x19, 0xe2, 0x45, 0x00, 0x0c, 0x00, 0x69, 0x42, 0x50, 0x02, 0x00, + 0x00, 0xe9, 0x04, 0x45, 0x06, 0x47, 0x00, 0x0c, 0x42, 0x69, 0x81, 0xee, + 0xa2, 0x94, 0x14, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x6c, 0x23, + 0xa2, 0x69, 0x43, 0x6a, 0xb0, 0x6d, 0xa4, 0x94, 0x06, 0x00, 0xa2, 0xe9, + 0xa4, 0x69, 0xb0, 0x6d, 0xa4, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0xa3, 0x69, + 0xb0, 0x6d, 0xa3, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0xb9, 0x41, 0x01, 0x80, + 0x39, 0x33, 0x31, 0x1c, 0xb9, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x02, 0xa5, + 0x62, 0xfc, 0x10, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, + 0x08, 0x60, 0x62, 0xfc, 0x14, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, + 0x64, 0xf8, 0x0c, 0x60, 0x62, 0xfc, 0x18, 0x0d, 0xa4, 0x41, 0x04, 0x80, + 0xb1, 0x25, 0x64, 0xf8, 0x10, 0x60, 0x62, 0xfc, 0x1c, 0x0d, 0xa4, 0x41, + 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0x14, 0x60, 0x62, 0xfc, 0x20, 0x0d, + 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0x18, 0x60, 0x62, 0xfc, + 0x24, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0x1c, 0x60, + 0x62, 0xfc, 0x28, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, + 0x20, 0x60, 0x62, 0xfc, 0x2c, 0x0d, 0xa4, 0x41, 0x04, 0x80, 0xb1, 0x25, + 0x64, 0xf8, 0x24, 0x60, 0x62, 0xfc, 0x30, 0x0d, 0xa4, 0x41, 0x04, 0x80, + 0xb1, 0x25, 0x64, 0xf8, 0x28, 0x60, 0x62, 0xfc, 0x34, 0x0d, 0xa4, 0x41, + 0x04, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0x2c, 0x60, 0x42, 0xfc, 0x38, 0x0d, + 0xa3, 0x41, 0x04, 0x80, 0x21, 0x25, 0x9f, 0x45, 0x43, 0xf8, 0x30, 0x60, + 0x44, 0xfc, 0xbc, 0x01, 0x25, 0x2d, 0x32, 0xad, 0xa2, 0x41, 0x04, 0x80, + 0x64, 0xfc, 0xc8, 0x01, 0xa2, 0xfc, 0x08, 0x60, 0x44, 0x34, 0xbc, 0x01, + 0x63, 0x00, 0xac, 0x28, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0x8c, 0x52, + 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x04, 0x80, 0xa5, 0xfc, 0x14, 0x60, + 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0xcc, 0x5a, 0x44, 0x38, 0xbc, 0x01, + 0xa5, 0x41, 0x04, 0x80, 0xa5, 0xfc, 0x20, 0x60, 0xa3, 0x00, 0x50, 0x18, + 0x43, 0x00, 0x0c, 0x63, 0x44, 0x38, 0xbc, 0x01, 0x64, 0xfc, 0xbc, 0x01, + 0x63, 0xd0, 0x18, 0x00, 0x8a, 0x8d, 0xa3, 0x41, 0x04, 0x80, 0x63, 0xfc, + 0x2c, 0x60, 0xb5, 0x25, 0x43, 0x00, 0x4c, 0x73, 0x44, 0x38, 0xbc, 0x01, + 0xbf, 0x45, 0x63, 0xfc, 0x2c, 0x60, 0x43, 0x00, 0x4c, 0x73, 0x9f, 0x45, + 0x44, 0x38, 0xbc, 0x01, 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xe9, 0x42, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0x44, 0x34, 0xbc, 0x01, + 0x64, 0x14, 0x15, 0x01, 0x40, 0x00, 0x4c, 0x4a, 0x87, 0x8d, 0x44, 0x38, + 0xbc, 0x01, 0xe5, 0x4b, 0x01, 0xed, 0x44, 0x18, 0xf4, 0x01, 0x06, 0x47, + 0xe5, 0x4b, 0x04, 0x18, 0xf4, 0x01, 0x06, 0x47, 0xb9, 0x41, 0x02, 0x80, + 0x60, 0x30, 0xb0, 0x03, 0xa2, 0x41, 0x04, 0x80, 0x39, 0x33, 0xd5, 0x09, + 0x99, 0x45, 0x62, 0xf8, 0x9c, 0x0e, 0x00, 0x0c, 0xed, 0x4f, 0x08, 0xed, + 0x75, 0x45, 0x05, 0x0e, 0x44, 0x0e, 0x45, 0x94, 0x27, 0x00, 0x66, 0x0e, + 0x05, 0xed, 0x45, 0xb4, 0x10, 0x00, 0x44, 0xb0, 0x01, 0x04, 0x0f, 0xad, + 0xb1, 0x41, 0x08, 0x80, 0x44, 0x02, 0x40, 0x50, 0x52, 0x00, 0x00, 0x28, + 0x42, 0x02, 0xd0, 0x11, 0x24, 0x25, 0x42, 0x02, 0x50, 0x91, 0x52, 0x02, + 0x00, 0x18, 0xb1, 0x41, 0x08, 0x80, 0xc0, 0x86, 0x31, 0x32, 0x23, 0x19, + 0xf1, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0xca, 0x86, 0x42, 0x30, + 0x29, 0x19, 0xe2, 0x45, 0x00, 0x0c, 0xcc, 0x86, 0x31, 0x0f, 0x35, 0x45, + 0x99, 0x45, 0x15, 0x4c, 0xa2, 0x41, 0x07, 0x00, 0x42, 0x50, 0x20, 0xa1, + 0xb1, 0x41, 0x08, 0x80, 0x54, 0x44, 0x60, 0x50, 0x50, 0xc3, 0xc0, 0x86, + 0x31, 0x32, 0x23, 0x19, 0xd1, 0x45, 0x43, 0x00, 0x58, 0x90, 0xa2, 0x41, + 0x08, 0x80, 0xca, 0x86, 0x42, 0x30, 0x29, 0x19, 0xe2, 0x45, 0x00, 0x0c, + 0xcc, 0x86, 0x31, 0x0f, 0x35, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x00, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0xfc, 0x34, 0x0e, 0xe2, 0x40, 0x06, 0x00, + 0x42, 0x14, 0x76, 0x00, 0x42, 0xb0, 0x10, 0x00, 0xe2, 0x40, 0x16, 0x00, + 0xf5, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xcf, 0x12, 0x44, 0x45, + 0xe2, 0x45, 0x04, 0x0e, 0x05, 0x8d, 0xb9, 0x41, 0x02, 0x80, 0x01, 0xed, + 0x04, 0x45, 0x06, 0x47, 0x90, 0x0c, 0xc0, 0x0c, 0x83, 0xee, 0x39, 0x33, + 0xa9, 0x95, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0x9f, 0x45, 0x01, 0xed, + 0xa2, 0x41, 0x04, 0x80, 0xc2, 0xfc, 0xe0, 0x0d, 0x67, 0x6b, 0x05, 0xaf, + 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0x69, 0xf7, 0xb9, 0x45, 0xf1, 0x4f, + 0x64, 0x45, 0xb2, 0x41, 0x02, 0x80, 0x04, 0x0e, 0x25, 0x0e, 0xc0, 0x0c, + 0x52, 0x32, 0xa9, 0x95, 0x83, 0xee, 0xf2, 0x45, 0x01, 0xee, 0xa2, 0x41, + 0x02, 0x80, 0x98, 0x86, 0x42, 0x30, 0x69, 0xf7, 0xe2, 0x45, 0x00, 0x0c, + 0x32, 0x0f, 0xc0, 0x0c, 0x83, 0xee, 0x80, 0x0c, 0x24, 0x45, 0x99, 0x45, + 0x11, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x64, 0x45, + 0x42, 0x30, 0x49, 0x42, 0xb2, 0x41, 0x08, 0x80, 0xb1, 0x41, 0x03, 0x80, + 0xc2, 0x45, 0xb0, 0x41, 0x08, 0x80, 0x52, 0x32, 0x3f, 0x15, 0x31, 0x32, + 0x6d, 0xc2, 0x10, 0x32, 0x7c, 0x49, 0x90, 0x0c, 0xf1, 0x45, 0xff, 0xee, + 0x7c, 0x8d, 0x82, 0x0c, 0xf2, 0x45, 0x00, 0x0c, 0xf9, 0xcf, 0x90, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0xf1, 0x19, 0xe5, 0xcb, + 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, 0xe5, 0x4b, 0x42, 0x30, + 0xb4, 0x1a, 0x81, 0xed, 0x62, 0x60, 0x17, 0x80, 0x62, 0x60, 0x14, 0x90, + 0x06, 0x47, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, 0x02, 0xa5, 0x04, 0xc8, + 0x42, 0xfc, 0x00, 0x28, 0x46, 0x45, 0x42, 0x00, 0x2c, 0x04, 0x11, 0x8d, + 0xb0, 0x41, 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, 0x50, 0x14, 0xc0, 0x0b, + 0x0a, 0xad, 0x85, 0xed, 0x50, 0xfc, 0x60, 0x0b, 0x62, 0x94, 0x2b, 0x00, + 0x84, 0xed, 0x62, 0x94, 0x0a, 0x00, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0xfd, 0x25, 0xe2, 0x45, 0x00, 0x0c, 0x06, 0x45, + 0x08, 0x47, 0x42, 0x30, 0x8b, 0x14, 0x89, 0x6e, 0xe2, 0x45, 0x01, 0xee, + 0x50, 0xfc, 0x68, 0x0b, 0x64, 0x48, 0x62, 0x00, 0x90, 0x13, 0x6d, 0x8d, + 0x07, 0xef, 0x88, 0xee, 0x80, 0x30, 0xb8, 0x0b, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x1d, 0x19, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xe7, 0x15, 0xe2, 0x45, 0x00, 0x0c, 0xde, 0xcf, 0xa2, 0x41, + 0x02, 0x80, 0x07, 0xef, 0x88, 0xee, 0xee, 0xcf, 0x80, 0x30, 0x88, 0x13, + 0xe9, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x80, 0xaf, 0xbd, 0x22, + 0x18, 0xd0, 0xe2, 0x45, 0x24, 0x0e, 0x02, 0x94, 0xc8, 0x00, 0xb2, 0x41, + 0x04, 0x80, 0x22, 0x62, 0x0b, 0x00, 0x52, 0x32, 0xe8, 0x02, 0x02, 0x0e, + 0x22, 0x62, 0x08, 0x10, 0x52, 0xfc, 0x54, 0x0b, 0x0e, 0xad, 0x14, 0xed, + 0x51, 0x94, 0x94, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0xc2, 0x86, + 0x42, 0x30, 0x6b, 0x16, 0xe2, 0x45, 0x00, 0x0c, 0xbd, 0x22, 0x18, 0x50, + 0x0c, 0x47, 0x51, 0xb4, 0x3d, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x00, 0x00, + 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, 0x9c, 0xfe, 0xec, 0x81, 0x54, 0x30, + 0x01, 0x00, 0x5c, 0xf8, 0xec, 0x81, 0x50, 0x60, 0x17, 0x00, 0x50, 0x60, + 0x14, 0x10, 0x33, 0x8d, 0xb3, 0x41, 0x04, 0x80, 0x73, 0x32, 0x20, 0x0f, + 0x53, 0xfc, 0x7c, 0x02, 0x72, 0x14, 0xc0, 0x0b, 0x20, 0x6d, 0x03, 0xb4, + 0xad, 0x00, 0x53, 0xf8, 0x7c, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xe1, 0x15, 0xe2, 0x45, 0x02, 0xee, 0x5c, 0xfc, 0xe8, 0x81, 0x9c, 0xfa, + 0xec, 0x81, 0x4d, 0xad, 0xa2, 0x41, 0x08, 0x80, 0x5c, 0xfc, 0xec, 0x81, + 0x48, 0xad, 0xa2, 0x41, 0x08, 0x80, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, + 0xa0, 0x00, 0xa2, 0x40, 0xbe, 0xff, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, + 0x00, 0x18, 0xbb, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, + 0xe2, 0x45, 0x02, 0xee, 0xb4, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x79, 0xc9, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x94, + 0x6f, 0x00, 0xa2, 0x41, 0x08, 0x80, 0xb3, 0x41, 0x04, 0x80, 0xa2, 0x41, + 0x04, 0x80, 0x73, 0x32, 0x20, 0x0f, 0x62, 0xfc, 0xc4, 0x02, 0x53, 0xfc, + 0x80, 0x02, 0x43, 0x94, 0x87, 0x00, 0x00, 0x0c, 0x53, 0xfc, 0x84, 0x02, + 0x20, 0x6d, 0x53, 0xf8, 0x84, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xe1, 0x15, 0xe2, 0x45, 0x01, 0xee, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, + 0x54, 0xaf, 0xe2, 0x45, 0x90, 0x0c, 0x52, 0x14, 0xc0, 0x0b, 0x02, 0xb4, + 0xa4, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x5c, 0xfc, 0xe8, 0x81, 0x9c, 0xfa, + 0xec, 0x81, 0xa2, 0x40, 0x83, 0xff, 0x5c, 0xfc, 0xec, 0x81, 0xa2, 0x40, + 0x7f, 0xff, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, 0xa0, 0x00, 0xa2, 0x40, + 0x79, 0xff, 0x00, 0x00, 0x7c, 0x57, 0x76, 0xcf, 0x00, 0x00, 0x00, 0x18, + 0x52, 0x14, 0xc0, 0x0b, 0x02, 0x94, 0x6b, 0xff, 0xa2, 0x41, 0x08, 0x80, + 0x72, 0xfc, 0x58, 0x0b, 0x02, 0xed, 0x43, 0xb4, 0x64, 0xff, 0xa2, 0x41, + 0x08, 0x80, 0x50, 0x60, 0x17, 0x00, 0x50, 0x60, 0x14, 0x10, 0xa2, 0x40, + 0x70, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, + 0xb0, 0x02, 0xb0, 0x6d, 0x62, 0xf8, 0xb0, 0x02, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xc5, 0x16, 0xe2, 0x45, 0x02, 0xee, 0x4c, 0xcf, 0xa2, 0x41, + 0x08, 0x80, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, + 0x02, 0xee, 0x17, 0x6a, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x71, 0x16, + 0xe2, 0x45, 0xb1, 0x0c, 0xe0, 0x40, 0x40, 0xff, 0x80, 0x86, 0x42, 0x30, + 0xe1, 0x12, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xe1, 0x15, 0xe2, 0x45, 0x01, 0xee, 0x5f, 0xcf, 0x5c, 0xfc, 0xe8, 0x81, + 0xa5, 0x41, 0x00, 0x00, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x4d, 0x1b, + 0xa5, 0x30, 0x00, 0x00, 0xe2, 0x45, 0x01, 0xee, 0x53, 0xfc, 0xb4, 0x02, + 0xb2, 0x41, 0x08, 0x80, 0x52, 0x32, 0xc5, 0x16, 0x20, 0x6d, 0x53, 0xf8, + 0xb4, 0x02, 0xf2, 0x45, 0x02, 0xee, 0x41, 0xcf, 0xa2, 0x41, 0x08, 0x80, + 0x52, 0x14, 0xc0, 0x0b, 0x0e, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0xb2, 0x41, + 0x08, 0x80, 0x52, 0x32, 0xc5, 0x16, 0xf2, 0x45, 0x01, 0xee, 0x81, 0xed, + 0x62, 0xb4, 0xd1, 0xff, 0x00, 0x0c, 0xe0, 0x40, 0xea, 0xff, 0x42, 0x30, + 0x85, 0x14, 0xe2, 0x45, 0x00, 0x0c, 0x20, 0x6e, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x8b, 0x14, 0xe2, 0x45, 0x89, 0x6e, 0x52, 0xfc, 0x68, 0x0b, + 0x64, 0x48, 0x62, 0x00, 0x90, 0x13, 0xa2, 0x40, 0x17, 0x00, 0x53, 0xfc, + 0x70, 0x02, 0x20, 0x6d, 0xb8, 0xcf, 0x53, 0xf8, 0x70, 0x02, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, 0xb4, 0x02, 0xb0, 0x6d, + 0x91, 0xcf, 0x62, 0xf8, 0xb4, 0x02, 0x42, 0x30, 0xc5, 0x16, 0xe2, 0x45, + 0x02, 0xee, 0x5b, 0xcf, 0x5c, 0xfc, 0xe8, 0x81, 0xa2, 0x41, 0x08, 0x80, + 0x86, 0x86, 0x42, 0x30, 0xe1, 0x12, 0xc2, 0x45, 0x73, 0xf8, 0x74, 0x02, + 0x9e, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0x00, 0x0c, 0x20, 0xed, 0x44, 0x94, + 0x05, 0x00, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0xed, 0x8b, 0xb9, 0x45, + 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x5a, 0x6e, 0x42, 0x30, 0x5d, 0x4c, + 0x44, 0x45, 0xe2, 0x45, 0x05, 0x0e, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, + 0x54, 0xaf, 0xe2, 0x45, 0x90, 0x0c, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, + 0x61, 0x14, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0xb9, 0x4f, 0x3d, 0x23, + 0x68, 0xd0, 0x14, 0xc8, 0x04, 0x0e, 0x25, 0x0e, 0x16, 0xc8, 0x17, 0xc8, + 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, 0x5c, 0xfc, 0xec, 0x81, + 0xb6, 0x41, 0x04, 0x80, 0xd6, 0x32, 0x20, 0x0f, 0x62, 0x0c, 0x56, 0xfc, + 0x58, 0x01, 0xb2, 0x41, 0x08, 0x80, 0x79, 0xc8, 0x20, 0x6d, 0x56, 0xf8, + 0x58, 0x01, 0xa2, 0x41, 0x03, 0x80, 0xb0, 0x6d, 0x92, 0x30, 0xc8, 0x45, + 0x42, 0x30, 0xc9, 0xd0, 0x7c, 0xf8, 0xec, 0x81, 0xe2, 0x45, 0x00, 0x0c, + 0x02, 0x94, 0x6c, 0x01, 0xa2, 0x0c, 0xe2, 0x0e, 0xa2, 0x41, 0x03, 0x80, + 0x42, 0x30, 0xe5, 0xd0, 0xc2, 0x45, 0x92, 0x30, 0xc8, 0x45, 0xb3, 0x41, + 0x01, 0x80, 0x01, 0xed, 0x73, 0x32, 0x61, 0xda, 0xb0, 0x0c, 0x2f, 0x6e, + 0x03, 0xef, 0x37, 0xfa, 0x10, 0x00, 0xd3, 0x45, 0x57, 0xf8, 0x1c, 0x00, + 0x5c, 0xfc, 0xd4, 0xa8, 0xd7, 0x4b, 0x03, 0xef, 0xb0, 0x30, 0x03, 0x00, + 0x97, 0x30, 0x18, 0x00, 0xd3, 0x45, 0x5e, 0x00, 0x50, 0xf1, 0x2f, 0x6e, + 0x03, 0xef, 0xd3, 0x45, 0xb0, 0x30, 0x06, 0x00, 0x37, 0x4a, 0xb2, 0x41, + 0x04, 0x80, 0x18, 0xef, 0xbe, 0x0c, 0x92, 0x30, 0x80, 0x61, 0xd3, 0x45, + 0x17, 0xf8, 0x0c, 0x00, 0x51, 0xb0, 0x15, 0x00, 0x02, 0xb4, 0xcf, 0x00, + 0xb4, 0x41, 0x02, 0x80, 0x54, 0x30, 0x85, 0xc3, 0xb0, 0x41, 0x04, 0x80, + 0x10, 0x32, 0xe8, 0x02, 0x46, 0xcc, 0x58, 0xc8, 0x96, 0x48, 0x64, 0xb0, + 0x05, 0x00, 0x03, 0xb4, 0x77, 0x00, 0x74, 0x00, 0x3c, 0x2b, 0x03, 0x40, + 0x1f, 0x01, 0x00, 0x0c, 0x74, 0xd0, 0x40, 0x00, 0xe3, 0x40, 0x05, 0x00, + 0x76, 0xfc, 0x80, 0x01, 0xb0, 0x6d, 0x76, 0xf8, 0x80, 0x01, 0x77, 0xfc, + 0x0c, 0x00, 0x76, 0xfd, 0x68, 0x01, 0x89, 0x6e, 0x03, 0x31, 0x14, 0x00, + 0xc3, 0x30, 0xa8, 0x00, 0x08, 0x01, 0x00, 0x10, 0x62, 0x27, 0x65, 0x00, + 0x50, 0x61, 0x3e, 0x31, 0x18, 0x00, 0x98, 0x4c, 0x62, 0x4d, 0x17, 0x01, + 0x50, 0x41, 0xd7, 0x00, 0x50, 0x31, 0xb0, 0x6d, 0x76, 0xf9, 0x68, 0x01, + 0x8c, 0x1a, 0x00, 0x00, 0x28, 0xf9, 0x00, 0x00, 0x60, 0xaa, 0x02, 0x94, + 0x8c, 0x00, 0x77, 0xf8, 0x0c, 0x00, 0x56, 0xfc, 0x70, 0x01, 0x20, 0x6d, + 0x56, 0xf8, 0x70, 0x01, 0x40, 0xed, 0x43, 0x94, 0x52, 0x00, 0xbe, 0x02, + 0x50, 0xf1, 0x51, 0xb0, 0x15, 0x00, 0x02, 0xb4, 0x86, 0x00, 0x5c, 0xfc, + 0xa8, 0xa7, 0x04, 0xef, 0xbe, 0x0c, 0xf3, 0x45, 0x2d, 0x6e, 0x56, 0x48, + 0xa2, 0x32, 0x19, 0x00, 0xb1, 0x02, 0x90, 0x1b, 0x03, 0xb4, 0x75, 0x00, + 0x62, 0xb0, 0x04, 0x00, 0x03, 0xb4, 0x71, 0x00, 0x5e, 0x00, 0x50, 0x11, + 0x82, 0x16, 0x18, 0x00, 0x58, 0x48, 0x92, 0x30, 0x80, 0x61, 0xc2, 0x45, + 0xb1, 0x02, 0xd0, 0x89, 0x70, 0xfc, 0x94, 0x0b, 0x50, 0x0d, 0x83, 0xb0, + 0x0a, 0x00, 0x05, 0xae, 0x23, 0x31, 0x01, 0x00, 0x20, 0x31, 0x01, 0x00, + 0x60, 0x0c, 0x92, 0x30, 0x80, 0x61, 0xc4, 0x14, 0x13, 0x00, 0x04, 0x15, + 0x04, 0x00, 0xb0, 0x05, 0x94, 0xd0, 0x01, 0x00, 0xc3, 0x18, 0x88, 0x0b, + 0x30, 0xf9, 0x94, 0x0b, 0xd7, 0xf8, 0x44, 0x00, 0x04, 0xb4, 0x86, 0xff, + 0x17, 0x19, 0x4d, 0x00, 0xe2, 0x40, 0x3b, 0x00, 0x56, 0xfc, 0x74, 0x01, + 0x20, 0x6d, 0x56, 0xf8, 0x74, 0x01, 0x56, 0xfc, 0x6c, 0x01, 0x77, 0xfc, + 0x0c, 0x00, 0x20, 0x6d, 0x56, 0xf8, 0x6c, 0x01, 0x40, 0xed, 0x43, 0xb4, + 0xb2, 0xff, 0xbe, 0x02, 0x50, 0xf1, 0x5c, 0xfc, 0xa8, 0xa7, 0xa0, 0x6d, + 0x57, 0xf8, 0x14, 0x00, 0x4a, 0xfc, 0xd4, 0x04, 0x02, 0x94, 0x40, 0x00, + 0x7c, 0xf8, 0xa8, 0xa7, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xcb, 0x19, + 0xe2, 0x45, 0x97, 0x0c, 0x79, 0x48, 0x5c, 0xfc, 0xe8, 0x81, 0x7c, 0xf8, + 0xec, 0x81, 0xa2, 0x40, 0x0e, 0x00, 0x5c, 0xfc, 0xec, 0x81, 0xa2, 0x40, + 0x0a, 0x00, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, 0xa0, 0x00, 0xa2, 0x40, + 0x04, 0x00, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, 0x00, 0x18, 0x3d, 0x23, + 0x68, 0x50, 0x9f, 0x45, 0x49, 0x4c, 0x56, 0xfc, 0xa0, 0x01, 0x20, 0x6d, + 0xc6, 0xcf, 0x56, 0xf8, 0xa0, 0x01, 0x56, 0xfc, 0x78, 0x01, 0x20, 0x6d, + 0x77, 0xcf, 0x56, 0xf8, 0x78, 0x01, 0x77, 0xfc, 0x0c, 0x00, 0x5c, 0xfc, + 0xa8, 0xa7, 0x20, 0x6e, 0x9c, 0xf8, 0xa8, 0xa7, 0xcd, 0x8d, 0x57, 0xf8, + 0x14, 0x00, 0xaa, 0x41, 0x04, 0x80, 0x4a, 0x31, 0xe8, 0x02, 0x4a, 0xfc, + 0xd4, 0x04, 0x46, 0xad, 0xa2, 0x41, 0x08, 0x80, 0xb7, 0xfc, 0x50, 0x00, + 0x97, 0x30, 0x20, 0x00, 0xf3, 0x45, 0x02, 0xef, 0x57, 0x34, 0x20, 0x00, + 0x60, 0x30, 0x94, 0x00, 0x82, 0xd0, 0xbc, 0x00, 0x64, 0x94, 0x4e, 0x00, + 0x42, 0xd0, 0xfc, 0x00, 0x60, 0x30, 0xe4, 0x00, 0x62, 0x94, 0x5b, 0x00, + 0xa2, 0x41, 0x08, 0x80, 0xab, 0x6e, 0xf2, 0x30, 0x80, 0x61, 0x29, 0x6f, + 0x42, 0x30, 0x2b, 0x14, 0xe2, 0x45, 0x97, 0x0c, 0xb5, 0x48, 0x05, 0xb4, + 0x45, 0x00, 0xa3, 0x41, 0x08, 0x80, 0x77, 0x34, 0x20, 0x00, 0x24, 0xee, + 0x63, 0xd0, 0xfc, 0x00, 0x83, 0x94, 0x66, 0x00, 0xd4, 0x48, 0x81, 0xed, + 0x62, 0xb4, 0x96, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x57, 0x34, 0x20, 0x00, + 0x42, 0xd0, 0x00, 0x40, 0x02, 0x94, 0x50, 0x00, 0x08, 0xed, 0x5d, 0x1c, + 0x10, 0x00, 0x02, 0x40, 0x87, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xc7, 0x14, 0xe2, 0x45, 0x97, 0x0c, 0x02, 0xb4, 0x57, 0x00, 0x0a, 0xed, + 0x77, 0xfc, 0x28, 0x00, 0x43, 0xb4, 0x42, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x56, 0x34, 0xc4, 0x01, 0x20, 0x6d, 0x74, 0xcf, 0x56, 0x38, 0xc4, 0x01, + 0x76, 0xfc, 0x7c, 0x01, 0xb0, 0x6d, 0xde, 0xce, 0x76, 0xf8, 0x7c, 0x01, + 0x56, 0xfc, 0xb8, 0x01, 0x20, 0x6d, 0x6e, 0xcf, 0x56, 0xf8, 0xb8, 0x01, + 0xa2, 0x41, 0x08, 0x80, 0xb2, 0x30, 0x80, 0x61, 0x42, 0x30, 0xb3, 0x16, + 0xe2, 0x45, 0x97, 0x0c, 0x64, 0xcf, 0x79, 0x48, 0xdd, 0x2e, 0x97, 0x0c, + 0x63, 0x30, 0xd1, 0x19, 0xc3, 0x45, 0x5d, 0xf8, 0x60, 0x00, 0xb5, 0xcf, + 0x58, 0x48, 0x97, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xe5, 0x14, 0xc2, 0x45, 0x84, 0x30, 0x0a, 0x00, 0x02, 0x94, 0x48, 0xff, + 0x57, 0xf8, 0xd8, 0x01, 0xa2, 0x41, 0x08, 0x80, 0x82, 0xee, 0x42, 0x30, + 0xd1, 0x19, 0xe2, 0x45, 0x97, 0x0c, 0x40, 0xcf, 0xa2, 0x41, 0x08, 0x80, + 0x57, 0xf8, 0x28, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xa1, 0x13, + 0xe2, 0x45, 0x97, 0x0c, 0x3a, 0xcf, 0x79, 0x48, 0xa2, 0x41, 0x08, 0x80, + 0xb2, 0x30, 0x80, 0x61, 0x42, 0x30, 0xd1, 0x16, 0xe2, 0x45, 0x97, 0x0c, + 0x93, 0xcf, 0x81, 0xed, 0x77, 0xfc, 0x28, 0x00, 0x43, 0xb4, 0x24, 0xff, + 0x00, 0x0c, 0xac, 0xcf, 0x56, 0x34, 0xc4, 0x01, 0xa4, 0x0c, 0xb9, 0x41, + 0x01, 0x80, 0xa4, 0x41, 0x04, 0x80, 0x44, 0xef, 0x39, 0x33, 0x61, 0xda, + 0x99, 0x45, 0x84, 0x30, 0xa8, 0x60, 0x00, 0x0c, 0xa2, 0x41, 0x01, 0xa4, + 0x81, 0xed, 0x42, 0x50, 0x10, 0xb0, 0xa0, 0xe9, 0xa4, 0x41, 0x00, 0xa4, + 0x44, 0xfc, 0xc8, 0x2d, 0xa3, 0x41, 0x02, 0xa5, 0xb9, 0x41, 0x04, 0x80, + 0x42, 0x50, 0x40, 0x00, 0x44, 0xf8, 0xc8, 0x2d, 0xa2, 0x41, 0x00, 0xa5, + 0x80, 0x30, 0x00, 0x1e, 0x82, 0xf8, 0xd4, 0x3c, 0xa2, 0x41, 0x05, 0x00, + 0x42, 0x50, 0x00, 0xab, 0x43, 0xf8, 0x34, 0x0d, 0x39, 0x33, 0x49, 0x42, + 0x03, 0xf8, 0x18, 0x0d, 0xb9, 0x45, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x85, 0x98, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0x49, 0x42, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0x43, 0xe8, 0x51, 0x69, 0x89, 0xed, + 0x7d, 0x38, 0x0a, 0x00, 0x22, 0x25, 0x51, 0xe9, 0x61, 0x69, 0x8f, 0xed, + 0x7d, 0x38, 0x0c, 0x00, 0x22, 0x25, 0x61, 0xe9, 0x52, 0x69, 0x60, 0x30, + 0xfa, 0xff, 0xab, 0x41, 0xff, 0x01, 0x24, 0x25, 0x52, 0xe9, 0x62, 0x69, + 0xaa, 0x41, 0xff, 0x00, 0x7d, 0x38, 0x02, 0x00, 0x24, 0x25, 0x62, 0xe9, + 0x25, 0xfd, 0x00, 0x00, 0xe0, 0x0c, 0x7d, 0x20, 0x14, 0xd0, 0x49, 0x00, + 0x80, 0xf8, 0x22, 0x01, 0x10, 0x1b, 0x1d, 0x0f, 0xfd, 0x31, 0x08, 0x00, + 0xc4, 0x0d, 0x40, 0x0e, 0xa0, 0x0d, 0x6b, 0x51, 0x25, 0xc0, 0x4a, 0x51, + 0x00, 0xc0, 0x81, 0xec, 0x02, 0xec, 0x20, 0x33, 0x03, 0x00, 0x1d, 0x38, + 0x00, 0x00, 0x1d, 0x38, 0x04, 0x00, 0x1d, 0x38, 0x08, 0x00, 0x87, 0x40, + 0x8d, 0x00, 0xa7, 0x05, 0x43, 0x01, 0x50, 0x13, 0xe2, 0x40, 0xda, 0x00, + 0x03, 0xcc, 0x40, 0x0c, 0xe8, 0x40, 0x08, 0x00, 0x20, 0x6d, 0xb2, 0x25, + 0x42, 0x00, 0x3c, 0x3b, 0xe2, 0xb4, 0xf8, 0xff, 0x43, 0x01, 0x50, 0x43, + 0x52, 0x00, 0x50, 0x43, 0x08, 0x94, 0xba, 0x00, 0x63, 0x01, 0x50, 0x43, + 0x08, 0x94, 0x07, 0x00, 0x2e, 0x6d, 0x20, 0x6d, 0xb4, 0xcc, 0xe0, 0x69, + 0xa8, 0x40, 0x0b, 0x00, 0x2e, 0x6d, 0x42, 0x00, 0x3c, 0x3b, 0x63, 0x00, + 0x80, 0x08, 0x52, 0x00, 0x50, 0x63, 0x0c, 0xb4, 0xf5, 0xff, 0x63, 0x01, + 0x50, 0x43, 0xe0, 0x69, 0x03, 0x01, 0x80, 0xf8, 0x68, 0x00, 0x10, 0x1b, + 0x87, 0x40, 0xa9, 0x00, 0x03, 0x01, 0xd0, 0x19, 0x43, 0x01, 0x50, 0x43, + 0xe8, 0x40, 0xa3, 0x00, 0x03, 0xcc, 0x40, 0x0e, 0xec, 0x40, 0x0b, 0x00, + 0x12, 0x31, 0x01, 0x00, 0x48, 0x02, 0x3c, 0x3b, 0xb2, 0x25, 0xf2, 0x00, + 0x50, 0x43, 0x08, 0xb4, 0xf5, 0xff, 0x43, 0x01, 0x50, 0x63, 0x42, 0x02, + 0x50, 0x1b, 0x82, 0x8d, 0x12, 0x0d, 0x02, 0x0d, 0x2d, 0x96, 0x9e, 0x00, + 0x08, 0x01, 0x3c, 0x3b, 0x0d, 0x96, 0x92, 0x00, 0x00, 0x0c, 0x08, 0x31, + 0xf2, 0xff, 0xe8, 0x00, 0x3c, 0x3b, 0x87, 0x40, 0x5a, 0x00, 0xe0, 0x69, + 0x40, 0x0c, 0x20, 0x6d, 0x42, 0x00, 0x3c, 0x3b, 0x29, 0x01, 0x00, 0x08, + 0x47, 0xb4, 0xf9, 0xff, 0xb2, 0x25, 0x49, 0x30, 0x00, 0x10, 0xe9, 0x90, + 0x00, 0x00, 0xe2, 0x00, 0x18, 0x48, 0x43, 0x30, 0x00, 0x10, 0xe3, 0x90, + 0x00, 0x00, 0xa2, 0x4d, 0xe2, 0x00, 0x18, 0x18, 0x29, 0x01, 0x00, 0x60, + 0x69, 0x00, 0x50, 0x19, 0x4d, 0xd0, 0xff, 0xff, 0x6e, 0xf8, 0x00, 0x00, + 0xa2, 0x01, 0x3c, 0x3b, 0xd2, 0x6e, 0x04, 0x4f, 0xe4, 0x4d, 0x62, 0x6f, + 0x22, 0x97, 0x30, 0x00, 0xc8, 0x4d, 0x25, 0xfd, 0x00, 0x00, 0xef, 0x3c, + 0x00, 0x00, 0x58, 0x3e, 0x00, 0x00, 0x49, 0x00, 0x80, 0xf8, 0x22, 0x01, + 0x10, 0x1b, 0xc7, 0x40, 0x75, 0xff, 0xa7, 0x05, 0x52, 0x40, 0x52, 0x00, + 0x40, 0x0c, 0x63, 0x01, 0x50, 0x13, 0x02, 0x94, 0x8b, 0xff, 0x40, 0x0c, + 0xe0, 0x69, 0xe3, 0x00, 0x80, 0xf8, 0x5f, 0x44, 0xf7, 0x05, 0x63, 0x01, + 0x50, 0x43, 0x08, 0x94, 0x05, 0x00, 0xe0, 0x0c, 0xa6, 0xcf, 0x40, 0x0e, + 0xa8, 0x40, 0x2a, 0x00, 0xfe, 0x6f, 0x63, 0x00, 0x80, 0x08, 0xe7, 0x00, + 0x3c, 0x3b, 0x47, 0xb6, 0xf7, 0xff, 0x63, 0x01, 0x50, 0x43, 0x9b, 0xcf, + 0x42, 0x02, 0x50, 0x1b, 0x7d, 0x20, 0x14, 0x50, 0x08, 0x47, 0x07, 0x94, + 0xae, 0xff, 0xe0, 0x00, 0xd0, 0x39, 0x40, 0x0c, 0x20, 0x6d, 0x03, 0x01, + 0x40, 0xf8, 0x89, 0x01, 0x40, 0xf8, 0x42, 0x00, 0x3c, 0x3b, 0x68, 0x00, + 0x50, 0x19, 0x2c, 0x01, 0x50, 0x49, 0xe2, 0x00, 0x50, 0x43, 0x29, 0x01, + 0x80, 0x08, 0x08, 0xb4, 0xef, 0xff, 0x63, 0x00, 0x80, 0x08, 0x99, 0xcf, + 0x49, 0x30, 0x00, 0x10, 0x78, 0xcf, 0x47, 0x0e, 0xe0, 0x69, 0x03, 0x01, + 0x80, 0xf8, 0x68, 0x00, 0x10, 0x1b, 0x03, 0x01, 0xd0, 0x19, 0x43, 0x01, + 0x50, 0x43, 0xa8, 0x40, 0x5d, 0xff, 0x12, 0x40, 0xbe, 0xff, 0x00, 0x0c, + 0x68, 0xcf, 0x40, 0x0e, 0x31, 0xcf, 0x40, 0x0c, 0x64, 0xcf, 0x40, 0x0e, + 0x43, 0x69, 0x68, 0x00, 0x00, 0x20, 0x34, 0x05, 0x43, 0xe9, 0x69, 0xcf, + 0x25, 0xfd, 0x00, 0x00, 0x43, 0x69, 0x4c, 0x4c, 0x02, 0x01, 0x50, 0x11, + 0x43, 0xe9, 0x61, 0xcf, 0x25, 0xfd, 0x00, 0x00, 0xf1, 0x4f, 0x64, 0x45, + 0x24, 0x62, 0x03, 0x00, 0x04, 0x0e, 0xa2, 0x41, 0x03, 0x80, 0x30, 0x62, + 0x00, 0x10, 0x80, 0x30, 0x2c, 0x01, 0x42, 0x30, 0x65, 0xab, 0xe2, 0x45, + 0x47, 0x0e, 0x11, 0x94, 0x5d, 0x00, 0xb9, 0x41, 0x01, 0x80, 0x08, 0x09, + 0x82, 0x30, 0xdc, 0xff, 0x62, 0x30, 0x9c, 0xff, 0x84, 0x00, 0x3c, 0x2b, + 0x63, 0x00, 0x3c, 0x2b, 0xe4, 0x00, 0x80, 0xf8, 0xc3, 0x00, 0x80, 0xf8, + 0x42, 0x30, 0x5b, 0x00, 0x42, 0x00, 0x3c, 0x2b, 0x67, 0x44, 0x5e, 0x44, + 0xa2, 0x00, 0x80, 0xf8, 0x79, 0x06, 0xe7, 0x05, 0x55, 0x44, 0x84, 0x00, + 0x3c, 0x2b, 0x63, 0x00, 0x3c, 0x2b, 0x55, 0x05, 0x64, 0x00, 0x50, 0x2b, + 0xa0, 0x8e, 0x42, 0x00, 0x3c, 0x2b, 0x44, 0x00, 0x50, 0x13, 0x02, 0xb4, + 0x4b, 0x00, 0x39, 0x33, 0xf9, 0xf4, 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, + 0x0e, 0x00, 0xb9, 0x41, 0x01, 0x80, 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, + 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, + 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x39, 0x33, 0xf9, 0xf4, + 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x43, 0x00, 0x50, 0x13, 0x65, 0x8d, + 0xb9, 0x41, 0x01, 0x80, 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, 0x0d, 0x00, + 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, + 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, + 0x3c, 0x2b, 0x39, 0x33, 0xf9, 0xf4, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, 0x0b, 0x00, 0xa2, 0x00, 0xec, 0x01, + 0x82, 0x00, 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, + 0xd2, 0x26, 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x39, 0x33, + 0xf9, 0xf4, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x52, 0x14, 0x3d, 0x00, + 0x72, 0x1c, 0x0c, 0x00, 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, 0x00, 0xc8, + 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, 0xa5, 0xd0, + 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0xd5, 0x4f, 0x3d, 0x23, 0x30, 0xd0, 0x3f, 0x49, 0x9d, 0x22, 0x68, 0x10, + 0xdd, 0x22, 0x70, 0x10, 0x0f, 0x8e, 0xde, 0x4b, 0xb9, 0x41, 0x02, 0x80, + 0x39, 0x33, 0xfd, 0xa8, 0x9d, 0x22, 0x68, 0x90, 0xdd, 0x22, 0x70, 0x90, + 0xde, 0xcb, 0x3f, 0xc9, 0x3d, 0x23, 0x30, 0x50, 0x99, 0x45, 0x2d, 0x4c, + 0xb0, 0x41, 0x02, 0x80, 0x45, 0x0e, 0x66, 0x0e, 0x83, 0xee, 0xc0, 0x0c, + 0x01, 0xee, 0x10, 0x32, 0xa9, 0x95, 0x27, 0x0e, 0xd0, 0x45, 0x3d, 0xf9, + 0x28, 0x00, 0x2a, 0x49, 0xa2, 0x41, 0x02, 0x80, 0x6a, 0x84, 0x90, 0x87, + 0x42, 0x30, 0xfd, 0xa8, 0x29, 0xc9, 0x9d, 0x22, 0x10, 0x90, 0xdd, 0x22, + 0x18, 0x90, 0xc2, 0x45, 0xdd, 0xfb, 0x20, 0x00, 0x80, 0x0c, 0xc0, 0x0c, + 0xf0, 0x45, 0x83, 0xee, 0xa2, 0x41, 0x04, 0x80, 0x62, 0x30, 0xb4, 0x1a, + 0x63, 0x60, 0x03, 0x00, 0x82, 0x30, 0xb4, 0x1a, 0x64, 0x60, 0x00, 0x10, + 0xe3, 0x40, 0x03, 0x00, 0x3d, 0x23, 0x30, 0x50, 0x16, 0x47, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0xb9, 0x74, 0xe2, 0x45, 0x00, 0x0c, 0x81, 0xed, + 0xa2, 0x41, 0x04, 0x80, 0x62, 0x18, 0xa5, 0x60, 0x3d, 0x23, 0x30, 0x50, + 0x16, 0x47, 0x00, 0x0c, 0xc1, 0x4f, 0x9d, 0x22, 0x6c, 0xd0, 0xb3, 0x41, + 0x04, 0x80, 0x53, 0x14, 0xa5, 0x60, 0x04, 0x0e, 0x3d, 0xfe, 0x90, 0x00, + 0x23, 0x8d, 0x5d, 0xfe, 0xa0, 0x00, 0x45, 0xb0, 0x0f, 0x00, 0x42, 0x70, + 0x01, 0x00, 0x50, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0x81, 0xed, 0x21, 0x6e, + 0x42, 0x30, 0xd9, 0x74, 0xbd, 0x18, 0x48, 0x00, 0xfd, 0x18, 0x4a, 0x00, + 0xf6, 0xc8, 0xbd, 0x20, 0x5c, 0x90, 0x11, 0xca, 0x3d, 0x1a, 0x49, 0x00, + 0x5d, 0x1a, 0x4b, 0x00, 0x7d, 0x18, 0x4c, 0x00, 0xc2, 0x45, 0x7d, 0x18, + 0x4d, 0x00, 0xf6, 0x48, 0xbd, 0x20, 0x5c, 0x10, 0x13, 0x18, 0xa5, 0x60, + 0x5d, 0xfc, 0xbc, 0x00, 0x24, 0xca, 0x4f, 0xc8, 0x5d, 0xfc, 0xb8, 0x00, + 0x48, 0xca, 0x4e, 0xc8, 0x5d, 0xfc, 0xb4, 0x00, 0x4d, 0xc8, 0x5d, 0xfc, + 0xb0, 0x00, 0x4c, 0xc8, 0x5d, 0x14, 0xac, 0x00, 0x4b, 0xc8, 0x5d, 0xfc, + 0xa8, 0x00, 0x4a, 0xc8, 0x5d, 0xfc, 0xa4, 0x00, 0x49, 0xc8, 0x5d, 0xfc, + 0x9c, 0x00, 0x47, 0xc8, 0x5d, 0xfc, 0x98, 0x00, 0x46, 0xc8, 0x5d, 0xfc, + 0x94, 0x00, 0x45, 0xc8, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x49, 0xab, + 0xe2, 0x45, 0x90, 0x0c, 0x9d, 0x22, 0x6c, 0x50, 0x9f, 0x45, 0x41, 0x4c, + 0xe5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x1d, 0x23, 0x14, 0xd0, 0xa2, 0x36, + 0xaa, 0x60, 0xb5, 0xd2, 0x0f, 0x00, 0x55, 0x30, 0xff, 0xff, 0x42, 0xb0, + 0x02, 0x00, 0x02, 0xb4, 0xc2, 0x00, 0x09, 0xed, 0xb5, 0x72, 0x03, 0x00, + 0x80, 0x32, 0x03, 0x00, 0xa0, 0x02, 0x18, 0x10, 0xa0, 0x02, 0x18, 0xa0, + 0xa2, 0x0e, 0x04, 0x94, 0xb0, 0x00, 0xb3, 0x41, 0x08, 0x80, 0xb2, 0x41, + 0x08, 0x80, 0xc4, 0x0e, 0x24, 0x32, 0x3c, 0x00, 0xe0, 0x0e, 0x00, 0x32, + 0xff, 0x3f, 0x73, 0x32, 0x43, 0x11, 0x11, 0xcc, 0x52, 0x32, 0x1f, 0x17, + 0x64, 0x94, 0x36, 0x00, 0x00, 0x0c, 0xc2, 0x00, 0x58, 0x28, 0xd3, 0x45, + 0xdc, 0xfc, 0x48, 0x81, 0xd2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0xc8, 0x4e, + 0xd1, 0x96, 0x2e, 0x00, 0x00, 0x0c, 0xb6, 0xfc, 0x00, 0x00, 0x40, 0x50, + 0x00, 0x90, 0x0f, 0xef, 0x51, 0x26, 0xa9, 0x05, 0x44, 0x00, 0x90, 0x13, + 0x84, 0xd0, 0xff, 0x3f, 0xf7, 0x30, 0x01, 0x00, 0x00, 0x31, 0x04, 0x09, + 0x04, 0x96, 0xeb, 0xff, 0x63, 0xd0, 0xff, 0x3f, 0x43, 0x00, 0x58, 0x20, + 0x44, 0x00, 0x2c, 0x1a, 0x60, 0x30, 0xd4, 0x09, 0xdd, 0x2e, 0xc2, 0x94, + 0xda, 0xff, 0xe7, 0xd2, 0xff, 0x00, 0x85, 0x02, 0xd0, 0x11, 0x2d, 0x2d, + 0x04, 0xb5, 0xce, 0xff, 0xc4, 0x70, 0xd8, 0x09, 0xa5, 0x02, 0xd0, 0x29, + 0xce, 0xcf, 0xdd, 0x2e, 0x85, 0x02, 0xd0, 0x29, 0xca, 0xcf, 0xdd, 0x2e, + 0x17, 0x94, 0x64, 0x00, 0x81, 0xed, 0xb4, 0x41, 0x04, 0x80, 0xb0, 0x41, + 0x04, 0x80, 0xb3, 0x41, 0x08, 0x80, 0xb2, 0x41, 0x08, 0x80, 0x94, 0x32, + 0xb0, 0x60, 0x10, 0x32, 0xec, 0x60, 0x20, 0x32, 0xff, 0x3f, 0x73, 0x32, + 0x43, 0x11, 0x52, 0x32, 0x1f, 0x17, 0x54, 0xfc, 0x00, 0x00, 0x80, 0x50, + 0x00, 0x90, 0x88, 0x4e, 0xad, 0x2e, 0x21, 0x25, 0xc5, 0x05, 0x63, 0xd0, + 0xff, 0x3f, 0x82, 0x00, 0x90, 0x23, 0x42, 0xd0, 0xff, 0x3f, 0x82, 0x00, + 0x18, 0x18, 0x22, 0x96, 0x07, 0x00, 0x83, 0x0c, 0xd3, 0x45, 0xdc, 0xfc, + 0x48, 0x81, 0xd2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0x90, 0xb6, 0xe5, 0xff, + 0xa2, 0x41, 0x04, 0x80, 0x62, 0x14, 0xec, 0x60, 0x01, 0xed, 0x43, 0xb4, + 0x2b, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x62, 0xfc, 0xf0, 0x60, 0xa2, 0x41, + 0x00, 0xa4, 0x42, 0x50, 0x04, 0x99, 0xa0, 0xe9, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0xf4, 0x60, 0x62, 0xf8, 0xd0, 0x00, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0xf8, 0x60, 0x62, 0xf8, 0xd4, 0x00, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0xfc, 0x60, 0x62, 0xf8, 0x00, 0x06, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x00, 0x61, 0x62, 0xf8, 0xd0, 0x06, 0xa3, 0x41, 0x04, 0x80, + 0x63, 0xfc, 0x04, 0x61, 0x62, 0xf8, 0xd4, 0x06, 0xa2, 0x41, 0x04, 0x80, + 0x02, 0x18, 0xa4, 0x60, 0x1d, 0x23, 0x14, 0x50, 0x0e, 0x47, 0x81, 0xed, + 0xa2, 0x41, 0x04, 0x80, 0x9a, 0xcf, 0x62, 0x18, 0xa4, 0x60, 0x80, 0x0e, + 0x46, 0xcf, 0xa0, 0x32, 0x05, 0x00, 0x00, 0x0c, 0xd5, 0x4f, 0xdd, 0x22, + 0x3c, 0xd0, 0x04, 0x0e, 0x3d, 0x22, 0x68, 0x10, 0x7d, 0x22, 0x70, 0x10, + 0x2d, 0x8e, 0xbe, 0x4a, 0x47, 0x14, 0xa8, 0x00, 0xa4, 0x41, 0x04, 0x80, + 0x81, 0xed, 0x62, 0x94, 0x3a, 0x00, 0x44, 0x18, 0xec, 0x60, 0xa2, 0x41, + 0x03, 0x80, 0x90, 0x0c, 0x42, 0x30, 0x85, 0x99, 0x3d, 0x22, 0x10, 0x90, + 0x7d, 0x22, 0x18, 0x90, 0xc2, 0x45, 0xbd, 0xfa, 0x20, 0x00, 0x0e, 0x8c, + 0x01, 0xed, 0x50, 0xb4, 0x08, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x02, 0x18, + 0x0d, 0x61, 0xa2, 0x41, 0x04, 0x80, 0x02, 0x18, 0x08, 0x61, 0xdd, 0x22, + 0x3c, 0x50, 0x16, 0x47, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0xc9, 0x5c, + 0xdd, 0x22, 0x3c, 0x50, 0x99, 0x45, 0x2d, 0x4c, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0xe5, 0x59, 0xbd, 0x20, 0x28, 0x90, 0xc2, 0x45, 0xfd, 0xf8, + 0x30, 0x00, 0xec, 0x48, 0xa4, 0x41, 0x04, 0x80, 0x81, 0xed, 0x47, 0x14, + 0xa8, 0x00, 0xbd, 0x20, 0x28, 0x10, 0x62, 0xb4, 0xca, 0xff, 0x44, 0x18, + 0xec, 0x60, 0x67, 0x15, 0xa9, 0x00, 0x47, 0x15, 0xaa, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0x27, 0x15, 0xab, 0x00, 0x07, 0x15, 0xac, 0x00, 0x62, 0xf9, + 0xf0, 0x60, 0xa2, 0x41, 0x04, 0x80, 0x87, 0x14, 0xad, 0x00, 0x42, 0xf9, + 0xf4, 0x60, 0xa2, 0x41, 0x04, 0x80, 0x67, 0x14, 0xae, 0x00, 0x22, 0xf9, + 0xf8, 0x60, 0xa2, 0x41, 0x04, 0x80, 0x02, 0xf9, 0xfc, 0x60, 0xa2, 0x41, + 0x04, 0x80, 0x82, 0xf8, 0x00, 0x61, 0xa2, 0x41, 0x04, 0x80, 0xa5, 0xcf, + 0x62, 0xf8, 0x04, 0x61, 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0x45, 0x44, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0xb9, 0x41, + 0x03, 0x80, 0x80, 0x30, 0x2c, 0x01, 0x39, 0x33, 0x65, 0xab, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xe5, 0x4f, 0x1d, 0x23, 0x14, 0xd0, 0x86, 0x40, + 0x2d, 0x00, 0xc4, 0x0e, 0x66, 0x32, 0xff, 0xff, 0x73, 0xd2, 0xff, 0xff, + 0x62, 0x4e, 0x73, 0x02, 0x00, 0x10, 0xb7, 0x41, 0x02, 0x80, 0xb5, 0x41, + 0x02, 0x80, 0xb4, 0x41, 0x02, 0x80, 0x47, 0x0e, 0x05, 0x0e, 0x65, 0x02, + 0x50, 0x99, 0xf7, 0x32, 0xf5, 0x57, 0xb5, 0x32, 0xfd, 0x57, 0x94, 0x32, + 0x15, 0x58, 0xf7, 0x45, 0x00, 0x6a, 0x00, 0x6a, 0x32, 0x36, 0x00, 0x00, + 0xf5, 0x45, 0x95, 0x04, 0xb2, 0x34, 0x02, 0x00, 0x31, 0x02, 0x3c, 0x3b, + 0x91, 0x0c, 0xd5, 0x06, 0xd4, 0x45, 0xa5, 0x00, 0x3c, 0x3b, 0x00, 0xe9, + 0x02, 0x6c, 0x70, 0xb6, 0xec, 0xff, 0x00, 0x0c, 0x40, 0x30, 0xae, 0x00, + 0x56, 0x38, 0x00, 0x00, 0x5c, 0x38, 0xca, 0x81, 0x1d, 0x23, 0x14, 0x50, + 0x0e, 0x47, 0x00, 0x0c, 0xe9, 0x4f, 0x52, 0x48, 0x59, 0x45, 0xb1, 0x41, + 0x00, 0xa5, 0x11, 0xfe, 0x44, 0x12, 0x46, 0xc8, 0x51, 0x48, 0x45, 0xc8, + 0x5d, 0x14, 0x40, 0x00, 0x44, 0xc8, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0xb9, 0xa2, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0xff, 0xff, 0x42, 0x30, + 0x00, 0x01, 0x82, 0x44, 0x10, 0x52, 0x00, 0x80, 0x11, 0xfa, 0x44, 0x12, + 0x19, 0x45, 0x0c, 0x47, 0x00, 0x31, 0x14, 0x00, 0x04, 0x01, 0x10, 0x40, + 0x06, 0xb4, 0x42, 0x00, 0x85, 0x49, 0x0e, 0xed, 0x45, 0x94, 0x08, 0x00, + 0xa0, 0x31, 0xb4, 0x09, 0xa5, 0x01, 0x00, 0x10, 0xad, 0x00, 0x50, 0x29, + 0xa5, 0x31, 0x67, 0x09, 0x5d, 0x14, 0x10, 0x00, 0x08, 0x01, 0x40, 0x08, + 0x0d, 0x01, 0xd0, 0x79, 0x44, 0x06, 0x44, 0x01, 0x00, 0x08, 0xca, 0x00, + 0x50, 0x51, 0x4a, 0x31, 0x10, 0x00, 0x4a, 0x01, 0x00, 0x10, 0x0d, 0x01, + 0x50, 0x41, 0xc0, 0x0c, 0x40, 0x0c, 0xc4, 0x0d, 0x47, 0x01, 0x50, 0x51, + 0x44, 0x26, 0x4e, 0x06, 0x24, 0xfd, 0x5c, 0x00, 0x64, 0xfc, 0x54, 0x00, + 0xaa, 0xfc, 0x00, 0x00, 0x8e, 0x0c, 0x69, 0x00, 0x50, 0x18, 0xdc, 0x06, + 0xa3, 0x00, 0x10, 0x1a, 0x60, 0x6f, 0xe3, 0x01, 0x90, 0x2b, 0x03, 0x01, + 0x90, 0x4b, 0x89, 0xae, 0x68, 0x00, 0x90, 0x5b, 0x0b, 0xb4, 0x07, 0x00, + 0xa3, 0x01, 0xd0, 0x19, 0x01, 0xed, 0x6c, 0xf8, 0x00, 0x00, 0xa9, 0x40, + 0xe1, 0xff, 0xbf, 0x45, 0x01, 0xed, 0x46, 0xb4, 0xc7, 0xff, 0xa0, 0x0d, + 0x45, 0xb0, 0xc5, 0x00, 0xa5, 0x01, 0x00, 0x10, 0x60, 0x30, 0x88, 0x13, + 0x20, 0x31, 0xa0, 0x0f, 0x49, 0x00, 0x58, 0x18, 0xad, 0x00, 0x50, 0x29, + 0xb9, 0xcf, 0x65, 0x00, 0x50, 0x69, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x79, 0x74, 0xc4, 0xc8, 0xa5, 0xc8, 0x86, 0xc8, + 0xe9, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xc4, 0x48, 0xa5, 0x48, 0x86, 0x48, + 0xe9, 0x4b, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0x71, 0x4f, 0x99, 0x45, + 0x15, 0x4c, 0x00, 0x0c, 0xd9, 0x4f, 0x05, 0xed, 0x4c, 0xc8, 0x08, 0xed, + 0x48, 0xc8, 0x01, 0xed, 0x5d, 0x22, 0x44, 0xd0, 0x86, 0xc8, 0x25, 0x0e, + 0x04, 0x0e, 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, + 0x0f, 0xc8, 0x9d, 0x8e, 0x45, 0xc8, 0x11, 0x6d, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0x83, 0xef, 0x18, 0xef, 0xa0, 0x0c, 0x42, 0x30, 0x2b, 0x11, + 0xc2, 0x45, 0x80, 0x30, 0x08, 0x10, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, + 0x42, 0x30, 0x1d, 0x0e, 0xe2, 0x45, 0x00, 0x0c, 0x5d, 0x22, 0x44, 0x50, + 0x14, 0x47, 0x19, 0x6d, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0x83, 0xef, + 0x18, 0xef, 0x42, 0x30, 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x08, 0x0a, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, + 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, 0x42, 0x30, 0x1d, 0x0e, 0xe2, 0x45, + 0x00, 0x0c, 0x5d, 0x22, 0x44, 0x50, 0x14, 0x47, 0xf1, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x79, 0xf2, 0x55, 0x45, 0x04, 0x0e, 0xe2, 0x45, + 0x25, 0x0e, 0xb9, 0x41, 0x04, 0x80, 0x98, 0x86, 0x39, 0x33, 0xc5, 0x56, + 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, 0x45, 0x90, 0xf4, 0x01, + 0x3e, 0x8d, 0xa2, 0x41, 0x00, 0xa4, 0x04, 0xb4, 0x7c, 0x00, 0x01, 0xed, + 0x45, 0x90, 0x0f, 0x00, 0x02, 0x94, 0xa7, 0x00, 0x40, 0x30, 0xf8, 0x00, + 0x0e, 0xed, 0x45, 0x94, 0xb0, 0x00, 0x00, 0x0c, 0xde, 0x6d, 0xb4, 0x26, + 0xba, 0x06, 0xa5, 0x30, 0x6c, 0x09, 0xd2, 0x25, 0x56, 0x26, 0x38, 0x06, + 0x5a, 0x25, 0x34, 0x05, 0x4a, 0x26, 0xc7, 0x05, 0x28, 0x26, 0xa2, 0x41, + 0x0f, 0x00, 0x42, 0x30, 0xe9, 0x0b, 0xa6, 0x05, 0xa2, 0x41, 0x19, 0x00, + 0x42, 0x30, 0x21, 0x03, 0x45, 0x05, 0x63, 0x00, 0x80, 0x68, 0x42, 0x00, + 0x80, 0x68, 0x1f, 0xee, 0xc3, 0x90, 0x20, 0x00, 0xa2, 0x90, 0x20, 0x00, + 0xc4, 0x00, 0x58, 0x18, 0xa4, 0x00, 0x58, 0x10, 0x82, 0x90, 0x00, 0x00, + 0xa3, 0x90, 0x00, 0x00, 0xa0, 0x00, 0x18, 0x18, 0x80, 0x00, 0x18, 0x10, + 0xb6, 0x25, 0x48, 0xcc, 0x26, 0x25, 0x42, 0x50, 0x30, 0x97, 0xa0, 0x6b, + 0xc2, 0xfc, 0x00, 0x06, 0x04, 0xb4, 0x59, 0x00, 0x52, 0x26, 0xd6, 0x25, + 0xc6, 0x05, 0xda, 0x26, 0x4a, 0x05, 0xba, 0x25, 0xb9, 0x05, 0xa8, 0x26, + 0xa4, 0x41, 0x0f, 0x00, 0xa2, 0x41, 0x19, 0x00, 0x84, 0x30, 0xe9, 0x0b, + 0x42, 0x30, 0x21, 0x03, 0xc6, 0x05, 0x55, 0x05, 0x63, 0x00, 0x80, 0x68, + 0x42, 0x00, 0x80, 0x68, 0x1f, 0xee, 0xa2, 0x90, 0x20, 0x00, 0x03, 0x91, + 0x20, 0x00, 0x04, 0x01, 0x58, 0x18, 0xa4, 0x00, 0x58, 0x10, 0x82, 0x90, + 0x00, 0x00, 0xa3, 0x90, 0x00, 0x00, 0x80, 0x00, 0x18, 0x10, 0xa0, 0x00, + 0x18, 0x18, 0xb6, 0x25, 0x26, 0x25, 0xe0, 0x00, 0xcc, 0x38, 0x63, 0x50, + 0x04, 0x00, 0xc0, 0x00, 0xcc, 0x38, 0x42, 0x50, 0x04, 0x00, 0xa4, 0x41, + 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, 0xdf, 0x44, 0xd6, 0x44, 0xc0, 0xe9, + 0x44, 0xf8, 0x00, 0x06, 0xbf, 0x45, 0x44, 0x94, 0x31, 0x00, 0x40, 0x30, + 0x88, 0x00, 0xe8, 0xed, 0xa4, 0x41, 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, + 0xc0, 0x6b, 0xc4, 0xfc, 0x00, 0x06, 0x63, 0x50, 0x04, 0x00, 0xe0, 0x00, + 0xcc, 0x38, 0xc0, 0x00, 0xcc, 0x38, 0x42, 0x50, 0x04, 0x00, 0xa4, 0x41, + 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, 0xdf, 0x44, 0xd6, 0x44, 0xc0, 0xe9, + 0x44, 0xf8, 0x00, 0x06, 0xbf, 0x45, 0xd4, 0x25, 0xd6, 0x05, 0x58, 0x25, + 0x54, 0x05, 0xba, 0x25, 0xbb, 0x05, 0x28, 0x26, 0xa5, 0x41, 0x0f, 0x00, + 0xa2, 0x41, 0x19, 0x00, 0xa5, 0x30, 0xe9, 0x0b, 0x42, 0x30, 0x21, 0x03, + 0xd6, 0x05, 0xa8, 0xcf, 0x45, 0x05, 0xd4, 0xcf, 0x60, 0x30, 0xc8, 0x00, + 0xd4, 0x25, 0x45, 0x90, 0xb2, 0x00, 0x0c, 0x8d, 0xd6, 0x05, 0x63, 0x30, + 0x88, 0x13, 0x34, 0x26, 0x38, 0x06, 0x5b, 0xcf, 0x38, 0x25, 0x40, 0x30, + 0xf8, 0x00, 0xc4, 0xcf, 0x60, 0x30, 0xb8, 0x00, 0x63, 0x30, 0xa0, 0x0f, + 0x38, 0x25, 0x34, 0x26, 0x34, 0x05, 0x38, 0x06, 0xa8, 0x26, 0x4a, 0x26, + 0xa2, 0x41, 0x19, 0x00, 0xc7, 0x05, 0x42, 0x30, 0x21, 0x03, 0xa4, 0x41, + 0x0f, 0x00, 0x55, 0x05, 0x84, 0x30, 0xe9, 0x0b, 0xc6, 0x05, 0x42, 0x00, + 0x80, 0x68, 0xa2, 0x90, 0x20, 0x00, 0x63, 0x00, 0x80, 0x68, 0x54, 0xcf, + 0x1f, 0xee, 0x00, 0x0c, 0xdd, 0x4f, 0xa2, 0x41, 0x03, 0x80, 0x3d, 0x22, + 0x40, 0xd0, 0x42, 0x30, 0x15, 0x8a, 0xe2, 0x45, 0x04, 0x0e, 0x50, 0x60, + 0x03, 0x00, 0x85, 0xed, 0x6c, 0xc8, 0x50, 0x60, 0x00, 0x10, 0x88, 0xed, + 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, 0x0f, 0xc8, + 0x1c, 0x8d, 0x68, 0xc8, 0x5c, 0xfc, 0x48, 0x81, 0x83, 0xef, 0x18, 0xef, + 0x46, 0xc8, 0x01, 0xed, 0x45, 0xc8, 0x11, 0x6d, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0xa0, 0x0c, 0x42, 0x30, 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, + 0x08, 0x10, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, + 0x9c, 0xfc, 0x48, 0x81, 0x3d, 0x22, 0x40, 0x50, 0x12, 0x47, 0x5c, 0xfc, + 0x48, 0x81, 0x83, 0xef, 0x18, 0xef, 0x46, 0xc8, 0x01, 0xed, 0x45, 0xc8, + 0x19, 0x6d, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xa0, 0x0c, 0x42, 0x30, + 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x08, 0x0a, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0x3d, 0x22, + 0x40, 0x50, 0x12, 0x47, 0xe5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0xdd, 0x22, + 0x1c, 0xd0, 0x04, 0x16, 0x3d, 0x00, 0x5d, 0x16, 0x48, 0x00, 0x93, 0x4a, + 0x34, 0x4a, 0x42, 0xfc, 0x1c, 0xaf, 0x10, 0x02, 0x00, 0xc8, 0x44, 0xca, + 0x85, 0xca, 0xa4, 0x0e, 0x67, 0x0e, 0xc2, 0x45, 0x10, 0x02, 0x80, 0xc8, + 0xf1, 0x40, 0x2f, 0x00, 0x11, 0x69, 0x2b, 0x2d, 0x62, 0x90, 0x20, 0x00, + 0xe3, 0x40, 0x24, 0x00, 0x74, 0x14, 0x00, 0x00, 0x43, 0x00, 0x50, 0x23, + 0xe4, 0x40, 0x05, 0x00, 0x14, 0x0a, 0x3b, 0x2d, 0x82, 0x00, 0x0c, 0x28, + 0x14, 0x8a, 0x52, 0xb2, 0x04, 0x00, 0xf2, 0x40, 0x0a, 0x00, 0xf3, 0x40, + 0x08, 0x00, 0x95, 0x14, 0x3c, 0x00, 0x94, 0x09, 0x45, 0x05, 0x2b, 0x2d, + 0x62, 0x00, 0x0c, 0x28, 0x94, 0x89, 0x02, 0x02, 0x50, 0x13, 0xe2, 0x40, + 0x04, 0x00, 0x14, 0x09, 0x50, 0x00, 0x0c, 0x28, 0x14, 0x89, 0xdd, 0x22, + 0x1c, 0x50, 0x0e, 0x47, 0x94, 0x09, 0x62, 0x00, 0x0c, 0x28, 0xe3, 0xcf, + 0x94, 0x89, 0x52, 0xb2, 0x04, 0x00, 0x12, 0x94, 0x04, 0x00, 0x54, 0x14, + 0x00, 0x00, 0xb3, 0x40, 0x09, 0x00, 0x42, 0x00, 0x3c, 0x2b, 0x02, 0x02, + 0x50, 0x13, 0xe2, 0x40, 0xea, 0xff, 0xe9, 0xcf, 0x14, 0x1a, 0x00, 0x00, + 0x75, 0x14, 0x3c, 0x00, 0x35, 0x05, 0x2d, 0x2d, 0xf2, 0xcf, 0x54, 0x18, + 0x00, 0x00, 0x00, 0x0c, 0xf1, 0x4f, 0x5c, 0xfc, 0x48, 0x81, 0xe7, 0xcb, + 0x80, 0x30, 0x64, 0x05, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xe0, 0x0c, + 0x01, 0xef, 0x42, 0x30, 0x37, 0x11, 0xe2, 0x45, 0x81, 0xee, 0x9c, 0xfc, + 0x48, 0x81, 0xe7, 0x4b, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, 0x1f, 0x17, + 0x99, 0x45, 0x11, 0x4c, 0xe9, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0x77, 0x45, + 0x05, 0x0e, 0x3d, 0x32, 0x16, 0x00, 0x42, 0x30, 0x8b, 0x17, 0x44, 0x0e, + 0x98, 0x86, 0xe2, 0x45, 0x66, 0x0e, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xe8, 0x02, 0xa4, 0x69, 0x63, 0x02, 0x50, 0x1b, 0xa3, 0x40, 0x7f, 0x00, + 0x10, 0xb2, 0x0f, 0x00, 0x10, 0xb2, 0x01, 0x00, 0x12, 0x02, 0x50, 0x81, + 0x70, 0x1c, 0x22, 0x00, 0x83, 0x00, 0xac, 0x38, 0x52, 0x14, 0x0f, 0x00, + 0x7d, 0x14, 0x16, 0x00, 0x03, 0xb4, 0x66, 0x00, 0x25, 0x25, 0xf2, 0x14, + 0x10, 0x00, 0x72, 0x14, 0x11, 0x00, 0xf5, 0x27, 0xb5, 0x25, 0x44, 0x05, + 0x2d, 0x2d, 0xce, 0x07, 0xc6, 0x05, 0xfd, 0x2f, 0xbd, 0x2d, 0x5c, 0x18, + 0x98, 0x81, 0x5c, 0x18, 0x99, 0x81, 0x5c, 0x18, 0x9a, 0x81, 0x5c, 0x18, + 0x9b, 0x81, 0x92, 0x30, 0x2a, 0x00, 0x89, 0x6e, 0x40, 0x09, 0xc2, 0x00, + 0x00, 0xe0, 0x42, 0x00, 0x3c, 0x2b, 0xc6, 0x00, 0x80, 0xe0, 0x42, 0x00, + 0x80, 0x20, 0x50, 0x8b, 0x51, 0x89, 0xa4, 0x4c, 0xb1, 0xb4, 0xf2, 0xff, + 0x40, 0x6e, 0x5d, 0x1d, 0x15, 0x00, 0x3d, 0x1d, 0x14, 0x00, 0x1d, 0x1d, + 0x13, 0x00, 0xdd, 0x1c, 0x12, 0x00, 0xbd, 0x1c, 0x11, 0x00, 0x9d, 0x1c, + 0x10, 0x00, 0xea, 0x00, 0x50, 0x51, 0xe9, 0x00, 0x50, 0x49, 0xe8, 0x00, + 0x50, 0x41, 0x7c, 0x07, 0xfa, 0x06, 0x78, 0x06, 0xb9, 0x41, 0x08, 0x80, + 0x43, 0x01, 0x50, 0xc3, 0x23, 0x01, 0x50, 0x7b, 0x03, 0x01, 0x50, 0x73, + 0xc3, 0x00, 0x50, 0x6b, 0xa3, 0x00, 0x50, 0x63, 0x83, 0x00, 0x50, 0x5b, + 0x59, 0x30, 0xb8, 0x1f, 0x03, 0x03, 0x18, 0x50, 0xe3, 0x01, 0x18, 0x48, + 0xc3, 0x01, 0x18, 0x40, 0xa3, 0x01, 0x18, 0x30, 0x83, 0x01, 0x18, 0x28, + 0x63, 0x01, 0x18, 0x20, 0x42, 0x19, 0x01, 0x00, 0x22, 0x19, 0x02, 0x00, + 0x02, 0x19, 0x03, 0x00, 0x24, 0x8b, 0xa5, 0x8a, 0x26, 0x8a, 0xa7, 0x8b, + 0x79, 0x18, 0xb8, 0x1f, 0x37, 0x45, 0x0c, 0x47, 0x72, 0x00, 0x50, 0x19, + 0xe3, 0x14, 0x11, 0x00, 0x63, 0x14, 0x14, 0x00, 0xf5, 0x27, 0x99, 0xcf, + 0xb5, 0x25, 0x25, 0x6b, 0x66, 0x02, 0x50, 0x9b, 0x13, 0xb4, 0x86, 0xff, + 0x80, 0x0c, 0x50, 0xb0, 0x0f, 0x00, 0x42, 0xb0, 0x01, 0x00, 0x52, 0x00, + 0x50, 0x11, 0x62, 0x1c, 0x24, 0x00, 0x7c, 0xcf, 0x83, 0x00, 0xac, 0x38, + 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x75, 0x4c, 0x44, 0x45, + 0xc2, 0x45, 0x1d, 0xfe, 0x34, 0x00, 0xa3, 0x41, 0x00, 0xa5, 0x63, 0x50, + 0x08, 0x86, 0x30, 0x69, 0xa4, 0x41, 0x4f, 0x00, 0x84, 0x30, 0x00, 0x0e, + 0x40, 0x00, 0x0c, 0xb8, 0xd4, 0x44, 0x30, 0xe9, 0x50, 0x14, 0x89, 0x00, + 0x90, 0x14, 0x88, 0x00, 0xb9, 0x41, 0x03, 0x80, 0x20, 0x25, 0x39, 0x33, + 0x65, 0xab, 0xe2, 0x44, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0x00, 0x0c, + 0x9f, 0x45, 0x01, 0xed, 0xa5, 0x41, 0x04, 0x80, 0x45, 0x1c, 0x08, 0x61, + 0x02, 0x94, 0x4f, 0x00, 0xa2, 0x41, 0x00, 0xa4, 0xa2, 0x41, 0x04, 0x80, + 0x62, 0x1c, 0x09, 0x61, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x1c, 0x0a, 0x61, + 0xa4, 0x30, 0xd7, 0xff, 0xa5, 0xb0, 0x1e, 0x00, 0xab, 0x8e, 0xa4, 0x90, + 0x47, 0x00, 0x63, 0x30, 0x0a, 0x00, 0x42, 0x30, 0x0b, 0x00, 0x63, 0x00, + 0x3c, 0x2b, 0x42, 0x00, 0x3c, 0x2b, 0x03, 0x40, 0x2c, 0x00, 0x83, 0x0c, + 0x84, 0x00, 0x3c, 0x2b, 0x02, 0x40, 0x2d, 0x00, 0x62, 0x0c, 0xa4, 0x90, + 0x10, 0x00, 0x83, 0xae, 0x43, 0x00, 0x3c, 0x2b, 0x0f, 0xee, 0xa3, 0x41, + 0x00, 0xa4, 0x84, 0x00, 0x3c, 0x2b, 0x63, 0x50, 0xd8, 0x99, 0xa2, 0x90, + 0x10, 0x00, 0x30, 0xea, 0x83, 0xae, 0xa3, 0x41, 0x00, 0xa4, 0x0f, 0xed, + 0x42, 0x00, 0x3c, 0x2b, 0x63, 0x50, 0xd8, 0x9f, 0x30, 0xe9, 0xbf, 0x45, + 0xa5, 0x40, 0x2c, 0x00, 0x63, 0x30, 0x0d, 0x00, 0x42, 0x30, 0x0f, 0x00, + 0x63, 0x00, 0x3c, 0x2b, 0x42, 0x00, 0x3c, 0x2b, 0x43, 0x40, 0xd6, 0xff, + 0x83, 0x0c, 0x80, 0x0c, 0x84, 0x00, 0x3c, 0x2b, 0x42, 0x40, 0xd5, 0xff, + 0x62, 0x0c, 0xd3, 0xcf, 0x60, 0x0c, 0x42, 0x50, 0xd8, 0x99, 0xa0, 0x69, + 0xa6, 0x41, 0x04, 0x80, 0xb7, 0x2d, 0x70, 0x4c, 0x63, 0x00, 0x3c, 0x2b, + 0x66, 0x18, 0x09, 0x61, 0x42, 0xfc, 0x00, 0x06, 0x01, 0xef, 0xc5, 0x18, + 0x08, 0x61, 0x27, 0x2d, 0x50, 0x4c, 0x42, 0x00, 0x3c, 0x2b, 0xa5, 0x41, + 0x04, 0x80, 0xa4, 0xcf, 0x45, 0x18, 0x0a, 0x61, 0xa4, 0x30, 0x13, 0x00, + 0xa5, 0xb0, 0x14, 0x00, 0xa5, 0x40, 0x0b, 0x00, 0x84, 0x90, 0xed, 0xff, + 0xe4, 0x40, 0x0e, 0x00, 0x6c, 0x4c, 0x4a, 0x4c, 0x63, 0x00, 0x3c, 0x2b, + 0xa2, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0x6e, 0x4c, 0x4c, 0x4c, 0x63, 0x00, + 0x3c, 0x2b, 0x9b, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0xb4, 0x6d, 0x24, 0x6d, + 0x63, 0x00, 0x3c, 0x2b, 0x94, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0x00, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x14, 0xa4, 0x60, 0x02, 0xb4, 0x4c, 0x00, + 0xa4, 0x41, 0x04, 0x80, 0x44, 0x1c, 0x0d, 0x61, 0x1e, 0xad, 0xa5, 0x41, + 0x04, 0x80, 0xa3, 0x41, 0x00, 0xa4, 0x63, 0x50, 0x04, 0x9f, 0x30, 0x69, + 0xa5, 0x41, 0x03, 0x80, 0xa5, 0xfc, 0x84, 0xea, 0x2d, 0x2d, 0x55, 0x05, + 0xa5, 0x41, 0x04, 0x80, 0x45, 0xf8, 0x10, 0x61, 0x01, 0xed, 0x44, 0x18, + 0x0d, 0x61, 0x43, 0xfc, 0x00, 0xfa, 0xa3, 0x41, 0x04, 0x80, 0x2d, 0x2d, + 0x52, 0x4c, 0x43, 0xf8, 0x14, 0x61, 0xa5, 0x41, 0x04, 0x80, 0x45, 0x1c, + 0x08, 0x61, 0x26, 0xad, 0xa2, 0x41, 0x00, 0xa4, 0x42, 0x50, 0xd8, 0x99, + 0x20, 0x6a, 0x62, 0xfc, 0x00, 0x06, 0xa6, 0x41, 0x04, 0x80, 0x47, 0x2e, + 0x90, 0x4c, 0xb7, 0x2d, 0x86, 0x18, 0x09, 0x61, 0x70, 0x4c, 0xa4, 0x41, + 0x04, 0x80, 0x64, 0x18, 0x0a, 0x61, 0x62, 0xfc, 0xfc, 0xff, 0x42, 0xfc, + 0xfc, 0x05, 0xa4, 0x41, 0x04, 0x80, 0xb7, 0x2d, 0x70, 0x4c, 0x27, 0x2d, + 0x50, 0x4c, 0x64, 0x18, 0x0b, 0x61, 0xa3, 0x41, 0x04, 0x80, 0x43, 0x18, + 0x0c, 0x61, 0x01, 0xed, 0x45, 0x18, 0x08, 0x61, 0xbf, 0x45, 0x00, 0x0c, + 0xf1, 0x4f, 0x5d, 0x14, 0x30, 0x00, 0x46, 0x45, 0x44, 0xc8, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x5d, 0xf0, 0xe2, 0x45, 0x06, 0x0e, 0x17, 0x8c, + 0xa2, 0x41, 0x00, 0xa4, 0x42, 0x50, 0x04, 0x9f, 0xa4, 0x41, 0x04, 0x80, + 0xa0, 0x69, 0x84, 0xfc, 0x10, 0x61, 0x9f, 0xee, 0x06, 0x45, 0x46, 0x06, + 0x64, 0x90, 0x20, 0x00, 0x64, 0x00, 0x18, 0x28, 0x65, 0x0c, 0x85, 0x90, + 0x00, 0x00, 0x80, 0x00, 0x18, 0x18, 0xa0, 0xe9, 0x08, 0x47, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0xfc, 0x14, 0x61, 0x1f, 0xee, 0x06, 0x45, 0x62, 0x30, + 0x07, 0x00, 0x43, 0x90, 0x20, 0x00, 0x43, 0x00, 0x18, 0x20, 0x64, 0x90, + 0x00, 0x00, 0x44, 0x0c, 0x60, 0x00, 0x18, 0x10, 0xa3, 0x41, 0x00, 0xa4, + 0x63, 0x50, 0x04, 0x99, 0x30, 0xe9, 0x08, 0x47, 0xed, 0x4f, 0x5c, 0xfc, + 0x44, 0x81, 0x66, 0x45, 0x04, 0x0e, 0x42, 0xfc, 0x58, 0x00, 0x82, 0x94, + 0x11, 0x00, 0x25, 0x0e, 0x01, 0xed, 0x44, 0x94, 0x23, 0x00, 0xe0, 0x0c, + 0x5c, 0xfc, 0x48, 0x81, 0x01, 0xef, 0xa0, 0x0c, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x37, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x04, 0x0d, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, 0x9c, 0xfc, + 0x48, 0x81, 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, 0x42, 0x30, 0x49, 0xf3, + 0xe2, 0x45, 0x00, 0x0c, 0xb9, 0x41, 0x04, 0x80, 0x98, 0x86, 0x39, 0x33, + 0xc5, 0x56, 0x26, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x5c, 0xfc, 0x48, 0x81, + 0xb2, 0x41, 0x08, 0x80, 0x01, 0xef, 0x44, 0xc8, 0x81, 0xee, 0x52, 0x32, + 0x37, 0x11, 0xd2, 0x45, 0x80, 0x30, 0x04, 0x0d, 0x5c, 0xfc, 0x48, 0x81, + 0x83, 0xef, 0x08, 0xef, 0x81, 0xee, 0x80, 0x30, 0x04, 0x0d, 0xd2, 0x45, + 0x5d, 0xf8, 0x10, 0x00, 0xd5, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0x00, 0x0c, + 0xed, 0x4f, 0xa2, 0x41, 0x01, 0x80, 0x57, 0x45, 0x42, 0x30, 0xdd, 0x02, + 0x25, 0x0e, 0xe2, 0x45, 0x04, 0x0e, 0x98, 0xac, 0xb9, 0x41, 0x08, 0x80, + 0xb1, 0x41, 0x08, 0x80, 0xe0, 0x0c, 0x01, 0xef, 0xa0, 0x0c, 0x80, 0x30, + 0x04, 0x0d, 0x31, 0x32, 0x37, 0x11, 0xd1, 0x45, 0x1d, 0xfa, 0x10, 0x00, + 0x83, 0xef, 0x08, 0xef, 0xa0, 0x0c, 0x80, 0x30, 0x04, 0x0d, 0xd1, 0x45, + 0x1d, 0xfa, 0x10, 0x00, 0xb9, 0x41, 0x08, 0x80, 0x90, 0x0c, 0x39, 0x33, + 0x1f, 0x17, 0x17, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0xca, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, + 0xf4, 0x01, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xf6, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x01, 0x00, 0x00, + 0xf5, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, + 0xf6, 0x01, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0xe2, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, + 0xf6, 0x01, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe2, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0xf5, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0xe2, 0x01, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0xe1, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, + 0xf6, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x53, 0x6c, 0x65, 0x65, 0x70, 0x20, 0x52, 0x65, 0x71, 0x20, 0x46, 0x61, + 0x69, 0x6c, 0x20, 0x2d, 0x20, 0x55, 0x6d, 0x61, 0x63, 0x00, 0x00, 0x00, + 0xfc, 0x1f, 0x01, 0xa2, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x28, 0x9e, 0x08, 0x80, + 0x47, 0x43, 0x43, 0x3a, 0x20, 0x28, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x63, + 0x61, 0x70, 0x65, 0x20, 0x47, 0x4e, 0x55, 0x20, 0x54, 0x6f, 0x6f, 0x6c, + 0x73, 0x20, 0x32, 0x30, 0x31, 0x37, 0x2e, 0x31, 0x30, 0x2d, 0x30, 0x35, + 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4d, 0x49, 0x50, 0x53, 0x20, 0x4d, 0x54, + 0x49, 0x20, 0x42, 0x61, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x6c, + 0x29, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x30, 0x00, 0x41, 0x0f, 0x00, 0x00, + 0x00, 0x67, 0x6e, 0x75, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x04, 0x03, + 0x12, 0x1d, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, + 0xae, 0x09, 0x00, 0x00, 0x0c, 0xd8, 0x06, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x01, 0x06, + 0xc0, 0x04, 0x00, 0x00, 0x03, 0x9b, 0x02, 0x00, 0x00, 0x02, 0x2b, 0x33, + 0x00, 0x00, 0x00, 0x02 +}; + +#else +const unsigned char __aligned(4) nrf_wifi_umac_patch_pri_bimg[] = { + 0xba, 0xda, 0xba, 0xab, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0x93, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0xa6, 0x70, 0x00, 0x00, 0x04, 0xd4, 0x1c, 0x94, 0x82, 0x16, 0x10, 0x80, + 0x01, 0x00, 0x42, 0x97, 0x04, 0xd4, 0xcc, 0x94, 0x88, 0x19, 0x10, 0x80, + 0x01, 0x00, 0x5c, 0x42, 0x04, 0xd4, 0x90, 0x8c, 0xca, 0x25, 0x10, 0x80, + 0x01, 0x00, 0xcc, 0x5a, 0x04, 0xd4, 0x0c, 0x70, 0xe8, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x21, 0x2f, 0x04, 0xd4, 0x92, 0x9b, 0x08, 0x1e, 0x10, 0x80, + 0x01, 0x00, 0x34, 0x2e, 0x04, 0xd4, 0x28, 0x6b, 0xa8, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x77, 0x24, 0x04, 0xd4, 0xb0, 0x6f, 0x26, 0x21, 0x10, 0x80, + 0x01, 0x00, 0x18, 0xe8, 0x04, 0xd4, 0x62, 0x69, 0x08, 0x21, 0x10, 0x80, + 0x01, 0x00, 0xd5, 0x45, 0x04, 0xd4, 0xa2, 0x86, 0xcc, 0x14, 0x10, 0x80, + 0x01, 0x00, 0xa6, 0x4b, 0x04, 0xd4, 0x9c, 0x65, 0xbe, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x69, 0x3b, 0x04, 0xd4, 0x8a, 0x78, 0xdc, 0x19, 0x10, 0x80, + 0x01, 0x00, 0xfa, 0x08, 0x04, 0xd4, 0x68, 0x96, 0x4a, 0x15, 0x10, 0x80, + 0x01, 0x00, 0x60, 0x15, 0x04, 0xd4, 0x60, 0x7d, 0xf0, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0xf5, 0x27, 0x04, 0xd4, 0x20, 0x93, 0xa2, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x9a, 0x00, 0x04, 0xd4, 0x58, 0x95, 0xbe, 0x19, 0x10, 0x80, + 0x01, 0x00, 0x08, 0x97, 0x04, 0xd4, 0xcc, 0x8c, 0xd8, 0x14, 0x10, 0x80, + 0x01, 0x00, 0x64, 0xb7, 0x04, 0xd4, 0x3a, 0x7c, 0x72, 0x23, 0x10, 0x80, + 0x01, 0x00, 0xaa, 0x59, 0x04, 0xd4, 0x9e, 0x6e, 0xac, 0x22, 0x10, 0x80, + 0x01, 0x00, 0xf0, 0x09, 0x04, 0xd4, 0x7a, 0x6c, 0x40, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x48, 0xf1, 0x04, 0xd4, 0xfa, 0x94, 0x40, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0xbc, 0xfa, 0x04, 0xd4, 0x00, 0x79, 0xc4, 0x19, 0x10, 0x80, + 0x01, 0x00, 0xa0, 0xcb, 0x04, 0xd4, 0x20, 0x89, 0x30, 0x11, 0x10, 0x80, + 0x01, 0x00, 0x60, 0x0a, 0x04, 0xd4, 0x28, 0xa0, 0xc4, 0x1c, 0x10, 0x80, + 0x01, 0x00, 0xe7, 0xe7, 0x04, 0xd4, 0x00, 0xa1, 0x16, 0x10, 0x10, 0x80, + 0x01, 0x00, 0xeb, 0x9e, 0x04, 0xd4, 0xac, 0x93, 0x60, 0x14, 0x10, 0x80, + 0x01, 0x00, 0xa0, 0x71, 0x04, 0xd4, 0x42, 0x89, 0x4a, 0x21, 0x10, 0x80, + 0x01, 0x00, 0x0e, 0xc7, 0x04, 0xd4, 0xde, 0x9a, 0xba, 0x17, 0x10, 0x80, + 0x01, 0x00, 0xa2, 0xa9, 0x04, 0xd4, 0xce, 0x68, 0x76, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0x93, 0x6c, 0x04, 0xd4, 0x66, 0x9d, 0x3a, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0x6c, 0xc3, 0x04, 0xd4, 0x48, 0x65, 0x6e, 0x24, 0x10, 0x80, + 0x01, 0x00, 0x04, 0x0c, 0x04, 0xd4, 0xb8, 0x9c, 0xd6, 0x1c, 0x10, 0x80, + 0x01, 0x00, 0xf0, 0xbd, 0x04, 0xd4, 0x20, 0x7c, 0x6c, 0x23, 0x10, 0x80, + 0x01, 0x00, 0x45, 0x6f, 0x04, 0xd4, 0xa4, 0x9d, 0xc4, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x10, 0x7b, 0x04, 0xd4, 0xd0, 0x7b, 0x3e, 0x21, 0x10, 0x80, + 0x01, 0x00, 0xdb, 0x84, 0x04, 0xd4, 0x48, 0x67, 0xfa, 0x19, 0x10, 0x80, + 0x01, 0x00, 0x76, 0x89, 0x04, 0xd4, 0x6a, 0x73, 0x8e, 0x1f, 0x10, 0x80, + 0x01, 0x00, 0xbd, 0x05, 0x04, 0xd4, 0xe6, 0x8f, 0xe8, 0x1c, 0x10, 0x80, + 0x01, 0x00, 0x53, 0xa8, 0x04, 0xd4, 0xba, 0x69, 0xf8, 0x24, 0x10, 0x80, + 0x01, 0x00, 0x01, 0xdf, 0x04, 0xd4, 0xee, 0x8b, 0x30, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0xe8, 0x74, 0x04, 0xd4, 0xda, 0x76, 0x66, 0x1a, 0x10, 0x80, + 0x01, 0x00, 0x6a, 0x62, 0x04, 0xd4, 0xc8, 0x9b, 0x24, 0x1a, 0x10, 0x80, + 0x01, 0x00, 0xc1, 0xc3, 0x04, 0xd4, 0x3a, 0xa1, 0x9e, 0x1b, 0x10, 0x80, + 0x01, 0x00, 0xd6, 0x7c, 0x04, 0xd4, 0x0e, 0x67, 0x00, 0x20, 0x10, 0x80, + 0x01, 0x00, 0x41, 0x4c, 0x04, 0xd4, 0x14, 0x6b, 0x90, 0x14, 0x10, 0x80, + 0x01, 0x00, 0xae, 0xf9, 0x04, 0xd4, 0xd8, 0x85, 0x30, 0x20, 0x10, 0x80, + 0x01, 0x00, 0xe3, 0xad, 0x04, 0xd4, 0x6c, 0x6f, 0x58, 0x22, 0x10, 0x80, + 0x01, 0x00, 0xa7, 0xe4, 0x04, 0xd4, 0x9c, 0x8a, 0xa6, 0x22, 0x10, 0x80, + 0x01, 0x00, 0x71, 0xd9, 0x04, 0xd4, 0xc6, 0x7d, 0xfc, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x34, 0x2a, 0x04, 0xd4, 0x7a, 0x8f, 0xb8, 0x1c, 0x10, 0x80, + 0x01, 0x00, 0x45, 0x09, 0x04, 0xd4, 0x5c, 0xa3, 0xae, 0x14, 0x10, 0x80, + 0x01, 0x00, 0x33, 0x5b, 0x04, 0xd4, 0x08, 0x91, 0x88, 0x1c, 0x10, 0x80, + 0x01, 0x00, 0x90, 0x1c, 0x04, 0xd4, 0xf4, 0x6f, 0x54, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0xbc, 0x58, 0x04, 0xd4, 0x44, 0x6f, 0x78, 0x23, 0x10, 0x80, + 0x01, 0x00, 0x4c, 0x1e, 0x04, 0xd4, 0x08, 0x9b, 0x20, 0x21, 0x10, 0x80, + 0x01, 0x00, 0x20, 0x2e, 0x04, 0xd4, 0x3a, 0x99, 0xd2, 0x1a, 0x10, 0x80, + 0x01, 0x00, 0x54, 0x7d, 0x04, 0xd4, 0xd0, 0x65, 0xc2, 0x1b, 0x10, 0x80, + 0x01, 0x00, 0x37, 0x51, 0x04, 0xd4, 0x3e, 0x78, 0xd6, 0x13, 0x10, 0x80, + 0x01, 0x00, 0x66, 0x7c, 0x04, 0xd4, 0x72, 0x78, 0x72, 0x1a, 0x10, 0x80, + 0x01, 0x00, 0xf4, 0xd4, 0x04, 0xd4, 0x0e, 0x65, 0x10, 0x10, 0x10, 0x80, + 0x01, 0x00, 0xc8, 0x3a, 0x04, 0xd4, 0x5c, 0x78, 0x34, 0x10, 0x10, 0x80, + 0x01, 0x00, 0xd2, 0x90, 0x04, 0xd4, 0x8a, 0x6a, 0x34, 0x25, 0x10, 0x80, + 0x01, 0x00, 0xdd, 0x5e, 0x04, 0xd4, 0x82, 0x81, 0x2c, 0x18, 0x10, 0x80, + 0x01, 0x00, 0x99, 0x29, 0x04, 0xd4, 0x86, 0x7e, 0xf6, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x64, 0x82, 0x04, 0xd4, 0x7c, 0x74, 0x8e, 0x10, 0x10, 0x80, + 0x01, 0x00, 0x7f, 0xc4, 0x04, 0xd4, 0xb8, 0x89, 0x42, 0x23, 0x10, 0x80, + 0x01, 0x00, 0x3e, 0x52, 0x04, 0xd4, 0xe6, 0x8a, 0x3c, 0x23, 0x10, 0x80, + 0x01, 0x00, 0xf6, 0x1a, 0x04, 0xd4, 0xfe, 0xa0, 0x46, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x3b, 0xaa, 0x04, 0xd4, 0x32, 0x8b, 0xb8, 0x19, 0x10, 0x80, + 0x01, 0x00, 0xde, 0x03, 0x04, 0xd4, 0x42, 0x63, 0xf0, 0x20, 0x10, 0x80, + 0x01, 0x00, 0x5c, 0xfb, 0x04, 0xd4, 0x36, 0x63, 0xc4, 0x25, 0x10, 0x80, + 0x01, 0x00, 0x47, 0x4e, 0x04, 0xd4, 0x56, 0x7f, 0x0c, 0x23, 0x10, 0x80, + 0x01, 0x00, 0x18, 0xd8, 0x04, 0xd4, 0x12, 0x66, 0xc6, 0x1d, 0x10, 0x80, + 0x01, 0x00, 0x66, 0xc6, 0x04, 0xd4, 0xee, 0x71, 0xee, 0x25, 0x10, 0x80, + 0x01, 0x00, 0xea, 0x82, 0x04, 0xd4, 0x60, 0x86, 0xc6, 0x14, 0x10, 0x80, + 0x01, 0x00, 0x53, 0x49, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0xba, 0x3e +}; + +const unsigned char __aligned(4) nrf_wifi_umac_patch_sec_bin[] = { + 0xf5, 0x4f, 0xa5, 0x41, 0x06, 0x80, 0xa5, 0x30, 0x2c, 0xae, 0x58, 0x09, + 0x44, 0x45, 0xb0, 0x41, 0x09, 0x80, 0x22, 0x27, 0x2c, 0x07, 0x6a, 0x27, + 0xa2, 0x41, 0x01, 0x80, 0x90, 0x30, 0x60, 0x4d, 0x42, 0x30, 0xbd, 0xa4, + 0xe2, 0x45, 0x68, 0x6f, 0xa3, 0x41, 0x59, 0x00, 0x50, 0x30, 0x60, 0x4d, + 0x83, 0x30, 0xf8, 0x08, 0x63, 0x50, 0x58, 0xf3, 0x62, 0xf8, 0xb4, 0x02, + 0x60, 0x50, 0x40, 0x9c, 0x62, 0xf8, 0xb8, 0x02, 0x60, 0x30, 0x8c, 0x0a, + 0x62, 0xf8, 0xc0, 0x02, 0x60, 0x30, 0x88, 0x08, 0x82, 0xf8, 0xb0, 0x02, + 0x02, 0xf8, 0xbc, 0x02, 0x62, 0xf8, 0x04, 0x03, 0x04, 0x45, 0x06, 0x47, + 0x5c, 0xfc, 0x28, 0x82, 0xa3, 0x41, 0x02, 0x01, 0x63, 0x30, 0x63, 0x08, + 0x62, 0x60, 0x07, 0x80, 0x62, 0x60, 0x04, 0x90, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x60, 0x4d, 0xa3, 0x41, 0x13, 0x80, 0x43, 0xf8, 0x8c, 0x1e, + 0xa2, 0x41, 0x09, 0x80, 0xa4, 0x41, 0x13, 0x80, 0x42, 0x30, 0x8d, 0xdc, + 0x44, 0xf8, 0xa0, 0x5d, 0x7c, 0xfc, 0xb0, 0x81, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x79, 0xc3, 0xa4, 0x41, 0x13, 0x80, 0x44, 0xf8, 0x48, 0x63, + 0xa2, 0x41, 0x09, 0x80, 0x83, 0x8d, 0x02, 0xf8, 0x20, 0x4d, 0xbf, 0x45, + 0xf5, 0x4f, 0xa4, 0x41, 0x09, 0x80, 0x44, 0x30, 0xe8, 0x4c, 0xe5, 0xcb, + 0x04, 0xf8, 0xe8, 0x4c, 0x2b, 0xe8, 0x2a, 0xe8, 0x29, 0xe8, 0x28, 0xe8, + 0x27, 0xe8, 0x26, 0xe8, 0x25, 0xe8, 0x24, 0xe8, 0x23, 0xe8, 0x22, 0xe8, + 0x21, 0xe8, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x41, 0x09, 0x80, 0x02, 0x18, + 0xd0, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x30, 0xd4, 0x4c, 0x02, 0xf8, + 0x84, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x03, 0xf8, 0xd4, 0x4c, 0x42, 0x30, + 0x01, 0xc0, 0xe2, 0x45, 0x52, 0xa8, 0xa3, 0x41, 0x09, 0x80, 0x43, 0x30, + 0x54, 0x4d, 0x03, 0xf8, 0x54, 0x4d, 0x21, 0xe8, 0x28, 0x88, 0xa2, 0x41, + 0x09, 0x80, 0x02, 0xf8, 0x18, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, + 0x25, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xf8, 0x28, 0x4d, 0xa2, 0x41, + 0x09, 0x80, 0x02, 0x18, 0x2c, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0xa4, 0x41, + 0x09, 0x80, 0x02, 0x18, 0x2d, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x04, 0x18, + 0x1c, 0x4d, 0x02, 0xf8, 0x30, 0x4d, 0x80, 0x86, 0xa2, 0x41, 0x09, 0x80, + 0x82, 0xf8, 0x40, 0x4d, 0xa2, 0xf8, 0x44, 0x4d, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0x18, 0x48, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x34, 0x4d, + 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x35, 0x4d, 0xa2, 0x41, 0x09, 0x80, + 0x8a, 0xed, 0x02, 0x18, 0x49, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x38, + 0x4a, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xf8, 0xdc, 0x4c, 0xa2, 0x41, + 0x09, 0x80, 0x02, 0x18, 0x70, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, + 0x1d, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xf8, 0x4c, 0x4d, 0xe5, 0x4b, + 0xa2, 0x41, 0x09, 0x80, 0x02, 0xf8, 0x50, 0x4d, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0xf8, 0x38, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x38, 0x72, 0x4c, + 0x06, 0x47, 0x00, 0x0c, 0x64, 0x30, 0x94, 0xf6, 0x63, 0xb0, 0x49, 0x00, + 0x85, 0x8d, 0x40, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x74, 0x4c, + 0x64, 0x30, 0xd8, 0xeb, 0x63, 0xb0, 0xb5, 0x00, 0x86, 0x8d, 0x64, 0x30, + 0x98, 0xea, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x75, 0x4c, 0x63, 0xb0, + 0xf1, 0x00, 0xe3, 0x40, 0x04, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, + 0x76, 0x4c, 0x84, 0x30, 0x8f, 0xe9, 0x84, 0xb0, 0x8d, 0x00, 0xe4, 0x40, + 0x04, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x77, 0x4c, 0xbf, 0x45, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x24, 0x9b, 0x24, 0x31, 0xf6, 0xff, + 0x43, 0x15, 0x08, 0x00, 0x0a, 0x94, 0x25, 0x00, 0x84, 0x30, 0x0a, 0x00, + 0xa8, 0x41, 0x62, 0x10, 0xb8, 0x6d, 0xc0, 0x0c, 0x08, 0x31, 0xd3, 0x4d, + 0x30, 0x69, 0xb1, 0x6a, 0x60, 0x6f, 0x02, 0x01, 0x3c, 0x9b, 0x02, 0x46, + 0x2d, 0x25, 0x49, 0x00, 0x90, 0x3b, 0x90, 0xaf, 0x63, 0x30, 0x60, 0x00, + 0x05, 0x01, 0x3c, 0x9b, 0x05, 0x46, 0xdd, 0x26, 0x85, 0x00, 0x90, 0x3b, + 0xa7, 0x40, 0x06, 0x00, 0x49, 0x94, 0x09, 0x00, 0x00, 0x0c, 0xa4, 0x94, + 0x08, 0x00, 0x00, 0x0c, 0x46, 0xb5, 0xe4, 0xff, 0x00, 0x0c, 0x9f, 0x45, + 0x40, 0x0c, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, 0x02, 0xed, 0x00, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0xe5, 0xcb, 0x42, 0x30, 0x11, 0xc2, + 0xe2, 0x45, 0x64, 0x0d, 0x10, 0x8d, 0x6b, 0x30, 0x94, 0xf6, 0x63, 0xb0, + 0x49, 0x00, 0x8d, 0x8d, 0x6b, 0x30, 0xd8, 0xeb, 0x81, 0xed, 0x62, 0x94, + 0x24, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, + 0x79, 0x4c, 0xe5, 0x4b, 0x06, 0x47, 0x63, 0xb0, 0x51, 0x00, 0x91, 0xad, + 0x81, 0xed, 0x6b, 0x30, 0x74, 0xeb, 0x63, 0xb0, 0x51, 0x00, 0x96, 0x8d, + 0x6b, 0x30, 0x98, 0xea, 0x81, 0xed, 0x62, 0x94, 0x30, 0x00, 0x00, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0xec, 0xcf, 0x42, 0x14, 0x7d, 0x4c, 0x62, 0x94, + 0x23, 0x00, 0xe5, 0x4b, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x7b, 0x4c, + 0x06, 0x47, 0xe1, 0xcf, 0x42, 0x14, 0x78, 0x4c, 0x63, 0xb0, 0xf1, 0x00, + 0x8f, 0xad, 0x81, 0xed, 0x6b, 0x30, 0x8f, 0xe9, 0x63, 0xb0, 0x51, 0x00, + 0x9b, 0x8d, 0x81, 0xed, 0x62, 0x94, 0x2d, 0x00, 0x00, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0xcf, 0xcf, 0x42, 0x14, 0x81, 0x4c, 0x62, 0x94, 0x1e, 0x00, + 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xc7, 0xcf, 0x42, 0x14, 0x7f, 0x4c, + 0xa2, 0x41, 0x09, 0x80, 0xc2, 0xcf, 0x42, 0x14, 0x7a, 0x4c, 0xa2, 0x41, + 0x09, 0x80, 0xbd, 0xcf, 0x42, 0x14, 0x7c, 0x4c, 0x6b, 0x31, 0x2b, 0xe9, + 0x6b, 0xb1, 0x29, 0x00, 0xeb, 0x40, 0x0d, 0x00, 0x62, 0x94, 0x12, 0x00, + 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xaf, 0xcf, 0x42, 0x14, 0x83, 0x4c, + 0xa2, 0x41, 0x09, 0x80, 0xaa, 0xcf, 0x42, 0x14, 0x7e, 0x4c, 0xa7, 0xcf, + 0x40, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0xcf, 0x42, 0x14, 0x80, 0x4c, + 0xa2, 0x41, 0x09, 0x80, 0x9e, 0xcf, 0x42, 0x14, 0x82, 0x4c, 0x00, 0x0c, + 0xdd, 0x4f, 0x3d, 0x23, 0x20, 0xd0, 0x4f, 0x68, 0xa2, 0x41, 0x10, 0x80, + 0x25, 0x0e, 0x90, 0x32, 0x18, 0x00, 0x42, 0x30, 0x0b, 0x1f, 0x44, 0x0e, + 0xe2, 0x45, 0x94, 0x0c, 0x1a, 0x2d, 0x02, 0x94, 0x50, 0x00, 0x1c, 0x2d, + 0x52, 0xfc, 0x04, 0x00, 0x0a, 0xe9, 0x52, 0xfc, 0x14, 0x00, 0x21, 0x6a, + 0x44, 0x30, 0x94, 0xf6, 0x42, 0xb0, 0x49, 0x00, 0x05, 0x8d, 0x80, 0x0d, + 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0x74, 0x4c, 0x44, 0x30, 0xd8, 0xeb, + 0x42, 0xb0, 0xb5, 0x00, 0x08, 0x8d, 0x44, 0x30, 0x98, 0xea, 0xa2, 0x41, + 0x09, 0x80, 0x82, 0x15, 0x75, 0x4c, 0x44, 0x30, 0x98, 0xea, 0x42, 0xb0, + 0xf1, 0x00, 0x08, 0x8d, 0x44, 0x30, 0x8f, 0xe9, 0xa2, 0x41, 0x09, 0x80, + 0x82, 0x15, 0x76, 0x4c, 0x44, 0x30, 0x8f, 0xe9, 0x42, 0xb0, 0x8d, 0x00, + 0x08, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, + 0x77, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x7d, 0xc2, 0xe2, 0x45, + 0x00, 0x0c, 0x0a, 0x6a, 0x84, 0x01, 0xd0, 0x21, 0x29, 0x06, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0xb9, 0xd7, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x94, + 0xca, 0x00, 0xa3, 0x41, 0x10, 0x80, 0x94, 0x0c, 0x63, 0x30, 0x1d, 0x1f, + 0xc3, 0x45, 0x5d, 0xf8, 0x18, 0x00, 0x3d, 0x23, 0x20, 0x50, 0x46, 0x48, + 0x12, 0x47, 0x02, 0x94, 0x67, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x52, 0xfc, + 0x04, 0x00, 0x0a, 0xe9, 0x52, 0xfc, 0x14, 0x00, 0x21, 0x6a, 0x44, 0x30, + 0x94, 0xf6, 0x42, 0xb0, 0x49, 0x00, 0x05, 0x8d, 0x80, 0x0d, 0xa2, 0x41, + 0x09, 0x80, 0x82, 0x15, 0x74, 0x4c, 0x44, 0x30, 0xd8, 0xeb, 0x42, 0xb0, + 0xb5, 0x00, 0x08, 0x8d, 0x44, 0x30, 0x98, 0xea, 0xa2, 0x41, 0x09, 0x80, + 0x82, 0x15, 0x75, 0x4c, 0x44, 0x30, 0x98, 0xea, 0x42, 0xb0, 0xf1, 0x00, + 0x08, 0x8d, 0x44, 0x30, 0x8f, 0xe9, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, + 0x76, 0x4c, 0x44, 0x30, 0x8f, 0xe9, 0x42, 0xb0, 0x8d, 0x00, 0x08, 0x8d, + 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x15, 0x77, 0x4c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x7d, 0xc2, 0xe2, 0x45, 0x00, 0x0c, + 0x0a, 0x6a, 0x84, 0x01, 0xd0, 0x21, 0x29, 0x06, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0xb9, 0xd7, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0xb4, 0xaf, 0xff, + 0xa3, 0x41, 0x10, 0x80, 0x52, 0xfc, 0x14, 0x00, 0x72, 0xfe, 0x1c, 0x00, + 0xd2, 0xfe, 0x18, 0x00, 0x21, 0x6a, 0xe2, 0xfe, 0x00, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0xe9, 0x16, 0xc2, 0x45, 0xb2, 0xfe, 0x20, 0x00, + 0xe4, 0x86, 0xa2, 0x41, 0x10, 0x80, 0xf6, 0x0c, 0xd5, 0x0c, 0x42, 0x30, + 0x8f, 0x22, 0xc2, 0x45, 0xfd, 0xfa, 0x10, 0x00, 0x02, 0xb4, 0x91, 0xff, + 0xa3, 0x41, 0x10, 0x80, 0xa2, 0x41, 0x04, 0x80, 0xd1, 0xd3, 0x10, 0x00, + 0x60, 0x0e, 0xe0, 0x32, 0x01, 0x00, 0xa7, 0x41, 0x09, 0x80, 0xc2, 0x32, + 0xc5, 0xdf, 0xa0, 0x32, 0x02, 0x00, 0x1e, 0x94, 0x0a, 0x00, 0xf3, 0x02, + 0x10, 0x10, 0x85, 0x69, 0x93, 0x44, 0xa2, 0x40, 0x25, 0x00, 0x62, 0x4e, + 0xb3, 0xb6, 0xf5, 0xff, 0x00, 0x0c, 0x12, 0x2d, 0xe2, 0x40, 0x07, 0x00, + 0x05, 0x69, 0xa1, 0x2d, 0x03, 0xb4, 0x7d, 0x00, 0x22, 0x2d, 0xa2, 0x40, + 0x3a, 0x00, 0x90, 0x2c, 0x89, 0x8c, 0x40, 0x0c, 0x05, 0x69, 0xa1, 0x2d, + 0x03, 0xb4, 0x59, 0x00, 0x22, 0x2d, 0xa2, 0x40, 0x3e, 0x00, 0x40, 0x0c, + 0xa3, 0x41, 0x10, 0x80, 0x94, 0x0c, 0x63, 0x30, 0x1d, 0x1f, 0xc3, 0x45, + 0x5d, 0xf8, 0x18, 0x00, 0x3d, 0x23, 0x20, 0x50, 0x46, 0x48, 0x12, 0x47, + 0x50, 0x14, 0x94, 0x00, 0x58, 0xad, 0x47, 0xfc, 0xac, 0x9b, 0xc2, 0xfc, + 0x38, 0x01, 0xa6, 0x40, 0xd2, 0xff, 0x52, 0xfc, 0x00, 0x00, 0x22, 0x2d, + 0xe2, 0x40, 0x67, 0x00, 0x01, 0xef, 0xf0, 0xfa, 0x48, 0x0b, 0x53, 0x30, + 0xd2, 0x02, 0x24, 0x25, 0x20, 0x05, 0xa1, 0x6a, 0x93, 0x0c, 0xe6, 0xc8, + 0xd6, 0x45, 0xa5, 0x30, 0x48, 0x01, 0xbf, 0xcf, 0xe6, 0x48, 0x1c, 0x2d, + 0xe2, 0x40, 0xa6, 0xff, 0x89, 0xcf, 0x52, 0xfc, 0x14, 0x00, 0xb0, 0xfc, + 0x50, 0x0b, 0xd2, 0x14, 0x30, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xa5, 0x30, + 0x48, 0x01, 0x42, 0x30, 0x71, 0xec, 0xe2, 0x45, 0x01, 0xee, 0xba, 0xcf, + 0x90, 0x2c, 0x10, 0xfe, 0x50, 0x0b, 0xd2, 0x14, 0x10, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0x10, 0x32, 0x48, 0x01, 0xb0, 0x0c, 0x42, 0x30, 0x95, 0xe7, + 0xe2, 0x45, 0x01, 0xee, 0xd2, 0x14, 0x0f, 0x00, 0xa2, 0x41, 0x04, 0x80, + 0xb0, 0x0c, 0x42, 0x30, 0x55, 0xe7, 0xe2, 0x45, 0x01, 0xee, 0xac, 0xcf, + 0x40, 0x0c, 0x30, 0xfe, 0x4c, 0x0b, 0xa2, 0x41, 0x04, 0x80, 0x31, 0x32, + 0x48, 0x01, 0x90, 0x86, 0x42, 0x30, 0x95, 0xe7, 0xc2, 0x45, 0xd2, 0x14, + 0x10, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x90, 0x86, 0x42, 0x30, 0x55, 0xe7, + 0xc2, 0x45, 0xd2, 0x14, 0x0f, 0x00, 0x05, 0x69, 0x22, 0x2d, 0xe2, 0x40, + 0x92, 0xff, 0xcf, 0xcf, 0x00, 0x0c, 0xb0, 0xfc, 0x4c, 0x0b, 0xd2, 0x14, + 0x30, 0x00, 0xa2, 0x41, 0x04, 0x80, 0xa5, 0x30, 0x48, 0x01, 0x42, 0x30, + 0x71, 0xec, 0xe2, 0x45, 0x80, 0x0c, 0x05, 0x69, 0x22, 0x2d, 0xe2, 0x40, + 0x76, 0xff, 0xaf, 0xcf, 0x00, 0x0c, 0x9b, 0xcf, 0x10, 0xf8, 0x48, 0x0b, + 0xb9, 0x41, 0x09, 0x80, 0x39, 0x33, 0x61, 0xc0, 0xb9, 0x45, 0x00, 0x0c, + 0xb9, 0x41, 0x09, 0x80, 0x39, 0x33, 0x61, 0xc0, 0xb9, 0x45, 0x00, 0x0c, + 0x45, 0xfc, 0x80, 0x00, 0xa2, 0x40, 0x3c, 0x01, 0x45, 0xfc, 0x90, 0x00, + 0xa2, 0x40, 0x38, 0x01, 0xe1, 0x4f, 0xc5, 0xc8, 0x3d, 0x23, 0x18, 0xd0, + 0x44, 0x14, 0x08, 0x02, 0x64, 0x14, 0x07, 0x02, 0xa4, 0x16, 0x0b, 0x02, + 0x20, 0x25, 0xd3, 0x44, 0xa3, 0x41, 0x09, 0x80, 0x43, 0x38, 0xe0, 0x4c, + 0x44, 0x14, 0x0a, 0x02, 0x64, 0x14, 0x09, 0x02, 0x84, 0x0e, 0x20, 0x25, + 0xd3, 0x44, 0xa3, 0x41, 0x09, 0x80, 0x43, 0x38, 0xe2, 0x4c, 0x64, 0x14, + 0x28, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x05, 0x0e, 0x25, 0x32, 0x20, 0x01, + 0x15, 0x94, 0x7e, 0x01, 0x62, 0x18, 0xe4, 0x4c, 0x55, 0x0c, 0x54, 0x16, + 0x70, 0x00, 0xf4, 0x60, 0x1f, 0x00, 0xd4, 0x60, 0x23, 0x00, 0x74, 0x14, + 0x6f, 0x00, 0xd4, 0x17, 0x2a, 0x00, 0xf4, 0x60, 0x1c, 0x10, 0xd4, 0x60, + 0x20, 0x10, 0x52, 0x02, 0x00, 0x40, 0x72, 0x00, 0x90, 0x92, 0x7e, 0x00, + 0x00, 0x28, 0xc3, 0x03, 0x50, 0x99, 0xe2, 0x02, 0x00, 0x10, 0x92, 0x30, + 0x80, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xe2, 0xf8, 0xb0, 0x9a, 0xc2, 0xf8, + 0xb4, 0x9a, 0x64, 0x02, 0x50, 0x21, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, + 0xd0, 0x00, 0x42, 0x30, 0x51, 0x1e, 0xc2, 0x45, 0xe4, 0x02, 0x50, 0x21, + 0x1e, 0x94, 0xe7, 0x00, 0xc2, 0x0e, 0x57, 0x30, 0x7c, 0x00, 0x56, 0x00, + 0x50, 0x11, 0x56, 0xf8, 0x00, 0x00, 0x12, 0xb4, 0x4e, 0x01, 0xd6, 0xfb, + 0x04, 0x00, 0xf0, 0x32, 0xec, 0x01, 0x77, 0x0d, 0x80, 0x31, 0x01, 0x00, + 0xa0, 0x0d, 0x40, 0x0d, 0xc0, 0x31, 0x04, 0x00, 0xe0, 0x31, 0x01, 0x00, + 0x2b, 0xfd, 0x00, 0x00, 0xe9, 0x40, 0x3c, 0x00, 0x54, 0x14, 0x6e, 0x00, + 0xe2, 0x40, 0x05, 0x00, 0xed, 0x40, 0x48, 0x01, 0xed, 0x95, 0x3a, 0x01, + 0x22, 0x2d, 0x49, 0xfc, 0x0c, 0x00, 0x80, 0x87, 0x82, 0x40, 0x2e, 0x00, + 0x00, 0x0c, 0xc9, 0xfc, 0x00, 0x00, 0x7c, 0x07, 0x62, 0x69, 0x21, 0x2d, + 0xa2, 0x40, 0x1e, 0x00, 0x15, 0x94, 0xa0, 0x00, 0x4a, 0x30, 0x1e, 0x00, + 0x54, 0x60, 0x10, 0x02, 0x06, 0xfd, 0x04, 0x00, 0x54, 0x60, 0x0d, 0x12, + 0x02, 0x95, 0x94, 0x00, 0x60, 0x0c, 0x08, 0xcc, 0xb0, 0x6d, 0xa2, 0x60, + 0x10, 0x00, 0xa2, 0x60, 0x0d, 0x10, 0xa8, 0x94, 0x8b, 0x00, 0xb0, 0x6d, + 0x43, 0x30, 0x80, 0x00, 0x24, 0x25, 0xa3, 0x02, 0x50, 0x2b, 0xf3, 0xae, + 0x54, 0x00, 0x50, 0x11, 0x49, 0xfc, 0x0c, 0x00, 0x40, 0x6e, 0x44, 0x00, + 0x50, 0x13, 0x55, 0xad, 0xe7, 0x30, 0x34, 0x00, 0xcc, 0x95, 0x05, 0x00, + 0x00, 0x0c, 0xa2, 0x4d, 0x68, 0x4d, 0xba, 0xcf, 0x82, 0x4d, 0x1e, 0xb4, + 0xb9, 0x00, 0x56, 0xf9, 0x08, 0x00, 0xb5, 0x41, 0x01, 0x80, 0xb5, 0x32, + 0xbd, 0xa4, 0x54, 0x14, 0x70, 0x00, 0x74, 0x14, 0x6f, 0x00, 0x20, 0x25, + 0xd3, 0x44, 0xa2, 0x40, 0xd6, 0x00, 0x76, 0x30, 0x24, 0x00, 0x90, 0x30, + 0xfc, 0x01, 0x81, 0xee, 0x57, 0xfc, 0x00, 0x00, 0x06, 0x8d, 0xe8, 0x4e, + 0x24, 0x69, 0xa2, 0x00, 0x10, 0x10, 0x2e, 0x6d, 0x30, 0xe9, 0xe4, 0xb6, + 0xf5, 0xff, 0xb2, 0x6d, 0xb4, 0x30, 0x01, 0x02, 0x06, 0xef, 0xd5, 0x45, + 0x96, 0x30, 0x38, 0x00, 0x54, 0x14, 0x6d, 0x00, 0x56, 0xf8, 0x74, 0x00, + 0x54, 0x60, 0x27, 0x00, 0x54, 0x60, 0x24, 0x10, 0xb4, 0x41, 0x05, 0x80, + 0x02, 0xb4, 0x61, 0x00, 0x56, 0xf8, 0x78, 0x00, 0xb0, 0x32, 0x70, 0x00, + 0x94, 0x32, 0x59, 0x5e, 0xf4, 0x45, 0x95, 0x0c, 0x42, 0x0e, 0xf4, 0x45, + 0x82, 0x0c, 0x55, 0x96, 0x16, 0x00, 0xbe, 0x41, 0x05, 0x80, 0xb7, 0x41, + 0x10, 0x80, 0x72, 0x0e, 0xde, 0x33, 0x61, 0x5e, 0xf7, 0x32, 0x3f, 0x1e, + 0x92, 0x0c, 0xde, 0x45, 0x5d, 0xf8, 0x10, 0x00, 0xf7, 0x45, 0x93, 0x0c, + 0x44, 0x48, 0x42, 0x0e, 0xf4, 0x45, 0x82, 0x0c, 0x55, 0xb6, 0xf4, 0xff, + 0x72, 0x0e, 0xa2, 0x41, 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, 0x65, 0x48, + 0x90, 0x0c, 0x56, 0xf8, 0x50, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x76, 0xf8, + 0x34, 0x00, 0xa3, 0x0c, 0x36, 0xfa, 0x4c, 0x00, 0x42, 0x30, 0x19, 0xd3, + 0xc2, 0x45, 0xd0, 0xfa, 0x80, 0x00, 0x02, 0x69, 0xb6, 0x0c, 0x91, 0x0c, + 0x22, 0xff, 0x90, 0x00, 0x3d, 0x23, 0x18, 0x50, 0x99, 0x45, 0x21, 0x4c, + 0x4a, 0x30, 0x1e, 0x00, 0x24, 0x25, 0x56, 0x00, 0x50, 0x11, 0x21, 0xeb, + 0x2b, 0xfd, 0x00, 0x00, 0x40, 0x6e, 0x42, 0x4d, 0x49, 0xfc, 0x0c, 0x00, + 0x44, 0x00, 0x50, 0x13, 0x02, 0xb4, 0x49, 0xff, 0xe7, 0x30, 0x34, 0x00, + 0x73, 0xcf, 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x30, 0xf0, 0xff, 0x12, 0x94, + 0x22, 0xff, 0x21, 0xe8, 0x56, 0x30, 0x7c, 0x00, 0xe2, 0x02, 0x50, 0xb9, + 0x1c, 0xcf, 0xf6, 0xfa, 0x10, 0x00, 0xb0, 0x32, 0x78, 0x00, 0x94, 0x32, + 0x59, 0x5e, 0xf4, 0x45, 0x95, 0x0c, 0xe2, 0x0e, 0xf4, 0x45, 0x82, 0x0c, + 0xf5, 0x96, 0x10, 0x00, 0xb7, 0x0c, 0xb7, 0x41, 0x10, 0x80, 0x42, 0x0e, + 0xf7, 0x32, 0x0b, 0x13, 0xa5, 0x30, 0x48, 0x00, 0xf7, 0x45, 0x91, 0x0c, + 0xf4, 0x45, 0x92, 0x0c, 0xb2, 0x0c, 0xb5, 0xb4, 0xf7, 0xff, 0x42, 0x0e, + 0xa2, 0x41, 0x09, 0x80, 0x62, 0x30, 0xd4, 0x4c, 0x02, 0xf8, 0xd4, 0x4c, + 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0xd0, 0x4c, 0x9c, 0xcf, 0x32, 0xa8, + 0x74, 0x14, 0x2b, 0x00, 0x56, 0xfc, 0x00, 0x00, 0xb5, 0x41, 0x01, 0x80, + 0xb4, 0x30, 0x2c, 0x00, 0x62, 0x18, 0x20, 0x00, 0xd4, 0x14, 0x2b, 0x00, + 0xb5, 0x32, 0xbd, 0xa4, 0xd5, 0x45, 0x96, 0xfc, 0x00, 0x00, 0x01, 0xed, + 0x5e, 0x94, 0x39, 0xff, 0xb4, 0x30, 0x4d, 0x00, 0x74, 0x14, 0x4c, 0x00, + 0x56, 0xfc, 0x00, 0x00, 0x62, 0x18, 0x41, 0x00, 0x96, 0xfc, 0x00, 0x00, + 0xd4, 0x14, 0x4c, 0x00, 0xd5, 0x45, 0x84, 0x30, 0x21, 0x00, 0x54, 0x14, + 0x70, 0x00, 0x74, 0x14, 0x6f, 0x00, 0x20, 0x25, 0xd3, 0x44, 0xe2, 0x40, + 0x2a, 0xff, 0x96, 0xfc, 0x10, 0x00, 0xd2, 0x0c, 0xb4, 0x30, 0x71, 0x00, + 0xd5, 0x45, 0x56, 0xfa, 0x14, 0x00, 0x23, 0xcf, 0x76, 0x30, 0x24, 0x00, + 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0x15, 0x26, 0xe2, 0x45, 0x91, 0x0c, + 0x80, 0xce, 0x54, 0x16, 0x70, 0x00, 0x62, 0x02, 0x50, 0x11, 0xb1, 0xce, + 0x56, 0xf8, 0x10, 0x00, 0xe2, 0x40, 0xfb, 0xfe, 0x49, 0xfc, 0x0c, 0x00, + 0x80, 0x87, 0xc2, 0x40, 0xc6, 0xfe, 0x00, 0x0c, 0xa2, 0x4d, 0x68, 0x4d, + 0xaf, 0xce, 0x82, 0x4d, 0x21, 0x2d, 0xa2, 0x40, 0xf3, 0xff, 0xa2, 0x4d, + 0x68, 0x4d, 0xa8, 0xce, 0x82, 0x4d, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0x99, 0xff, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0x01, 0xed, 0x5c, 0x18, 0x58, 0x82, 0x06, 0x47, 0x00, 0x0c, + 0xe9, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x60, 0x9b, 0x68, 0x45, + 0x04, 0x0e, 0x25, 0x0e, 0x14, 0x8d, 0x46, 0x0e, 0xa4, 0x41, 0x09, 0x80, + 0xa2, 0x41, 0x01, 0x80, 0xf8, 0x6e, 0x06, 0xef, 0x84, 0x30, 0xd4, 0x4c, + 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0xfd, 0xf8, 0x18, 0x00, 0xe6, 0x48, + 0x81, 0xed, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x18, 0xd0, 0x4c, 0x51, 0x48, + 0x52, 0x84, 0x45, 0xc8, 0x50, 0x48, 0x44, 0xc8, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0x6d, 0x9f, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0x28, 0x45, + 0x0c, 0x47, 0x00, 0x0c, 0x43, 0x29, 0xc2, 0x2b, 0x44, 0x2b, 0x60, 0x50, + 0xff, 0xff, 0x97, 0x44, 0x96, 0x44, 0x62, 0x94, 0x3c, 0x00, 0xa9, 0x41, + 0x09, 0x80, 0x44, 0x09, 0x21, 0x2d, 0x3f, 0x8d, 0x29, 0x31, 0xe8, 0x4c, + 0x49, 0xfc, 0x14, 0x00, 0x20, 0x6d, 0x49, 0xf8, 0x14, 0x00, 0x40, 0x29, + 0x88, 0xed, 0x42, 0xd0, 0x0c, 0x00, 0x62, 0x94, 0x06, 0x00, 0x00, 0x0c, + 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0x09, 0xf6, 0xb9, 0x45, 0x45, 0x60, + 0x17, 0x00, 0x45, 0x60, 0x14, 0x10, 0x76, 0x8d, 0xc0, 0x0c, 0xe9, 0xfc, + 0x24, 0x00, 0x64, 0x25, 0x64, 0x05, 0x22, 0x25, 0x2a, 0x05, 0x62, 0x14, + 0x41, 0x00, 0x02, 0x15, 0x40, 0x00, 0x60, 0x6f, 0x30, 0x25, 0x02, 0x01, + 0x90, 0x12, 0xae, 0x07, 0xe9, 0xf8, 0x24, 0x00, 0x45, 0x60, 0x17, 0x00, + 0x45, 0x60, 0x14, 0x10, 0x46, 0x00, 0x90, 0x13, 0x6b, 0xad, 0x64, 0x25, + 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0x09, 0xf6, 0xb9, 0x45, 0x29, 0x31, + 0xe8, 0x4c, 0x49, 0xfc, 0x18, 0x00, 0x20, 0x6d, 0xca, 0xcf, 0x49, 0xf8, + 0x18, 0x00, 0x49, 0xfc, 0x10, 0x00, 0x20, 0x6d, 0xc4, 0xcf, 0x49, 0xf8, + 0x10, 0x00, 0x00, 0x0c, 0x49, 0x29, 0x48, 0x2b, 0xca, 0x2a, 0x60, 0x50, + 0xff, 0xff, 0x96, 0x44, 0x95, 0x44, 0x62, 0x94, 0x21, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x44, 0x14, 0x10, 0x00, 0x21, 0x2d, 0x11, 0xad, 0xa2, 0x41, + 0x09, 0x80, 0x44, 0x09, 0x21, 0x2d, 0x07, 0xad, 0xa3, 0x41, 0x09, 0x80, + 0x43, 0xfc, 0xe8, 0x4c, 0x20, 0x6d, 0x43, 0xf8, 0xe8, 0x4c, 0xb9, 0x41, + 0x04, 0x80, 0x39, 0x33, 0x41, 0xe0, 0xb9, 0x45, 0x42, 0x30, 0xe8, 0x4c, + 0xa1, 0x69, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0x41, 0xe0, 0xb0, 0x6d, + 0x99, 0x45, 0xa1, 0xe9, 0x42, 0x30, 0xe8, 0x4c, 0xa2, 0x69, 0xb9, 0x41, + 0x04, 0x80, 0x39, 0x33, 0x41, 0xe0, 0xb0, 0x6d, 0x99, 0x45, 0xa2, 0xe9, + 0xf1, 0x4f, 0x55, 0x45, 0x04, 0x0e, 0x40, 0x6a, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x8f, 0x1c, 0xc2, 0x45, 0x24, 0xfe, 0x70, 0x00, 0x08, 0xee, + 0x90, 0x29, 0x63, 0xd0, 0x0c, 0x00, 0x83, 0x94, 0x0a, 0x00, 0x00, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x59, 0x70, 0xe2, 0x45, 0x90, 0x0c, + 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, 0xe2, 0x40, 0xf5, 0xff, 0x02, 0x15, + 0x28, 0x00, 0x08, 0x94, 0xf1, 0xff, 0xa9, 0x41, 0x09, 0x80, 0x29, 0x31, + 0xe8, 0x4c, 0xc9, 0xfc, 0x0c, 0x00, 0xa0, 0x0c, 0xd2, 0x25, 0xd6, 0x05, + 0xb2, 0x25, 0xb4, 0x05, 0x83, 0x14, 0x2a, 0x00, 0xe3, 0x14, 0x29, 0x00, + 0xd0, 0x6e, 0xc0, 0x25, 0xdf, 0x44, 0x05, 0xb5, 0xf3, 0xff, 0x3c, 0x07, + 0xa2, 0x41, 0x04, 0x80, 0x90, 0x0c, 0x42, 0x30, 0x59, 0x70, 0xc2, 0x45, + 0xc9, 0xf8, 0x0c, 0x00, 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, 0x00, 0x0c, + 0xf1, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x55, 0x45, 0xa0, 0x30, 0xd0, 0x00, + 0x24, 0x0e, 0x42, 0x30, 0x51, 0x1e, 0xc2, 0x45, 0x80, 0x30, 0x93, 0x02, + 0x02, 0x94, 0x78, 0x00, 0x02, 0x0e, 0x02, 0x60, 0x0b, 0x80, 0x02, 0x60, + 0x08, 0x90, 0x40, 0x30, 0x93, 0x02, 0x50, 0x60, 0x03, 0x80, 0x50, 0x60, + 0x00, 0x90, 0x01, 0xed, 0x50, 0x60, 0x07, 0x80, 0x50, 0x60, 0x04, 0x90, + 0x82, 0xed, 0x70, 0x60, 0x0f, 0x80, 0xa4, 0x41, 0x09, 0x80, 0x70, 0x60, + 0x0c, 0x90, 0x40, 0x30, 0x87, 0x02, 0x84, 0xfc, 0xac, 0x9b, 0x50, 0x60, + 0x13, 0x80, 0x50, 0x60, 0x10, 0x90, 0x44, 0xfc, 0x84, 0x01, 0x62, 0x94, + 0x37, 0x00, 0x83, 0xed, 0x62, 0x94, 0x3e, 0x00, 0x84, 0xed, 0x62, 0x94, + 0x46, 0x00, 0x00, 0x0c, 0x0d, 0x8d, 0xa2, 0x41, 0x02, 0x80, 0xa2, 0x41, + 0x10, 0x80, 0xa0, 0x30, 0x93, 0x02, 0x42, 0x30, 0x4f, 0x23, 0xe2, 0x45, + 0x90, 0x0c, 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, 0x42, 0x30, 0xd9, 0xf9, + 0xe2, 0x45, 0x0a, 0x6e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x8b, 0x1d, + 0xc2, 0x45, 0x90, 0x30, 0xb2, 0x00, 0xa2, 0x41, 0x10, 0x80, 0xb1, 0x0c, + 0x42, 0x30, 0x79, 0x1d, 0xc2, 0x45, 0x90, 0x30, 0x26, 0x00, 0xa5, 0x41, + 0x09, 0x80, 0xa2, 0x41, 0x01, 0x80, 0x30, 0xef, 0xa5, 0x30, 0xe8, 0x4c, + 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x90, 0x30, 0x63, 0x02, 0xd7, 0xcf, + 0xa2, 0x41, 0x10, 0x80, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x8b, 0x1d, + 0xc2, 0x45, 0x90, 0x30, 0xb2, 0x00, 0xeb, 0xcf, 0xa5, 0x41, 0x09, 0x80, + 0xa2, 0x41, 0x10, 0x80, 0xb1, 0x0c, 0x42, 0x30, 0x79, 0x1d, 0xc2, 0x45, + 0x90, 0x30, 0x26, 0x00, 0xc2, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0xd9, 0xf9, 0xe2, 0x45, 0x0a, 0x6e, 0xb9, 0xcf, + 0xa2, 0x41, 0x10, 0x80, 0xbd, 0xcf, 0x7f, 0xed, 0xf1, 0x4f, 0x64, 0x45, + 0x04, 0x0e, 0x8c, 0x48, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x55, 0x14, + 0x45, 0x0e, 0xe2, 0x45, 0x26, 0x0e, 0x50, 0x60, 0x0b, 0x80, 0x50, 0x60, + 0x08, 0x90, 0x50, 0x62, 0x03, 0x80, 0x50, 0x62, 0x00, 0x90, 0x30, 0x62, + 0x07, 0x80, 0x30, 0x62, 0x04, 0x90, 0x24, 0x45, 0x08, 0x47, 0x00, 0x0c, + 0xed, 0x4f, 0x66, 0x69, 0xbd, 0x22, 0x10, 0xd0, 0x85, 0x0e, 0x42, 0xd0, + 0x00, 0x01, 0x0e, 0xad, 0x00, 0x0e, 0x44, 0xfc, 0x40, 0x00, 0x42, 0x00, + 0x2c, 0x01, 0xe2, 0x40, 0x35, 0x00, 0x46, 0x1c, 0x26, 0x00, 0x22, 0x24, + 0x20, 0x04, 0x06, 0x24, 0x20, 0x04, 0x04, 0x24, 0x74, 0x32, 0x78, 0x00, + 0xb2, 0x41, 0x05, 0x80, 0x52, 0x32, 0x59, 0x5e, 0xf2, 0x45, 0x93, 0x0c, + 0x53, 0x94, 0x07, 0x00, 0x00, 0x0c, 0x42, 0xfc, 0x6c, 0x00, 0x02, 0x02, + 0x50, 0x83, 0x1b, 0x8c, 0x7f, 0xed, 0xf2, 0x45, 0x93, 0x0c, 0x22, 0x0e, + 0xf2, 0x45, 0x82, 0x0c, 0x33, 0x96, 0x12, 0x00, 0x94, 0x32, 0x20, 0x01, + 0xb1, 0x0c, 0xb1, 0x41, 0x10, 0x80, 0x02, 0x0e, 0x31, 0x32, 0x0b, 0x13, + 0xa5, 0x30, 0x48, 0x00, 0xf1, 0x45, 0x94, 0x0c, 0xf2, 0x45, 0x90, 0x0c, + 0xb0, 0x0c, 0xb3, 0xb4, 0xf7, 0xff, 0x02, 0x0e, 0x40, 0x0c, 0xbd, 0x22, + 0x10, 0x50, 0x0a, 0x47, 0x04, 0xfe, 0x40, 0x00, 0x10, 0x02, 0xec, 0x00, + 0x4f, 0x8c, 0x74, 0x32, 0x78, 0x00, 0x66, 0x1c, 0x26, 0x00, 0x44, 0x1c, + 0x64, 0x00, 0x32, 0x24, 0x30, 0x04, 0x06, 0x24, 0x30, 0x04, 0x04, 0x24, + 0x50, 0x00, 0x3c, 0xab, 0x02, 0x00, 0x3c, 0x70, 0xbf, 0xcf, 0x50, 0x46, + 0x44, 0x60, 0x27, 0x00, 0x44, 0x60, 0x24, 0x10, 0x24, 0x2d, 0x05, 0x8d, + 0x81, 0xed, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x18, 0x1c, 0x4d, 0xb9, 0x41, + 0x03, 0x80, 0x39, 0x33, 0x09, 0xb5, 0xb9, 0x45, 0xf5, 0x4f, 0x44, 0x45, + 0x05, 0xfe, 0xb0, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x24, 0x9b, + 0x16, 0x8c, 0x40, 0x0c, 0x45, 0x14, 0x0b, 0x01, 0x11, 0x8d, 0xa2, 0x41, + 0x01, 0x80, 0x02, 0xef, 0xa3, 0x30, 0x09, 0x00, 0x42, 0x30, 0xa1, 0xa4, + 0xe2, 0x45, 0x90, 0x0c, 0x07, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, + 0x1c, 0x4d, 0x05, 0x8d, 0xa2, 0x41, 0x10, 0x80, 0x40, 0x0c, 0x04, 0x45, + 0x06, 0x47, 0x88, 0x86, 0x42, 0x30, 0x47, 0x22, 0xe2, 0x45, 0x00, 0x0c, + 0x40, 0x0c, 0x04, 0x45, 0x06, 0x47, 0x00, 0x0c, 0x35, 0x4f, 0x3d, 0x23, + 0x70, 0xd1, 0xa4, 0xfe, 0x34, 0x00, 0x15, 0x94, 0x10, 0x01, 0xe5, 0xfe, + 0x70, 0x00, 0x45, 0xfc, 0x48, 0x00, 0x42, 0xb0, 0x18, 0x00, 0x0e, 0xad, + 0xc4, 0x0f, 0x57, 0x34, 0x00, 0x00, 0x50, 0xee, 0x42, 0xd0, 0xfc, 0x00, + 0x82, 0x94, 0x0a, 0x00, 0x05, 0x0e, 0x80, 0x30, 0x80, 0x00, 0x82, 0x94, + 0x29, 0x00, 0x00, 0x0c, 0x3d, 0x23, 0x70, 0x51, 0x9f, 0x45, 0xcd, 0x4c, + 0x5e, 0xfe, 0xa0, 0x06, 0x9e, 0xfe, 0x84, 0x06, 0xf2, 0x40, 0x24, 0x01, + 0x7e, 0xfe, 0x34, 0x06, 0x5e, 0xfc, 0x88, 0x06, 0x13, 0x94, 0x03, 0x00, + 0xa0, 0x0c, 0xb3, 0xfc, 0x20, 0x00, 0xe2, 0x40, 0x51, 0x01, 0x2a, 0x69, + 0x5d, 0xf8, 0x50, 0x01, 0xd7, 0x32, 0x04, 0x00, 0xb1, 0x41, 0x04, 0x80, + 0xd6, 0x0c, 0x31, 0x32, 0xe1, 0x9c, 0xf1, 0x45, 0x92, 0x0c, 0x02, 0x94, + 0xde, 0x00, 0xbd, 0xfc, 0x50, 0x01, 0x0b, 0xcc, 0x9e, 0xfc, 0x34, 0x00, + 0x5e, 0xfe, 0xa0, 0x06, 0x5e, 0xfc, 0x84, 0x06, 0xf2, 0x40, 0xfc, 0x00, + 0x7e, 0xfe, 0x34, 0x06, 0x95, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xf5, 0x16, 0xc2, 0x45, 0xb0, 0x34, 0x30, 0x00, 0x47, 0x8d, 0xc2, 0x0e, + 0x22, 0x69, 0x21, 0x2d, 0x43, 0xad, 0x0a, 0x6d, 0xf5, 0xfc, 0x60, 0xff, + 0x5d, 0xf8, 0x50, 0x01, 0x71, 0x69, 0xe2, 0x40, 0x74, 0x00, 0x70, 0x69, + 0x42, 0x14, 0x20, 0x00, 0x02, 0x94, 0xbf, 0x00, 0x57, 0x30, 0x24, 0x00, + 0x22, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x82, 0x84, 0x24, 0xef, 0x80, 0x0c, + 0x42, 0x30, 0xf7, 0x11, 0x04, 0xc8, 0x05, 0xc8, 0xc2, 0x45, 0x3d, 0xfa, + 0x68, 0x01, 0xaa, 0x41, 0x09, 0x80, 0x82, 0x0e, 0x4a, 0x30, 0x60, 0x9b, + 0x25, 0xe8, 0x26, 0xe8, 0x27, 0xe8, 0x28, 0xe8, 0x29, 0xe8, 0x2a, 0xe8, + 0x2b, 0xe8, 0x2c, 0xe8, 0x2d, 0xe8, 0xb0, 0xfc, 0x48, 0x00, 0x97, 0x30, + 0x10, 0x00, 0x00, 0x85, 0x0a, 0xf8, 0x60, 0x9b, 0xdd, 0x20, 0x10, 0x90, + 0x87, 0xc8, 0x88, 0xc8, 0x06, 0xc8, 0x24, 0xe8, 0x23, 0xe8, 0x22, 0xe8, + 0x21, 0xe8, 0xa2, 0x41, 0x10, 0x80, 0x95, 0x6f, 0xa5, 0x30, 0xdc, 0xff, + 0x42, 0x30, 0x7d, 0x1c, 0xe2, 0x45, 0x91, 0x0c, 0xf5, 0xfc, 0x60, 0xff, + 0x47, 0xfd, 0x04, 0x00, 0x8a, 0x40, 0xac, 0x00, 0x54, 0x30, 0x02, 0x00, + 0x5d, 0xf8, 0x60, 0x01, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xa1, 0xa4, + 0x20, 0x0e, 0x87, 0xfd, 0x00, 0x00, 0x09, 0xcc, 0x5d, 0xf8, 0x64, 0x01, + 0x90, 0x6c, 0x9d, 0x2c, 0x51, 0x01, 0x50, 0x13, 0x02, 0x94, 0x99, 0x00, + 0x4e, 0x48, 0x9a, 0x26, 0x9a, 0x06, 0xac, 0x00, 0x50, 0x29, 0x45, 0x14, + 0x20, 0x00, 0xe2, 0x40, 0xf1, 0xff, 0xd4, 0x14, 0x01, 0x00, 0x46, 0xb4, + 0xed, 0xff, 0x9d, 0xfc, 0x60, 0x01, 0x5d, 0xfc, 0x64, 0x01, 0x5d, 0xf9, + 0x54, 0x01, 0x9d, 0xf9, 0x58, 0x01, 0xc2, 0x45, 0xfd, 0xf8, 0x5c, 0x01, + 0x5d, 0xfd, 0x54, 0x01, 0x9d, 0xfd, 0x58, 0x01, 0x5d, 0xad, 0xfd, 0xfc, + 0x5c, 0x01, 0x53, 0xfc, 0x78, 0x00, 0xe2, 0x40, 0x51, 0x00, 0x70, 0x69, + 0x42, 0x14, 0x20, 0x00, 0x1c, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x47, 0x34, + 0x38, 0x00, 0xa7, 0x34, 0x3a, 0x00, 0x87, 0x34, 0x3c, 0x00, 0xd5, 0x44, + 0xd4, 0x44, 0x2f, 0x2d, 0x02, 0x94, 0x90, 0x00, 0x04, 0xed, 0xa2, 0x41, + 0x01, 0x80, 0x06, 0xef, 0xa7, 0x30, 0x38, 0x00, 0x42, 0x30, 0xa1, 0xa4, + 0xc2, 0x45, 0x97, 0x30, 0x10, 0x00, 0x02, 0xb4, 0x25, 0xff, 0xa2, 0x41, + 0x09, 0x80, 0x97, 0x0c, 0x42, 0x30, 0x3d, 0xce, 0xe2, 0x45, 0x95, 0x6e, + 0xf0, 0xfc, 0x48, 0x00, 0xbd, 0xfc, 0x50, 0x01, 0xa2, 0x41, 0x10, 0x80, + 0xd7, 0x0c, 0x9e, 0x0c, 0x42, 0x30, 0x7b, 0x15, 0xc4, 0xca, 0xc2, 0x45, + 0x1d, 0xf8, 0x14, 0x00, 0xe2, 0x40, 0x0e, 0xff, 0xa2, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x5f, 0x19, 0xe2, 0x45, 0x9e, 0x0c, 0x06, 0xcf, + 0x00, 0x0c, 0x5c, 0xfc, 0xe4, 0x81, 0x20, 0x6d, 0xee, 0xce, 0x5c, 0xf8, + 0xe4, 0x81, 0xd6, 0x0c, 0xf1, 0x45, 0x94, 0x0c, 0xe2, 0x40, 0xfa, 0xfe, + 0x2a, 0xcf, 0x9e, 0xfc, 0x34, 0x00, 0x53, 0xfc, 0x78, 0x00, 0x51, 0xad, + 0xa2, 0x41, 0x09, 0x80, 0xf0, 0xfc, 0x48, 0x00, 0xbd, 0xfc, 0x50, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x41, 0x25, 0xd7, 0x0c, 0x9e, 0x0c, + 0xc2, 0x45, 0xdd, 0xfa, 0x10, 0x00, 0x57, 0x34, 0x22, 0x00, 0x21, 0x2d, + 0x02, 0x94, 0xe0, 0xfe, 0xa2, 0x41, 0x10, 0x80, 0x20, 0xef, 0xb6, 0x0c, + 0x42, 0x30, 0x41, 0x22, 0xe2, 0x45, 0x95, 0x0c, 0xd7, 0xce, 0x00, 0x0c, + 0xa2, 0x40, 0x02, 0xff, 0xd3, 0xce, 0x00, 0x0c, 0xf4, 0x40, 0xd0, 0xfe, + 0xd9, 0xce, 0x00, 0x0c, 0x4e, 0x48, 0xe2, 0x40, 0xcb, 0xfe, 0x22, 0x09, + 0x2c, 0x2d, 0x02, 0x94, 0xc7, 0xfe, 0x5d, 0xfc, 0x20, 0x01, 0x02, 0x94, + 0xc3, 0xfe, 0x15, 0x6d, 0xf0, 0xfc, 0x48, 0x00, 0xbd, 0xfc, 0x68, 0x01, + 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xd7, 0x0c, 0x95, 0x30, 0xe0, 0xfe, + 0x42, 0x30, 0x1d, 0x13, 0xc2, 0x45, 0xe7, 0x30, 0xdc, 0xff, 0x02, 0x94, + 0xb1, 0xfe, 0xdd, 0xfc, 0x50, 0x01, 0xa2, 0x41, 0x09, 0x80, 0xf7, 0x0c, + 0xb2, 0x0c, 0x9e, 0x0c, 0x04, 0xca, 0x42, 0x30, 0x39, 0xca, 0xc2, 0x45, + 0xdd, 0xfa, 0x14, 0x00, 0xa3, 0xce, 0x00, 0x0c, 0x75, 0xfc, 0x6c, 0xff, + 0x43, 0xb4, 0x7b, 0xff, 0xa2, 0x41, 0x09, 0x80, 0x9b, 0xce, 0x00, 0x0c, + 0xb1, 0xce, 0x1d, 0xf8, 0x50, 0x01, 0x00, 0x0c, 0xe5, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0xdd, 0x22, 0x1c, 0xd0, 0x46, 0x32, 0x2c, 0x00, 0x24, 0x0e, + 0x65, 0x0e, 0x92, 0x0c, 0x42, 0x30, 0x0b, 0x1f, 0x86, 0x0e, 0xc2, 0x45, + 0xb3, 0x32, 0x58, 0x00, 0xa2, 0x41, 0x05, 0x80, 0xff, 0xee, 0x42, 0x30, + 0xf1, 0x4b, 0xe2, 0x45, 0x95, 0x0c, 0x11, 0x62, 0x27, 0x00, 0x11, 0x62, + 0x24, 0x10, 0x39, 0xac, 0xa2, 0x41, 0x05, 0x80, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0x41, 0x5e, 0xc2, 0x45, 0x93, 0x30, 0x70, 0x00, 0x02, 0x94, + 0x4a, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x40, 0x30, 0x45, 0x02, 0x44, 0xc8, + 0xa2, 0x41, 0x10, 0x80, 0x89, 0x6e, 0x42, 0x30, 0xb7, 0x24, 0xe2, 0x45, + 0x02, 0xee, 0x02, 0x94, 0x43, 0x00, 0x22, 0x0e, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x55, 0x14, 0xe2, 0x45, 0x7d, 0xee, 0x51, 0x60, 0x0b, 0x80, + 0x51, 0x60, 0x08, 0x90, 0x11, 0x60, 0x07, 0x80, 0xa2, 0x41, 0x03, 0x80, + 0xf2, 0x86, 0x42, 0x30, 0x85, 0xbc, 0xc2, 0x45, 0x11, 0x60, 0x04, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, 0x45, 0x02, 0x42, 0x30, 0x19, 0x1d, + 0xe2, 0x45, 0x91, 0x0c, 0x10, 0xcc, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, + 0x15, 0x01, 0xe2, 0x45, 0x93, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x7c, 0x84, + 0x42, 0x30, 0x4d, 0x06, 0xe2, 0x45, 0x91, 0x0c, 0x02, 0x0e, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0xf9, 0x4b, 0xe2, 0x45, 0x95, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x1d, 0x1f, 0xe2, 0x45, 0x92, 0x0c, 0x50, 0x0c, + 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, 0x7c, 0x84, 0x42, 0x30, 0x29, 0xc0, + 0xe2, 0x45, 0x91, 0x0c, 0xea, 0xcf, 0x02, 0x0e, 0xf4, 0xcf, 0x00, 0x32, + 0x97, 0xff, 0x00, 0x0c, 0x01, 0xed, 0x45, 0x94, 0x0e, 0x00, 0x06, 0xed, + 0x45, 0x94, 0x0e, 0x00, 0x07, 0xed, 0x08, 0xed, 0x45, 0x94, 0x03, 0x00, + 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, 0x04, 0xed, 0x4e, 0xe9, 0x9f, 0x45, + 0x40, 0x0c, 0x4e, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x4e, 0xe9, 0x9f, 0x45, + 0x40, 0x0c, 0x00, 0x0c, 0x55, 0x09, 0x82, 0xed, 0x62, 0x94, 0x09, 0x00, + 0x62, 0xb0, 0x03, 0x00, 0x03, 0xb4, 0x46, 0x00, 0x84, 0xed, 0x62, 0xb4, + 0x22, 0x00, 0x85, 0xed, 0x03, 0xed, 0x4e, 0xe9, 0x56, 0x09, 0x01, 0xef, + 0x44, 0x4c, 0x24, 0x25, 0x2d, 0x2d, 0xaa, 0x05, 0xb0, 0x09, 0x44, 0x4c, + 0xb4, 0x25, 0x26, 0x05, 0x2d, 0x2d, 0xaa, 0x06, 0xdf, 0x09, 0x04, 0x18, + 0x49, 0x00, 0x50, 0x09, 0x2d, 0x25, 0x44, 0x18, 0x49, 0x00, 0xc3, 0x94, + 0x25, 0x00, 0x06, 0xed, 0x43, 0x94, 0x2e, 0x00, 0x07, 0xed, 0x08, 0xed, + 0x43, 0x94, 0x21, 0x00, 0x00, 0x0c, 0x9f, 0x45, 0x40, 0x0c, 0x62, 0xb4, + 0x23, 0x00, 0x00, 0x0c, 0x01, 0xed, 0x4e, 0xe9, 0x56, 0x09, 0x01, 0xef, + 0x44, 0x4c, 0x24, 0x25, 0x2d, 0x2d, 0xaa, 0x05, 0xb0, 0x09, 0x44, 0x4c, + 0xb4, 0x25, 0x26, 0x05, 0x2d, 0x2d, 0xaa, 0x06, 0xdf, 0x09, 0x04, 0x18, + 0x49, 0x00, 0x50, 0x09, 0x2d, 0x25, 0x44, 0x18, 0x49, 0x00, 0xc3, 0xb4, + 0xdd, 0xff, 0x06, 0xed, 0x4e, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x04, 0xed, + 0xfc, 0xcf, 0x4e, 0xe9, 0x81, 0xed, 0x62, 0x94, 0xdf, 0xff, 0x00, 0x0c, + 0xbb, 0xcf, 0x4e, 0xe8, 0x4e, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, + 0xe5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xf1, 0xa5, 0x3d, 0x23, + 0x10, 0xd0, 0xc2, 0x45, 0xb7, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, + 0x62, 0xfc, 0x88, 0x4c, 0xa2, 0x41, 0x00, 0xb0, 0x62, 0xf8, 0xdc, 0x4f, + 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0x8c, 0x4c, 0x62, 0xf8, 0xd8, 0x4f, + 0x57, 0xfc, 0x58, 0xbf, 0x02, 0x94, 0xa3, 0x00, 0xb1, 0x41, 0x05, 0x80, + 0xa4, 0x41, 0x09, 0x80, 0x31, 0x32, 0xe9, 0x4b, 0xd1, 0x45, 0x84, 0x30, + 0xc4, 0x9b, 0x17, 0xfe, 0x58, 0xbf, 0xb4, 0x41, 0x05, 0x80, 0x94, 0x32, + 0x59, 0x5e, 0xd1, 0x45, 0x90, 0x30, 0x3c, 0x00, 0xd1, 0x45, 0x90, 0x30, + 0x58, 0x00, 0xd1, 0x45, 0x90, 0x30, 0x64, 0x00, 0x97, 0xfc, 0x58, 0xbf, + 0xd4, 0x45, 0x84, 0x30, 0x20, 0x02, 0xa2, 0x0e, 0x57, 0xfc, 0x58, 0xbf, + 0x42, 0x30, 0x20, 0x02, 0x55, 0x94, 0x7f, 0x00, 0xb6, 0x41, 0x10, 0x80, + 0xd6, 0x32, 0x17, 0x1f, 0x40, 0x32, 0x10, 0x00, 0xd1, 0x45, 0x95, 0x30, + 0x20, 0x00, 0xd1, 0x45, 0x95, 0x30, 0x2c, 0x00, 0xd1, 0x45, 0x95, 0x30, + 0x8c, 0x00, 0xd5, 0xff, 0x10, 0x00, 0xd1, 0x45, 0x9e, 0x30, 0xb8, 0x00, + 0x7e, 0xfe, 0x50, 0x02, 0xd1, 0x45, 0x93, 0x30, 0xf4, 0x03, 0xd1, 0x45, + 0x93, 0x30, 0x60, 0x04, 0xd1, 0x45, 0x93, 0x30, 0x54, 0x04, 0xd1, 0x45, + 0x93, 0x30, 0xe4, 0x05, 0xd1, 0x45, 0x93, 0x30, 0xf0, 0x05, 0xd1, 0x45, + 0x93, 0x30, 0xfc, 0x05, 0xd1, 0x45, 0x93, 0x30, 0xc8, 0x06, 0xd1, 0x45, + 0x93, 0x30, 0xb4, 0x07, 0x13, 0xfe, 0x3c, 0x00, 0x73, 0x32, 0x70, 0x04, + 0xf1, 0x45, 0x0c, 0x6e, 0xd1, 0x45, 0x90, 0x30, 0x90, 0x0c, 0xd1, 0x45, + 0x90, 0x30, 0x78, 0x0c, 0xd1, 0x45, 0x90, 0x30, 0x84, 0x0c, 0x90, 0x30, + 0x3c, 0x0b, 0xf6, 0x45, 0xa0, 0x0c, 0x90, 0x30, 0x30, 0x0b, 0xf6, 0x45, + 0xa0, 0x0c, 0x90, 0x30, 0x18, 0x0b, 0xf6, 0x45, 0xa0, 0x0c, 0xa0, 0x0c, + 0xd6, 0x45, 0x90, 0x30, 0x24, 0x0b, 0xd1, 0x45, 0x9e, 0x30, 0x98, 0x06, + 0xf4, 0x45, 0x93, 0x0c, 0x53, 0x94, 0x21, 0x00, 0x02, 0x0e, 0xd1, 0x45, + 0x90, 0x30, 0x54, 0x00, 0xd1, 0x45, 0x90, 0x30, 0x60, 0x00, 0xd1, 0x45, + 0x90, 0x30, 0x7c, 0x00, 0xd1, 0x45, 0x90, 0x30, 0xac, 0x04, 0xc0, 0x0f, + 0x5e, 0x30, 0x2c, 0x01, 0x24, 0x25, 0x20, 0x05, 0x22, 0x69, 0xc2, 0x4f, + 0x03, 0x8d, 0x24, 0x6e, 0xf1, 0x45, 0x00, 0x0c, 0x5e, 0xb6, 0xf6, 0xff, + 0x5e, 0x30, 0x2c, 0x01, 0xf4, 0x45, 0x90, 0x0c, 0x53, 0xb4, 0xe1, 0xff, + 0x02, 0x0e, 0xf4, 0x45, 0x95, 0x0c, 0xa2, 0x0e, 0x57, 0xfc, 0x58, 0xbf, + 0x42, 0x30, 0x20, 0x02, 0x55, 0xb4, 0x88, 0xff, 0x00, 0x0c, 0x3d, 0x23, + 0x10, 0x50, 0x0e, 0x47, 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, + 0x30, 0xea, 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, + 0xfc, 0xff, 0x34, 0x69, 0xbf, 0x45, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0x7d, 0xa4, 0xe9, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xa6, 0x41, 0x01, 0xa4, 0xc6, 0x50, 0x10, 0xb8, 0x89, 0x6e, 0x40, 0xee, + 0x66, 0x30, 0xf4, 0xff, 0xc4, 0xef, 0x60, 0xea, 0x30, 0x69, 0x22, 0x2d, + 0xe2, 0x40, 0xfc, 0xff, 0x34, 0x69, 0x40, 0x6e, 0x50, 0xe9, 0xe4, 0xb4, + 0xf6, 0xff, 0xd2, 0x6e, 0x44, 0x48, 0xff, 0xed, 0x62, 0x94, 0x58, 0x00, + 0x00, 0x0c, 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, 0x55, 0xed, + 0x30, 0xe9, 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, + 0xfc, 0xff, 0xb4, 0x69, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xf8, 0x88, 0x4c, + 0xa3, 0x41, 0x01, 0xa4, 0x63, 0x50, 0x10, 0xb8, 0x1d, 0xed, 0x30, 0xe9, + 0x63, 0x30, 0xf4, 0xff, 0x30, 0x69, 0x22, 0x2d, 0x7d, 0x8d, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0x5c, 0xbf, 0x34, 0x6b, 0x2f, 0x6a, 0xa3, 0x41, + 0xfa, 0x50, 0xa5, 0x41, 0x09, 0x80, 0x63, 0x30, 0xfa, 0x50, 0x64, 0x94, + 0x03, 0x00, 0xc5, 0xf8, 0x8c, 0x4c, 0x2f, 0xe8, 0xa3, 0x41, 0x01, 0xa4, + 0x63, 0x50, 0x10, 0xb8, 0x56, 0xed, 0x30, 0xe9, 0x63, 0x30, 0xf4, 0xff, + 0x30, 0x69, 0x22, 0x2d, 0xe2, 0x40, 0xfc, 0xff, 0xb4, 0x69, 0xa6, 0x41, + 0x01, 0xa4, 0xc6, 0x50, 0x10, 0xb8, 0xa2, 0x41, 0x09, 0x80, 0xa5, 0x41, + 0x09, 0x80, 0x62, 0xf8, 0x90, 0x4c, 0xa5, 0x30, 0x94, 0x4c, 0x57, 0xee, + 0x66, 0x30, 0xf4, 0xff, 0xe6, 0xef, 0x60, 0xea, 0x30, 0x69, 0x22, 0x2d, + 0xe2, 0x40, 0xfc, 0xff, 0x34, 0x69, 0x40, 0x6e, 0x50, 0xe9, 0xe4, 0xb4, + 0xf6, 0xff, 0xd2, 0x6e, 0xe9, 0x4b, 0x0a, 0x47, 0x85, 0x48, 0x44, 0xb4, + 0xa8, 0xff, 0xa3, 0x41, 0x01, 0xa4, 0x66, 0x48, 0x83, 0xb4, 0xa1, 0xff, + 0x47, 0x48, 0x62, 0xb4, 0xa0, 0xff, 0xa3, 0x41, 0x01, 0xa4, 0xa3, 0x41, + 0x09, 0x80, 0xaa, 0xcf, 0x43, 0xf8, 0x88, 0x4c, 0x84, 0x30, 0xcc, 0xff, + 0x64, 0xb0, 0x06, 0x00, 0x87, 0x8d, 0x7f, 0xed, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x3c, 0x4c, 0x82, 0x00, 0x18, 0x11, 0xbf, 0x45, 0x00, 0x0c, + 0xb9, 0x41, 0x10, 0x80, 0x39, 0x33, 0x47, 0x22, 0x99, 0x45, 0xa0, 0x0c, + 0xed, 0x4f, 0x57, 0x45, 0x04, 0x0e, 0x44, 0x34, 0x24, 0x00, 0x84, 0x34, + 0x26, 0x00, 0x70, 0x34, 0x28, 0x00, 0xd4, 0x44, 0xd3, 0x44, 0x2f, 0x2d, + 0x02, 0x94, 0x9a, 0x00, 0xa5, 0x41, 0x09, 0x80, 0x50, 0x60, 0x34, 0x01, + 0x90, 0x14, 0x2e, 0x01, 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, 0x31, 0x11, + 0x83, 0x18, 0x34, 0x4d, 0xa3, 0x41, 0x09, 0x80, 0x43, 0xf8, 0x84, 0x4c, + 0x50, 0x60, 0x4d, 0x01, 0xa3, 0x41, 0x09, 0x80, 0x50, 0x60, 0x4a, 0x11, + 0x43, 0x18, 0x24, 0x4d, 0x50, 0x60, 0x49, 0x01, 0x50, 0x60, 0x46, 0x11, + 0x21, 0x2d, 0x05, 0x8d, 0x81, 0xed, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x18, + 0x35, 0x4d, 0x70, 0x14, 0x45, 0x01, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x18, + 0x1d, 0x4d, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x09, 0xf6, 0xe2, 0x45, + 0x90, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x90, 0x30, 0x2f, 0x01, 0x42, 0x30, + 0x47, 0x22, 0xe2, 0x45, 0xa0, 0x0c, 0x30, 0x16, 0x35, 0x01, 0x30, 0x17, + 0x36, 0x01, 0x10, 0x17, 0x37, 0x01, 0xa2, 0x41, 0x09, 0x80, 0xf0, 0x15, + 0x38, 0x01, 0x22, 0x1a, 0x74, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xd0, 0x15, + 0x39, 0x01, 0x22, 0x1b, 0x75, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xb0, 0x15, + 0x3a, 0x01, 0x02, 0x1b, 0x76, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x90, 0x15, + 0x3b, 0x01, 0xe2, 0x19, 0x77, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x70, 0x15, + 0x3c, 0x01, 0xc2, 0x19, 0x78, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x50, 0x15, + 0x3d, 0x01, 0xa2, 0x19, 0x79, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x30, 0x15, + 0x3e, 0x01, 0x82, 0x19, 0x7a, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x10, 0x15, + 0x3f, 0x01, 0x62, 0x19, 0x7b, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xf0, 0x14, + 0x40, 0x01, 0x42, 0x19, 0x7c, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xd0, 0x14, + 0x41, 0x01, 0x22, 0x19, 0x7d, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xb0, 0x14, + 0x42, 0x01, 0x02, 0x19, 0x7e, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x90, 0x14, + 0x43, 0x01, 0xe2, 0x18, 0x7f, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x70, 0x14, + 0x44, 0x01, 0xc2, 0x18, 0x80, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x18, + 0x81, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x18, 0x82, 0x4c, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0x18, 0x83, 0x4c, 0x40, 0x0c, 0x17, 0x45, 0x0a, 0x47, + 0xa2, 0x41, 0x04, 0x80, 0x09, 0x6e, 0x06, 0xef, 0x42, 0x30, 0x31, 0x26, + 0xc2, 0x45, 0xa5, 0x30, 0x50, 0x49, 0xa2, 0x41, 0x01, 0x80, 0x06, 0xef, + 0x89, 0x6e, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x90, 0x30, 0x24, 0x00, + 0x57, 0xcf, 0x50, 0x60, 0x34, 0x01, 0x00, 0x0c, 0x64, 0xfc, 0x40, 0x00, + 0x02, 0xed, 0x43, 0x94, 0x09, 0x00, 0x00, 0x0c, 0x83, 0xee, 0xa3, 0x94, + 0x02, 0x00, 0x40, 0x0c, 0xbf, 0x45, 0x9f, 0x45, 0x44, 0x14, 0x44, 0x00, + 0x9f, 0x45, 0x44, 0xfc, 0x44, 0x00, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, + 0x05, 0x80, 0xdd, 0x22, 0x14, 0xd0, 0x04, 0x32, 0x70, 0x00, 0x90, 0x0c, + 0x42, 0x30, 0x41, 0x5e, 0xe2, 0x45, 0xa5, 0x0e, 0x02, 0xb4, 0x4d, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xbd, 0x48, 0xe2, 0x45, 0x90, 0x0c, + 0x82, 0xfc, 0x40, 0x00, 0x82, 0xed, 0x64, 0x94, 0x58, 0x00, 0x83, 0xee, + 0xa4, 0x94, 0x63, 0x00, 0x60, 0x0c, 0x55, 0xfc, 0x40, 0x00, 0x02, 0xee, + 0x82, 0x94, 0x57, 0x00, 0x03, 0xee, 0x82, 0x94, 0x57, 0x00, 0x20, 0x0e, + 0x23, 0x02, 0x50, 0x1b, 0xbd, 0x8d, 0xb2, 0x41, 0x05, 0x80, 0x52, 0x32, + 0x59, 0x5e, 0xf2, 0x45, 0x90, 0x0c, 0x60, 0x32, 0x02, 0x00, 0x50, 0xb4, + 0x10, 0x00, 0x80, 0x32, 0x03, 0x00, 0x1f, 0xcc, 0x40, 0x0c, 0x84, 0x96, + 0x1f, 0x00, 0x00, 0x0c, 0x71, 0x00, 0x50, 0x1b, 0x91, 0x8d, 0x82, 0x0c, + 0xf2, 0x45, 0x00, 0x0c, 0x50, 0x94, 0x12, 0x00, 0x00, 0x0c, 0x82, 0xfc, + 0x40, 0x00, 0x64, 0xb6, 0xf0, 0xff, 0x60, 0x0c, 0x62, 0xfc, 0x44, 0x00, + 0x71, 0x00, 0x50, 0x1b, 0xf1, 0xad, 0x82, 0x0c, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0x71, 0x5e, 0xe2, 0x45, 0xb5, 0x0c, 0x40, 0x0c, 0xdd, 0x22, + 0x14, 0x50, 0x0c, 0x47, 0xe1, 0xcf, 0x62, 0x14, 0x44, 0x00, 0xa2, 0x41, + 0x05, 0x80, 0xb5, 0x0c, 0x42, 0x30, 0x7d, 0x5e, 0xe2, 0x45, 0x90, 0x0c, + 0x40, 0x0c, 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0xa2, 0x41, 0x05, 0x80, + 0xb5, 0x0c, 0x42, 0x30, 0x31, 0x5e, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, + 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0x62, 0xfc, 0x44, 0x00, 0x55, 0xfc, + 0x40, 0x00, 0x02, 0xee, 0x82, 0xb4, 0xab, 0xff, 0x03, 0xee, 0xac, 0xcf, + 0x35, 0xfe, 0x44, 0x00, 0xa9, 0xcf, 0x35, 0x16, 0x44, 0x00, 0x9d, 0xcf, + 0x62, 0x14, 0x44, 0x00, 0x3d, 0x4f, 0x3d, 0x23, 0x60, 0xd1, 0x44, 0xfe, + 0x34, 0x00, 0x47, 0x30, 0xdc, 0xff, 0x27, 0x0e, 0x5d, 0xf8, 0x50, 0x01, + 0x9d, 0x20, 0x88, 0x91, 0x12, 0x94, 0x58, 0x01, 0xdd, 0xf8, 0x90, 0x01, + 0x5d, 0xfc, 0x8c, 0x01, 0xa4, 0x41, 0x00, 0x1c, 0xa3, 0x41, 0x00, 0x04, + 0x27, 0x69, 0x94, 0x44, 0x62, 0x94, 0x1b, 0x01, 0xa3, 0x41, 0x00, 0xf8, + 0x34, 0x05, 0x42, 0xb0, 0x01, 0x00, 0x7d, 0xfc, 0x90, 0x01, 0xfd, 0xfc, + 0x98, 0x01, 0x44, 0xc8, 0x63, 0x30, 0x24, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0xa3, 0x0c, 0xd1, 0x30, 0xdc, 0xff, 0x92, 0x0c, 0x42, 0x30, 0x03, 0x12, + 0xc2, 0x45, 0x7d, 0xf8, 0x54, 0x01, 0x02, 0x0e, 0x52, 0xfc, 0x60, 0xff, + 0xa2, 0x6a, 0xe5, 0x40, 0x11, 0x00, 0x62, 0xfc, 0x7c, 0x00, 0x03, 0x96, + 0x11, 0x00, 0x42, 0x30, 0x80, 0x00, 0x06, 0xcc, 0x60, 0x0c, 0x82, 0xfc, + 0xfc, 0xff, 0x90, 0x94, 0x09, 0x00, 0x00, 0x0c, 0xb0, 0x6d, 0x65, 0xb4, + 0xf8, 0xff, 0x22, 0x6d, 0x3d, 0x23, 0x60, 0x51, 0x9f, 0x45, 0xc5, 0x4c, + 0x31, 0xb2, 0x24, 0x00, 0xf9, 0xac, 0xd2, 0x32, 0x50, 0xff, 0xb3, 0x41, + 0x05, 0x80, 0x73, 0x32, 0x59, 0x5e, 0xf3, 0x45, 0x96, 0x0c, 0xc2, 0x0f, + 0x5d, 0xfc, 0x90, 0x01, 0xd6, 0x97, 0xdb, 0x00, 0x82, 0x32, 0x10, 0x00, + 0xb5, 0x41, 0x01, 0x80, 0xfe, 0x0e, 0x08, 0xcc, 0xb5, 0x32, 0xa1, 0xa4, + 0xf3, 0x45, 0x00, 0x0c, 0xc2, 0x0f, 0x56, 0x94, 0xce, 0x00, 0xe2, 0x0e, + 0x3e, 0x32, 0x29, 0x00, 0x94, 0x0c, 0x06, 0xef, 0xf5, 0x45, 0xb1, 0x0c, + 0x22, 0x0d, 0x72, 0xad, 0x9e, 0x0c, 0x60, 0x32, 0x01, 0x00, 0xb5, 0x41, + 0x01, 0x80, 0xf2, 0x86, 0x06, 0xef, 0xb5, 0x32, 0xbd, 0xa4, 0xd5, 0x45, + 0x3d, 0xf9, 0x58, 0x01, 0x60, 0x0c, 0x40, 0x0c, 0xbd, 0xfc, 0x50, 0x01, + 0x9d, 0xfc, 0x54, 0x01, 0x5d, 0x20, 0x10, 0x90, 0xa2, 0x41, 0x10, 0x80, + 0x95, 0x6f, 0xc0, 0x0c, 0x06, 0xc8, 0x87, 0xca, 0x42, 0x30, 0x7d, 0x1c, + 0xc2, 0x45, 0x3d, 0xfa, 0x20, 0x00, 0xdd, 0x14, 0x25, 0x01, 0xaf, 0x48, + 0xd5, 0x45, 0x97, 0x30, 0x09, 0x00, 0x5d, 0x14, 0x25, 0x01, 0x57, 0x18, + 0x08, 0x00, 0x00, 0x69, 0x57, 0x60, 0x32, 0x80, 0x57, 0x60, 0x2f, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe9, 0x16, 0xe2, 0x45, 0x01, 0x6a, + 0x57, 0x60, 0x36, 0x80, 0x62, 0xb0, 0x24, 0x00, 0x57, 0x60, 0x33, 0x90, + 0x03, 0xb4, 0xb3, 0x00, 0x3d, 0xfd, 0x58, 0x01, 0x01, 0xed, 0x57, 0x18, + 0x37, 0x00, 0x01, 0xed, 0x17, 0xf8, 0x38, 0x00, 0x7e, 0x48, 0x03, 0x94, + 0xfb, 0x00, 0x7f, 0x48, 0x42, 0x50, 0x20, 0x00, 0x57, 0x18, 0x37, 0x00, + 0x7e, 0x48, 0xb0, 0x09, 0xb4, 0x2d, 0x85, 0x8d, 0x7b, 0x48, 0x81, 0xed, + 0x77, 0x18, 0x48, 0x00, 0x7b, 0x48, 0x03, 0x94, 0xd6, 0x00, 0x7c, 0x48, + 0x42, 0x50, 0x10, 0x00, 0x57, 0x18, 0x37, 0x00, 0x79, 0x48, 0x03, 0x94, + 0xc7, 0x00, 0x7a, 0x48, 0x42, 0x50, 0x08, 0x00, 0x57, 0x18, 0x37, 0x00, + 0x7d, 0xfc, 0x90, 0x01, 0x63, 0x34, 0x20, 0x00, 0x77, 0x38, 0x3c, 0x00, + 0x7d, 0xfc, 0x90, 0x01, 0x63, 0x34, 0x22, 0x00, 0x77, 0x38, 0x3e, 0x00, + 0x84, 0xed, 0x62, 0x94, 0x87, 0x00, 0x81, 0xed, 0x62, 0x94, 0x84, 0x00, + 0x00, 0x0c, 0xb4, 0x48, 0x05, 0x94, 0x8f, 0x00, 0xdd, 0x14, 0x29, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0x97, 0x0c, 0x42, 0x30, 0x09, 0x21, 0xc2, 0x45, + 0x3d, 0xf9, 0x58, 0x01, 0x3d, 0xfd, 0x58, 0x01, 0x5d, 0xfc, 0x14, 0x01, + 0x03, 0x8d, 0x05, 0xed, 0x57, 0xf8, 0x38, 0x00, 0xb3, 0x40, 0x48, 0xff, + 0x52, 0xfc, 0x3c, 0x00, 0x81, 0xed, 0x62, 0x94, 0x8d, 0x00, 0x82, 0xed, + 0x62, 0xb4, 0x07, 0x00, 0x4e, 0x48, 0x03, 0xed, 0x57, 0xf8, 0x40, 0x00, + 0x37, 0x19, 0x44, 0x00, 0x4e, 0x48, 0x1a, 0x8d, 0x52, 0x32, 0xe0, 0xfe, + 0x22, 0x09, 0x2c, 0x2d, 0x17, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x5d, 0xfc, + 0x20, 0x01, 0x10, 0x8d, 0x15, 0x6d, 0xfd, 0xfc, 0x50, 0x01, 0xdd, 0xfc, + 0x54, 0x01, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xb7, 0x0c, 0x92, 0x0c, + 0x85, 0xca, 0x42, 0x30, 0xb9, 0x25, 0xc2, 0x45, 0x3d, 0xfa, 0x18, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0xb7, 0x0c, 0x42, 0x30, 0xf1, 0xd7, 0xe2, 0x45, + 0x92, 0x0c, 0x3d, 0x23, 0x60, 0x51, 0x9f, 0x45, 0xc5, 0x4c, 0xe9, 0xce, + 0x02, 0xed, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, 0xd0, 0x00, 0x42, 0x30, + 0x51, 0x1e, 0xe2, 0x45, 0x4c, 0xee, 0xe2, 0x0e, 0x5d, 0xfc, 0x8c, 0x01, + 0x26, 0x69, 0x42, 0xd0, 0x00, 0x01, 0x02, 0xb4, 0x48, 0x00, 0x37, 0x32, + 0x29, 0x00, 0x5d, 0xfc, 0x88, 0x01, 0x62, 0xfe, 0x40, 0x00, 0x73, 0x02, + 0x2c, 0x01, 0x13, 0xb4, 0x53, 0x00, 0x5d, 0xfc, 0x8c, 0x01, 0x5d, 0xfc, + 0x88, 0x01, 0x22, 0xfd, 0x40, 0x00, 0x29, 0x01, 0xec, 0x00, 0x09, 0xb4, + 0x5e, 0x00, 0x5d, 0xfc, 0x8c, 0x01, 0x37, 0x32, 0x29, 0x00, 0x15, 0xcf, + 0x69, 0x0e, 0x04, 0xed, 0x57, 0x18, 0x37, 0x00, 0x4f, 0xcf, 0x04, 0xed, + 0x5c, 0xfc, 0xe4, 0x81, 0x20, 0x6d, 0xa6, 0xce, 0x5c, 0xf8, 0xe4, 0x81, + 0x57, 0x34, 0x3e, 0x00, 0x28, 0x2d, 0x02, 0x94, 0x79, 0xff, 0xb4, 0x48, + 0x59, 0x48, 0x03, 0x8d, 0x5a, 0x48, 0xa2, 0x40, 0x73, 0xff, 0x01, 0xed, + 0x70, 0xcf, 0x57, 0xf8, 0x38, 0x00, 0x5d, 0xfc, 0x18, 0x01, 0x02, 0x94, + 0x79, 0xff, 0x02, 0xed, 0x57, 0xf8, 0x38, 0x00, 0x7d, 0xfc, 0x18, 0x01, + 0x01, 0xed, 0x63, 0x14, 0x19, 0x00, 0x43, 0xb4, 0x71, 0xff, 0x5d, 0xfc, + 0x14, 0x01, 0x06, 0xed, 0x6b, 0xcf, 0x57, 0xf8, 0x38, 0x00, 0x60, 0x0e, + 0xe4, 0xce, 0x20, 0x0d, 0x02, 0xed, 0x57, 0xf8, 0x40, 0x00, 0x78, 0xcf, + 0x37, 0xf9, 0x44, 0x00, 0x03, 0xb4, 0x38, 0xff, 0x7d, 0xfc, 0x90, 0x01, + 0x3d, 0xcf, 0x63, 0x34, 0x20, 0x00, 0x03, 0xb4, 0x29, 0xff, 0x79, 0x48, + 0x2c, 0xcf, 0x00, 0x0c, 0x37, 0x32, 0x29, 0x00, 0x60, 0x0e, 0x42, 0x1c, + 0x26, 0x00, 0x22, 0x01, 0x00, 0x08, 0x49, 0x00, 0x50, 0x49, 0x29, 0x01, + 0x00, 0x18, 0x49, 0x00, 0x50, 0x49, 0xc3, 0xce, 0x29, 0x01, 0x00, 0x10, + 0x03, 0xb4, 0x04, 0xff, 0x7b, 0x48, 0x0f, 0xcf, 0x00, 0x0c, 0x37, 0x32, + 0x29, 0x00, 0x62, 0x1c, 0x26, 0x00, 0x5d, 0xfc, 0x88, 0x01, 0x22, 0x1d, + 0x64, 0x00, 0x32, 0x25, 0x34, 0x05, 0x26, 0x25, 0x34, 0x05, 0x24, 0x25, + 0x22, 0x01, 0x3c, 0xab, 0x09, 0x00, 0x3c, 0x70, 0xaa, 0xce, 0x49, 0x46, + 0xed, 0x4f, 0x75, 0x45, 0x44, 0xfc, 0x58, 0x02, 0x21, 0x2d, 0x24, 0xad, + 0x64, 0x30, 0x20, 0x01, 0x05, 0x32, 0x02, 0x00, 0xa2, 0x41, 0x02, 0x80, + 0x24, 0x0e, 0xc6, 0x86, 0x42, 0x30, 0x69, 0xc1, 0xe2, 0x45, 0x01, 0xef, + 0x14, 0xad, 0x42, 0x0e, 0xb3, 0x41, 0x01, 0x80, 0xb0, 0x0c, 0x91, 0x30, + 0xd4, 0x00, 0x73, 0x32, 0xbd, 0xa4, 0xf3, 0x45, 0x06, 0xef, 0xb0, 0x0c, + 0x91, 0x30, 0x96, 0x00, 0xf3, 0x45, 0x06, 0xef, 0x06, 0xef, 0xb0, 0x0c, + 0xd3, 0x45, 0x91, 0x30, 0x68, 0x08, 0x52, 0x0c, 0x35, 0x45, 0x0a, 0x47, + 0xfc, 0xcf, 0x40, 0x32, 0xf0, 0xff, 0x00, 0x0c, 0xc9, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0xfb, 0xcb, 0x09, 0x6e, 0x58, 0xef, 0x42, 0x30, 0x51, 0xa8, + 0xe2, 0x45, 0xa0, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x62, 0xfc, 0x8c, 0x4c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x90, 0x4c, 0xa5, 0x41, 0x09, 0x80, + 0x3c, 0xef, 0x4a, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0xa5, 0x30, 0x94, 0x4c, + 0x17, 0x6e, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x7d, 0xf8, 0x24, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x20, 0xef, 0xd8, 0xee, 0x42, 0x30, 0xf5, 0x22, + 0xe2, 0x45, 0x09, 0x6e, 0xfb, 0x4b, 0x1c, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xd8, 0x9b, 0x02, 0x94, 0x9a, 0x00, 0x7c, 0xfc, 0xd4, 0x81, + 0x39, 0x4f, 0x7d, 0x22, 0x80, 0xd1, 0x42, 0xfe, 0x04, 0x00, 0xa2, 0x41, + 0x01, 0x80, 0x24, 0x0e, 0x05, 0x0e, 0xc0, 0x30, 0x6c, 0x01, 0xa0, 0x0c, + 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, 0x09, 0x6e, 0x11, 0x94, 0x72, 0x00, + 0x29, 0xca, 0xb0, 0x41, 0x01, 0x80, 0x10, 0x32, 0xbd, 0xa4, 0xa2, 0x41, + 0x09, 0x80, 0x22, 0xfd, 0x58, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0x02, 0xfd, + 0x5c, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0xe2, 0xfc, 0x60, 0x9a, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0xfc, 0x64, 0x9a, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, + 0x54, 0x9a, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, 0x74, 0x9a, + 0x9d, 0x30, 0x0c, 0x01, 0x7d, 0xf8, 0x08, 0x01, 0x3d, 0xf9, 0xfc, 0x00, + 0x1d, 0xf9, 0x00, 0x01, 0xfd, 0xf8, 0x04, 0x01, 0xd0, 0x45, 0x5d, 0xf8, + 0xf8, 0x00, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, 0xa5, 0x30, 0x78, 0x9a, + 0xd0, 0x45, 0x9d, 0x30, 0x10, 0x01, 0xa5, 0x41, 0x09, 0x80, 0x04, 0xef, + 0xa5, 0x30, 0x7c, 0x9a, 0xd0, 0x45, 0x9d, 0x30, 0x14, 0x01, 0xa5, 0x41, + 0x09, 0x80, 0xb2, 0x41, 0x09, 0x80, 0x24, 0xef, 0xa5, 0x30, 0x80, 0x9a, + 0xd0, 0x45, 0x9d, 0x30, 0x18, 0x01, 0xb2, 0x30, 0x5c, 0xbf, 0x9d, 0x30, + 0x3c, 0x01, 0x3c, 0xef, 0xd0, 0x45, 0x52, 0x32, 0x5c, 0xbf, 0x72, 0xfc, + 0x3c, 0x00, 0xa2, 0x41, 0xfa, 0x50, 0x42, 0x30, 0xfa, 0x50, 0x01, 0xee, + 0x53, 0x44, 0x43, 0x00, 0x18, 0x20, 0x8f, 0x8c, 0x9d, 0xf8, 0x78, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0xc0, 0x0c, 0xa0, 0x30, 0x6c, 0x01, 0x42, 0x30, + 0xf5, 0x22, 0xe2, 0x45, 0x09, 0x6e, 0x7d, 0x22, 0x80, 0x51, 0x9f, 0x45, + 0xc9, 0x4c, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xe9, 0xdc, 0xe2, 0x45, + 0x00, 0x0c, 0x42, 0x40, 0xeb, 0xff, 0x7f, 0xed, 0xf2, 0xcf, 0x00, 0x0c, + 0xb2, 0xfc, 0x0c, 0x0b, 0x1d, 0xfa, 0xf0, 0x00, 0xb0, 0x41, 0x01, 0x80, + 0x45, 0xfc, 0xe0, 0x00, 0xc0, 0x30, 0xc8, 0x00, 0x15, 0x6e, 0x10, 0x32, + 0xbd, 0xa4, 0xdc, 0x6e, 0xd0, 0x45, 0x5d, 0xf8, 0xf4, 0x00, 0x83, 0xcf, + 0xa2, 0x41, 0x09, 0x80, 0x7f, 0xed, 0xb0, 0x6d, 0x9f, 0x45, 0x7c, 0xf8, + 0xd4, 0x81, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xed, 0x0f, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0xa3, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc8, 0x9e, 0x63, 0x30, 0x78, 0xa4, + 0x28, 0xee, 0x20, 0xea, 0x42, 0x30, 0x34, 0x00, 0x62, 0xb4, 0xfb, 0xff, + 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0xa3, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xf0, 0x9b, 0x63, 0x30, 0xc8, 0x9e, 0x28, 0xee, 0x20, 0xea, 0x42, 0x30, + 0x34, 0x00, 0x43, 0xb4, 0xfb, 0xff, 0xe5, 0x4b, 0x06, 0x47, 0x00, 0x0c, + 0xe9, 0x4f, 0xdd, 0x22, 0x14, 0xd0, 0xb2, 0x41, 0x09, 0x80, 0x52, 0xfc, + 0x24, 0x9b, 0xb0, 0x41, 0x09, 0x80, 0x10, 0x32, 0x60, 0x4d, 0x84, 0x0e, + 0xa5, 0x0e, 0x02, 0x96, 0x2e, 0x00, 0xa4, 0x41, 0x13, 0x80, 0xa3, 0x41, + 0x06, 0x80, 0x63, 0x30, 0x2c, 0xae, 0x62, 0x94, 0x2a, 0x00, 0x04, 0xf8, + 0x8c, 0x1e, 0x02, 0x02, 0x10, 0x1b, 0x60, 0x00, 0x58, 0x10, 0xb1, 0x41, + 0x03, 0x80, 0x82, 0x0c, 0x31, 0x32, 0x2d, 0x33, 0xd1, 0x45, 0xb3, 0x41, + 0x13, 0x80, 0xd1, 0x45, 0x93, 0xfc, 0x8c, 0x1e, 0x13, 0xfa, 0x8c, 0x1e, + 0xb2, 0xfa, 0x24, 0x9b, 0x14, 0xb4, 0x05, 0x00, 0xb9, 0x41, 0x10, 0x80, + 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0xa4, 0x41, 0x13, 0x80, 0x84, 0x30, + 0xfc, 0x5f, 0x39, 0x33, 0x23, 0x22, 0xdd, 0x22, 0x14, 0x50, 0x99, 0x45, + 0x19, 0x4c, 0x40, 0x0c, 0xde, 0xcf, 0x04, 0xf8, 0x8c, 0x1e, 0xdb, 0xcf, + 0x40, 0x0c, 0x00, 0x0c, 0xed, 0x4f, 0x30, 0xed, 0xd5, 0xed, 0x5d, 0x18, + 0x10, 0x00, 0x5d, 0x18, 0x11, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x7d, 0x18, + 0x14, 0x00, 0x42, 0x30, 0x8d, 0x36, 0xd3, 0xed, 0x66, 0x45, 0xc2, 0x45, + 0x7d, 0x18, 0x15, 0x00, 0xb1, 0x41, 0x01, 0x80, 0x42, 0x32, 0x09, 0x00, + 0x31, 0x32, 0xa1, 0xa4, 0x02, 0xef, 0x8b, 0x6e, 0x92, 0x0c, 0xf1, 0x45, + 0x02, 0x0e, 0x07, 0xad, 0x02, 0xef, 0xa2, 0x41, 0x59, 0x00, 0x42, 0x30, + 0xf8, 0x08, 0x50, 0xf8, 0xf0, 0x01, 0x89, 0x6e, 0xf1, 0x45, 0x92, 0x0c, + 0x18, 0xad, 0xa2, 0x41, 0x59, 0x00, 0x62, 0x30, 0xf8, 0x08, 0x42, 0x50, + 0x58, 0xf3, 0x50, 0xf8, 0xb4, 0x02, 0x40, 0x50, 0x40, 0x9c, 0x50, 0xf8, + 0xb8, 0x02, 0x40, 0x30, 0x8c, 0x0a, 0x50, 0xf8, 0xc0, 0x02, 0x40, 0x30, + 0x88, 0x08, 0x70, 0xf8, 0xb0, 0x02, 0x10, 0xf8, 0xbc, 0x02, 0x50, 0xf8, + 0x04, 0x03, 0x50, 0x0c, 0x26, 0x45, 0x0a, 0x47, 0xf5, 0x4f, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x69, 0xcb, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xa3, 0x41, 0x09, 0x80, 0x83, 0xfc, 0x84, 0x4c, 0x81, 0xed, 0x64, 0xb4, + 0x08, 0x00, 0xe5, 0x4b, 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, 0xac, 0x9b, + 0x03, 0xf8, 0xec, 0x00, 0xe5, 0x4b, 0x06, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0xfc, 0xd8, 0x9b, 0x02, 0x94, 0xca, 0x01, 0x7c, 0xfc, 0xd4, 0x81, + 0xd5, 0x4f, 0x3d, 0x23, 0x30, 0xd0, 0xb1, 0x41, 0x10, 0x80, 0x65, 0x0e, + 0x04, 0x0e, 0xa0, 0x30, 0xd0, 0x00, 0x80, 0x30, 0x84, 0x01, 0x31, 0x32, + 0x4b, 0x1e, 0xd1, 0x45, 0x42, 0xfe, 0x04, 0x00, 0x02, 0x94, 0xbb, 0x01, + 0xc2, 0x0f, 0x93, 0xfc, 0x08, 0x00, 0xa0, 0x30, 0xd0, 0x00, 0xf1, 0x45, + 0x4c, 0x6e, 0x02, 0x94, 0xb5, 0x01, 0x4a, 0xc8, 0xa2, 0x41, 0x01, 0x80, + 0xa0, 0x0c, 0x9e, 0x0c, 0x42, 0x30, 0x51, 0xa8, 0xc2, 0x45, 0xc0, 0x30, + 0x84, 0x01, 0x1e, 0x62, 0x1b, 0x80, 0x1e, 0x62, 0x18, 0x90, 0x53, 0xfc, + 0x04, 0x00, 0xa3, 0x41, 0x09, 0x80, 0xa3, 0x34, 0xe2, 0x4c, 0x5e, 0x60, + 0x29, 0x80, 0x5e, 0x60, 0x26, 0x90, 0x53, 0xfc, 0x00, 0x00, 0x68, 0xc8, + 0x5e, 0x60, 0x23, 0x80, 0x5e, 0x60, 0x20, 0x90, 0x92, 0xfc, 0x0c, 0x0b, + 0x84, 0xfc, 0x60, 0x01, 0x9e, 0x60, 0x1f, 0x80, 0x05, 0x94, 0x6b, 0x01, + 0x9e, 0x60, 0x1c, 0x90, 0x01, 0xee, 0xb2, 0xee, 0xbe, 0x18, 0x24, 0x00, + 0x1e, 0x18, 0x25, 0x00, 0x9e, 0x60, 0x17, 0x80, 0x9e, 0x60, 0x14, 0x90, + 0x02, 0x94, 0xc0, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x44, 0xc8, 0xa2, 0x41, + 0x09, 0x80, 0x45, 0xc8, 0xa2, 0x41, 0x09, 0x80, 0x46, 0xc8, 0xa2, 0x41, + 0x09, 0x80, 0xb2, 0x41, 0x10, 0x80, 0xb1, 0x41, 0x09, 0x80, 0x47, 0xc8, + 0xa2, 0x41, 0x09, 0x80, 0x80, 0x0e, 0x52, 0x32, 0xe9, 0x16, 0x31, 0x32, + 0x7d, 0xc2, 0xb7, 0x41, 0x09, 0x80, 0x2c, 0xcc, 0x49, 0xc8, 0x50, 0x14, + 0xa6, 0x01, 0x42, 0xd0, 0x0a, 0x00, 0x02, 0xb4, 0x72, 0x00, 0x68, 0x48, + 0x49, 0x48, 0xc2, 0x34, 0xe0, 0x4c, 0x01, 0xed, 0x44, 0x60, 0x7b, 0x80, + 0x06, 0x94, 0x2d, 0x01, 0x44, 0x60, 0x78, 0x90, 0x61, 0x25, 0xc4, 0x18, + 0x7d, 0x00, 0x44, 0x18, 0x7e, 0x00, 0x5e, 0x60, 0x17, 0x00, 0x01, 0xee, + 0x5e, 0x60, 0x14, 0x10, 0x82, 0x94, 0x75, 0x00, 0x95, 0x02, 0x50, 0x41, + 0x5e, 0x60, 0x23, 0x00, 0xb4, 0x30, 0x01, 0x00, 0x85, 0xd2, 0xff, 0x00, + 0x5e, 0x60, 0x20, 0x10, 0x54, 0x00, 0x90, 0x13, 0xe2, 0x40, 0x7a, 0x00, + 0xd4, 0x00, 0x00, 0x08, 0xd3, 0x00, 0x50, 0xb1, 0x96, 0x34, 0x10, 0x01, + 0xb4, 0x02, 0x00, 0x18, 0xd2, 0x45, 0x93, 0x02, 0x50, 0x81, 0x95, 0x02, + 0x50, 0x21, 0x9e, 0x00, 0x50, 0x21, 0x44, 0x18, 0x76, 0x00, 0x50, 0x14, + 0x74, 0x01, 0x64, 0x48, 0x44, 0x18, 0x77, 0x00, 0x96, 0x34, 0x10, 0x01, + 0x45, 0x48, 0x43, 0x15, 0x74, 0x4c, 0x84, 0x31, 0x94, 0xf6, 0x22, 0x15, + 0x75, 0x4c, 0x46, 0x48, 0x8c, 0xb1, 0x49, 0x00, 0xc4, 0x30, 0xd8, 0xeb, + 0x67, 0x48, 0x80, 0x01, 0x58, 0x50, 0x42, 0x14, 0x76, 0x4c, 0x8a, 0x0d, + 0xc6, 0xb0, 0xb5, 0x00, 0xc9, 0x00, 0x18, 0x60, 0xc4, 0x30, 0x98, 0xea, + 0xc6, 0xb0, 0xf1, 0x00, 0x23, 0x15, 0x77, 0x4c, 0xc2, 0x00, 0x18, 0x60, + 0x44, 0x30, 0x8f, 0xe9, 0x42, 0xb0, 0x8d, 0x00, 0xd1, 0x45, 0x49, 0x00, + 0x18, 0x60, 0x95, 0x02, 0x50, 0x21, 0x9e, 0x00, 0x50, 0x21, 0xc4, 0x14, + 0x77, 0x00, 0x37, 0x15, 0xe4, 0x4c, 0x4c, 0x00, 0x50, 0x11, 0x2d, 0x05, + 0x09, 0x94, 0x8b, 0xff, 0x44, 0x18, 0x77, 0x00, 0x68, 0x48, 0x95, 0x02, + 0x50, 0x11, 0x5e, 0x00, 0x50, 0x11, 0x83, 0x34, 0xe2, 0x4c, 0x02, 0x60, + 0x7b, 0x80, 0x04, 0x94, 0xb3, 0x00, 0x02, 0x60, 0x78, 0x90, 0x41, 0x27, + 0x82, 0x18, 0x7d, 0x00, 0xc2, 0x18, 0x7e, 0x00, 0x5e, 0x60, 0x17, 0x00, + 0x01, 0xee, 0x5e, 0x60, 0x14, 0x10, 0x82, 0xb4, 0x8f, 0xff, 0x95, 0x02, + 0x50, 0x41, 0x02, 0xed, 0x1e, 0x01, 0x50, 0x41, 0x48, 0x18, 0x7c, 0x00, + 0x5e, 0x60, 0x23, 0x00, 0xb4, 0x30, 0x01, 0x00, 0x85, 0xd2, 0xff, 0x00, + 0x5e, 0x60, 0x20, 0x10, 0x54, 0x00, 0x90, 0x13, 0x02, 0xb4, 0x8a, 0xff, + 0xd4, 0x00, 0x00, 0x08, 0x53, 0xfc, 0x0c, 0x01, 0x6a, 0x48, 0x5e, 0x60, + 0x2d, 0x80, 0x5e, 0x60, 0x2a, 0x90, 0x53, 0xfc, 0x08, 0x00, 0x43, 0x60, + 0x17, 0x80, 0x43, 0x60, 0x14, 0x90, 0xd3, 0xfc, 0x08, 0x00, 0x06, 0xb4, + 0x95, 0x00, 0x4a, 0x48, 0x53, 0xfc, 0x04, 0x00, 0x82, 0x40, 0x9d, 0x00, + 0x00, 0x0c, 0x5e, 0x60, 0x29, 0x00, 0x5e, 0x60, 0x26, 0x10, 0x3f, 0x8d, + 0x00, 0x0e, 0xb1, 0x41, 0x01, 0x80, 0x0c, 0xcc, 0x31, 0x32, 0xbd, 0xa4, + 0x9e, 0x60, 0x29, 0x00, 0x00, 0x6c, 0x0d, 0x2c, 0x9e, 0x60, 0x26, 0x10, + 0x90, 0x00, 0x90, 0x13, 0xe2, 0x40, 0x25, 0x00, 0x8a, 0x26, 0x8a, 0x06, + 0xb3, 0x00, 0x50, 0x41, 0x06, 0x26, 0xc8, 0x14, 0xf8, 0x01, 0x08, 0x06, + 0x44, 0x26, 0x9e, 0x00, 0x50, 0x11, 0xc2, 0x60, 0x31, 0x80, 0x68, 0x8f, + 0xc2, 0x60, 0x2e, 0x90, 0xc8, 0x14, 0xf8, 0x01, 0xa5, 0x30, 0xd8, 0x01, + 0x84, 0x30, 0x32, 0x00, 0x9e, 0x00, 0x50, 0x21, 0xd1, 0x45, 0xb3, 0x00, + 0x50, 0x29, 0x9e, 0x60, 0x29, 0x00, 0x00, 0x6c, 0x0d, 0x2c, 0x9e, 0x60, + 0x26, 0x10, 0x90, 0x00, 0x90, 0x13, 0x5d, 0xad, 0x8a, 0x26, 0xe4, 0x40, + 0x08, 0x00, 0x40, 0x0c, 0x20, 0x6d, 0x2d, 0x2d, 0x82, 0x00, 0x90, 0x2b, + 0xfc, 0xae, 0x20, 0x6d, 0x2e, 0x6d, 0xbe, 0x60, 0x23, 0x00, 0xbe, 0x60, + 0x20, 0x10, 0x87, 0x8e, 0x40, 0x0c, 0x20, 0x6d, 0x2d, 0x2d, 0xa2, 0x00, + 0x90, 0x23, 0x7c, 0xae, 0x20, 0x6d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xc4, 0xbe, 0xa2, 0x60, 0x27, 0x00, 0x2a, 0x4a, 0xb0, 0x41, 0x10, 0x80, + 0xa2, 0x60, 0x24, 0x10, 0x10, 0x32, 0xf5, 0x22, 0x17, 0xef, 0xd0, 0x6e, + 0xa2, 0x60, 0x27, 0x80, 0xa2, 0x60, 0x24, 0x90, 0xb3, 0xfc, 0x08, 0x00, + 0x91, 0x0c, 0xf0, 0x45, 0xdc, 0x6e, 0x01, 0xef, 0xa0, 0x30, 0x84, 0x01, + 0xf0, 0x45, 0x9e, 0x0c, 0xb0, 0x41, 0x10, 0x80, 0x10, 0x32, 0x3f, 0x1e, + 0xf0, 0x45, 0x9e, 0x0c, 0xf0, 0x45, 0x91, 0x0c, 0x40, 0x0c, 0x3d, 0x23, + 0x30, 0x50, 0x16, 0x47, 0x80, 0x30, 0x82, 0xff, 0x82, 0x18, 0x7d, 0x00, + 0xdc, 0xce, 0x02, 0x18, 0x7e, 0x00, 0x32, 0xed, 0x44, 0x18, 0x7d, 0x00, + 0xd6, 0xce, 0x04, 0x18, 0x7e, 0x00, 0xa4, 0x41, 0x09, 0x80, 0x84, 0x34, + 0xe0, 0x4c, 0x04, 0x94, 0x9b, 0xfe, 0x01, 0xee, 0x91, 0xce, 0xb2, 0xee, + 0x2c, 0x6e, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0xb3, 0x30, 0x0c, 0x00, 0x53, 0xfc, 0x04, 0x00, 0xc2, 0x40, 0x65, 0xff, + 0x00, 0x0c, 0x9e, 0x60, 0x29, 0x00, 0x9b, 0xcf, 0x9e, 0x60, 0x26, 0x10, + 0x7f, 0xed, 0xb0, 0x6d, 0x9f, 0x45, 0x7c, 0xf8, 0xd4, 0x81, 0xcf, 0xcf, + 0x40, 0x30, 0xf4, 0xff, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3f, 0x1e, + 0xe2, 0x45, 0x9e, 0x0c, 0xc6, 0xcf, 0x40, 0x30, 0xf4, 0xff, 0x00, 0x0c, + 0x0b, 0x8e, 0xb9, 0x41, 0x01, 0x80, 0x64, 0x30, 0xe0, 0xfe, 0xa2, 0x41, + 0x09, 0x80, 0x39, 0x33, 0xe9, 0x7e, 0x99, 0x45, 0x62, 0xf8, 0x58, 0xbf, + 0x5c, 0xfc, 0xe4, 0x81, 0x64, 0x30, 0xe0, 0xfe, 0x20, 0x6d, 0x5c, 0xf8, + 0xe4, 0x81, 0x39, 0x33, 0xe9, 0x7e, 0xa2, 0x41, 0x09, 0x80, 0x99, 0x45, + 0x62, 0xf8, 0x58, 0xbf, 0xa6, 0x41, 0x62, 0x10, 0xa2, 0x41, 0x09, 0x80, + 0x46, 0x31, 0xd3, 0x4d, 0xa6, 0x41, 0xeb, 0x51, 0x82, 0xfd, 0x24, 0x9b, + 0x84, 0x30, 0xec, 0x01, 0x81, 0xed, 0x40, 0x0c, 0x60, 0x0d, 0x84, 0xef, + 0x00, 0x31, 0x01, 0x00, 0xa0, 0x31, 0x0b, 0x00, 0x26, 0x51, 0x1f, 0x85, + 0x40, 0x6b, 0xe6, 0x40, 0x1b, 0x00, 0xed, 0x4f, 0x3d, 0x21, 0x04, 0xd0, + 0xe2, 0x40, 0x23, 0x00, 0x02, 0x95, 0xb4, 0x00, 0x00, 0x0c, 0xe3, 0x94, + 0x09, 0x00, 0x00, 0x0c, 0x42, 0x6e, 0x40, 0x6b, 0x20, 0x6d, 0x74, 0xaf, + 0xb0, 0x6d, 0xe3, 0xb4, 0xf9, 0xff, 0x00, 0x0c, 0x65, 0x61, 0x29, 0x80, + 0x40, 0x0c, 0x65, 0x61, 0x26, 0x90, 0x3d, 0x21, 0x04, 0x50, 0x0a, 0x47, + 0xe3, 0x94, 0x05, 0x00, 0x00, 0x0c, 0x20, 0x6d, 0x42, 0x6e, 0xdc, 0xcf, + 0xb0, 0x6d, 0x65, 0x61, 0x29, 0x80, 0x65, 0x61, 0x26, 0x90, 0x9f, 0x45, + 0x40, 0x0c, 0xc6, 0xfd, 0x0c, 0x00, 0x0e, 0x94, 0xdf, 0xff, 0xcb, 0x01, + 0x00, 0x08, 0x6e, 0x01, 0x50, 0x91, 0x52, 0x02, 0x00, 0x10, 0x72, 0x01, + 0xd0, 0x91, 0x52, 0x32, 0x32, 0x00, 0x45, 0x02, 0x50, 0x91, 0x60, 0x0e, + 0xa0, 0x0e, 0x06, 0xff, 0x00, 0x00, 0x6e, 0x01, 0x50, 0x79, 0xef, 0x01, + 0x00, 0x10, 0x78, 0x02, 0x50, 0x71, 0xce, 0xfd, 0x04, 0x00, 0x6f, 0x01, + 0xd0, 0x79, 0xe5, 0x01, 0x50, 0x79, 0xcf, 0x61, 0x2d, 0x80, 0xcf, 0x61, + 0x2a, 0x90, 0xc6, 0xfd, 0x00, 0x00, 0x6e, 0x02, 0x50, 0x71, 0x2e, 0xff, + 0x08, 0x00, 0x20, 0x03, 0xd0, 0x72, 0xce, 0xd1, 0x01, 0x00, 0x39, 0xd3, + 0x01, 0x00, 0x19, 0xb4, 0x52, 0x00, 0xd2, 0x19, 0x00, 0x00, 0xc6, 0xfd, + 0x00, 0x00, 0x0c, 0x16, 0x08, 0x00, 0x6e, 0x02, 0x50, 0x71, 0x2e, 0xfe, + 0x04, 0x00, 0x91, 0x32, 0xf6, 0xff, 0x10, 0x94, 0x44, 0x00, 0xd1, 0x32, + 0x0a, 0x00, 0x0c, 0x33, 0x10, 0x00, 0xd8, 0xfd, 0x00, 0x00, 0x4e, 0x01, + 0x3c, 0x9b, 0x0e, 0x46, 0xce, 0x01, 0x40, 0x30, 0x2e, 0x02, 0x90, 0xbb, + 0x17, 0x94, 0x2f, 0x00, 0x22, 0x4f, 0xf8, 0xfe, 0x04, 0x00, 0x57, 0x01, + 0x3c, 0x9b, 0x17, 0x46, 0xf7, 0x02, 0x40, 0x30, 0xf1, 0x02, 0x90, 0xf3, + 0x1e, 0x94, 0x23, 0x00, 0xd4, 0x01, 0x90, 0x73, 0x0e, 0xb4, 0x1f, 0x00, + 0xd7, 0x02, 0x90, 0xbb, 0x17, 0xb4, 0x1d, 0x00, 0x19, 0x02, 0x90, 0x73, + 0xd8, 0xfd, 0x10, 0x00, 0x2e, 0x01, 0x3c, 0x9b, 0x0e, 0x46, 0xce, 0x01, + 0x40, 0x28, 0xcf, 0x61, 0x31, 0x80, 0xcf, 0x61, 0x2e, 0x90, 0xd8, 0xfd, + 0x54, 0x00, 0xce, 0x01, 0xec, 0x01, 0xd2, 0x19, 0x01, 0x00, 0xd8, 0xfd, + 0x54, 0x00, 0xce, 0x01, 0x2c, 0x01, 0xd2, 0x19, 0x02, 0x00, 0x0c, 0x16, + 0x08, 0x00, 0x19, 0x02, 0x90, 0x73, 0x0e, 0xb4, 0xc2, 0xff, 0x18, 0x33, + 0x60, 0x00, 0xc6, 0xfd, 0x0c, 0x00, 0xa2, 0x4e, 0x62, 0x4d, 0xd5, 0x01, + 0x90, 0x73, 0x73, 0x32, 0x34, 0x00, 0x0e, 0x94, 0x55, 0xff, 0x52, 0x32, + 0x0b, 0x00, 0x81, 0xcf, 0xcb, 0x01, 0x00, 0x08, 0xc6, 0xfd, 0x0c, 0x00, + 0x0e, 0x94, 0x4c, 0xff, 0xab, 0x01, 0x10, 0x72, 0x60, 0x0e, 0x80, 0x0e, + 0xae, 0x00, 0x50, 0x91, 0x52, 0x32, 0x32, 0x00, 0xe6, 0xfd, 0x00, 0x00, + 0xcb, 0x01, 0x00, 0x08, 0x6e, 0x01, 0x50, 0x71, 0x6f, 0x02, 0x50, 0x79, + 0xef, 0xfd, 0x04, 0x00, 0xce, 0x01, 0x00, 0x10, 0x6e, 0x01, 0xd0, 0x71, + 0xc5, 0x01, 0x50, 0x71, 0xee, 0x61, 0x2d, 0x80, 0xee, 0x61, 0x2a, 0x90, + 0xe6, 0xfd, 0x00, 0x00, 0x6f, 0x02, 0x50, 0x79, 0x2f, 0xff, 0x08, 0x00, + 0x20, 0x03, 0xd0, 0x7a, 0xef, 0xd1, 0x01, 0x00, 0x39, 0xd3, 0x01, 0x00, + 0x19, 0xb4, 0x52, 0x00, 0xf2, 0x19, 0x00, 0x00, 0xe6, 0xfd, 0x00, 0x00, + 0x0c, 0x16, 0x08, 0x00, 0x6f, 0x02, 0x50, 0x79, 0x2f, 0xfe, 0x04, 0x00, + 0xb1, 0x32, 0xf6, 0xff, 0x10, 0x94, 0x44, 0x00, 0xd1, 0x32, 0x0a, 0x00, + 0x0c, 0x33, 0x10, 0x00, 0xf8, 0xfd, 0x00, 0x00, 0x4f, 0x01, 0x3c, 0x9b, + 0x0f, 0x46, 0xef, 0x01, 0x40, 0x30, 0x2f, 0x02, 0x90, 0xbb, 0x17, 0x94, + 0x2f, 0x00, 0x22, 0x4f, 0xf8, 0xfe, 0x04, 0x00, 0x57, 0x01, 0x3c, 0x9b, + 0x17, 0x46, 0xf7, 0x02, 0x40, 0x30, 0xf1, 0x02, 0x90, 0xf3, 0x1e, 0x94, + 0x23, 0x00, 0xf5, 0x01, 0x90, 0x7b, 0x0f, 0xb4, 0x1f, 0x00, 0xd7, 0x02, + 0x90, 0xbb, 0x17, 0xb4, 0x1d, 0x00, 0x19, 0x02, 0x90, 0x7b, 0xf8, 0xfd, + 0x10, 0x00, 0x2f, 0x01, 0x3c, 0x9b, 0x0f, 0x46, 0xef, 0x01, 0x40, 0x28, + 0xee, 0x61, 0x31, 0x80, 0xee, 0x61, 0x2e, 0x90, 0xf8, 0xfd, 0x54, 0x00, + 0xef, 0x01, 0xec, 0x01, 0xf2, 0x19, 0x01, 0x00, 0xf8, 0xfd, 0x54, 0x00, + 0xef, 0x01, 0x2c, 0x01, 0xf2, 0x19, 0x02, 0x00, 0x0c, 0x16, 0x08, 0x00, + 0x19, 0x02, 0x90, 0x7b, 0x0f, 0xb4, 0xc2, 0xff, 0x18, 0x33, 0x60, 0x00, + 0xc6, 0xfd, 0x0c, 0x00, 0x82, 0x4e, 0x62, 0x4d, 0xd4, 0x01, 0x90, 0x73, + 0x73, 0x32, 0x34, 0x00, 0x0e, 0xb4, 0x82, 0xff, 0x52, 0x32, 0x0b, 0x00, + 0xc4, 0xce, 0x42, 0x6e, 0xed, 0x4f, 0x66, 0x45, 0x44, 0x20, 0xec, 0x11, + 0xa5, 0x41, 0x09, 0x80, 0x25, 0xfe, 0x24, 0x9b, 0x23, 0x69, 0xb3, 0x69, + 0xb4, 0x05, 0x32, 0x25, 0x34, 0x05, 0x24, 0x25, 0x35, 0x05, 0x42, 0x30, + 0x2a, 0x00, 0xb7, 0x8c, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x44, 0x0e, + 0x89, 0x6e, 0x42, 0x30, 0xb7, 0x24, 0xe2, 0x45, 0x02, 0xee, 0x30, 0x8d, + 0x02, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x55, 0x14, 0xe2, 0x45, + 0x1f, 0xee, 0x50, 0x60, 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0x10, 0x60, + 0x03, 0x80, 0x10, 0x60, 0x00, 0x90, 0x10, 0x60, 0x07, 0x80, 0xa2, 0x41, + 0x01, 0x80, 0xb1, 0x30, 0x09, 0x00, 0x90, 0x30, 0x24, 0x00, 0x42, 0x30, + 0x55, 0xab, 0xc2, 0x45, 0x10, 0x60, 0x04, 0x90, 0xa2, 0x41, 0x09, 0x80, + 0xca, 0x86, 0x42, 0x30, 0x11, 0xe4, 0xe2, 0x45, 0x00, 0x0c, 0xa4, 0x48, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, 0xe2, 0x45, 0x90, 0x0c, + 0x40, 0x0c, 0x26, 0x45, 0x0a, 0x47, 0xfd, 0xcf, 0x40, 0x30, 0xea, 0xff, + 0xfa, 0xcf, 0x40, 0x30, 0x97, 0xff, 0x00, 0x0c, 0xe1, 0x4f, 0x1d, 0x23, + 0x1c, 0xd0, 0x45, 0x14, 0x13, 0x05, 0x65, 0x14, 0x12, 0x05, 0x44, 0xfe, + 0x50, 0x02, 0x20, 0x25, 0xd3, 0x44, 0x82, 0x30, 0x2c, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0x05, 0x0e, 0xff, 0xef, 0xa0, 0xee, 0x66, 0x0e, 0x42, 0x30, + 0x11, 0xb0, 0xe2, 0x45, 0xc0, 0x0c, 0xb4, 0x41, 0x10, 0x80, 0x82, 0x0c, + 0x98, 0xee, 0x94, 0x32, 0xb5, 0x23, 0xf4, 0x45, 0x22, 0x0e, 0x84, 0x86, + 0xa2, 0x0e, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, + 0x18, 0xef, 0x50, 0x60, 0x11, 0x05, 0x81, 0xed, 0x50, 0x60, 0x0e, 0x15, + 0x62, 0x94, 0x7a, 0x00, 0xf0, 0x32, 0x00, 0x05, 0x50, 0xed, 0x55, 0x38, + 0x00, 0x00, 0x7f, 0xed, 0xb6, 0x41, 0x01, 0x80, 0xd6, 0x32, 0xbd, 0xa4, + 0xb7, 0x0c, 0x06, 0xef, 0x95, 0x30, 0x0a, 0x00, 0x55, 0x18, 0x04, 0x00, + 0x55, 0x18, 0x05, 0x00, 0x55, 0x18, 0x06, 0x00, 0x55, 0x18, 0x07, 0x00, + 0x55, 0x18, 0x08, 0x00, 0xd6, 0x45, 0x55, 0x18, 0x09, 0x00, 0x06, 0xef, + 0xb7, 0x0c, 0xd6, 0x45, 0x95, 0x30, 0x10, 0x00, 0x91, 0x0c, 0xf4, 0x45, + 0x88, 0xee, 0x70, 0x60, 0xab, 0x06, 0x91, 0x0c, 0x82, 0xee, 0x70, 0x60, + 0xa8, 0x16, 0xf4, 0x45, 0xa0, 0x89, 0x70, 0x14, 0xa6, 0x06, 0x91, 0x0c, + 0x82, 0xee, 0xf4, 0x45, 0xa0, 0x89, 0x70, 0x14, 0xa4, 0x06, 0x91, 0x0c, + 0xa0, 0x89, 0x50, 0x14, 0x13, 0x05, 0xb0, 0x14, 0x12, 0x05, 0x20, 0x25, + 0xd4, 0x45, 0xa2, 0x00, 0x90, 0x2a, 0x70, 0x14, 0x13, 0x05, 0xd0, 0x14, + 0x12, 0x05, 0xb0, 0x30, 0x14, 0x05, 0xb0, 0x25, 0xf3, 0x44, 0xf6, 0x45, + 0x82, 0x0c, 0x70, 0x60, 0x0d, 0x05, 0xa2, 0x41, 0xeb, 0x51, 0x42, 0x50, + 0x1f, 0x85, 0x70, 0x60, 0x0a, 0x15, 0xf1, 0xfc, 0x48, 0x00, 0xd1, 0xfc, + 0x70, 0x00, 0x43, 0x00, 0x3c, 0x8b, 0x63, 0x00, 0x80, 0xf8, 0x9a, 0x6e, + 0x92, 0x0c, 0x02, 0x46, 0x42, 0x00, 0x80, 0x28, 0x35, 0x05, 0x51, 0x18, + 0x3a, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x64, 0xca, 0x42, 0x30, 0x7b, 0x15, + 0xc2, 0x45, 0x1d, 0xf8, 0x14, 0x00, 0x0b, 0x8d, 0xb9, 0x41, 0x10, 0x80, + 0xaa, 0x86, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x5f, 0x19, 0xe2, 0x45, + 0x00, 0x0c, 0xb9, 0x41, 0x10, 0x80, 0x91, 0x0c, 0x39, 0x33, 0x41, 0x13, + 0x1d, 0x23, 0x1c, 0x50, 0x99, 0x45, 0x21, 0x4c, 0x40, 0x30, 0x80, 0x00, + 0x88, 0xcf, 0x55, 0x38, 0x00, 0x00, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0x9d, 0x18, 0x24, 0x00, 0xeb, 0xcb, 0x1e, 0xef, 0x95, 0xee, + 0x42, 0x30, 0xf5, 0x22, 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, + 0x08, 0xc8, 0xe2, 0x45, 0x09, 0x6e, 0xeb, 0x4b, 0x0c, 0x47, 0x00, 0x0c, + 0xcd, 0x4f, 0x3d, 0x23, 0x40, 0xd0, 0xa5, 0xfe, 0x70, 0x00, 0x44, 0x0e, + 0x65, 0x0e, 0x95, 0x34, 0x00, 0x00, 0xc4, 0xc8, 0xa5, 0xc8, 0x44, 0x2d, + 0xc4, 0xd2, 0x0c, 0x00, 0x46, 0xca, 0x07, 0xc8, 0x08, 0xc8, 0x09, 0xc8, + 0x0a, 0xc8, 0x0b, 0xc8, 0x0c, 0xc8, 0x0d, 0xc8, 0x1c, 0xad, 0x0e, 0xc8, + 0x52, 0xfc, 0xec, 0x06, 0x20, 0x6d, 0x16, 0xb4, 0x16, 0x00, 0x52, 0xf8, + 0xec, 0x06, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3d, 0x17, 0xc2, 0x45, + 0x05, 0xfe, 0x48, 0x00, 0x50, 0x00, 0x90, 0x13, 0xe2, 0x40, 0x24, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x41, 0x13, 0xe2, 0x45, 0x93, 0x0c, + 0x3d, 0x23, 0x40, 0x50, 0x1a, 0x47, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x3d, 0x17, 0xe2, 0x45, 0x00, 0x0c, 0x93, 0xfc, 0x48, 0x00, 0x73, 0xfc, + 0x4c, 0x00, 0xb9, 0x05, 0x43, 0x00, 0x90, 0x2b, 0x8d, 0x8e, 0x44, 0x00, + 0x90, 0x23, 0x66, 0xae, 0xb5, 0x06, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xdd, 0x10, 0xe2, 0x45, 0x93, 0x0c, 0x60, 0x8d, 0xa2, 0x41, 0x10, 0x80, + 0x33, 0xfe, 0x70, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x0f, 0x18, + 0xe2, 0x45, 0x09, 0x6e, 0x10, 0x29, 0xd0, 0xed, 0x42, 0xd0, 0xfc, 0x00, + 0x62, 0x94, 0x56, 0x00, 0x60, 0x30, 0x80, 0x00, 0x62, 0x94, 0x54, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0xb0, 0x41, 0x05, 0x80, 0x10, 0x32, 0x59, 0x5e, + 0x08, 0xed, 0x56, 0x94, 0x2c, 0x01, 0x00, 0x0c, 0x52, 0x32, 0xdc, 0x05, + 0xf0, 0x45, 0x92, 0x0c, 0x42, 0x96, 0xba, 0xff, 0x82, 0x0e, 0xb7, 0x41, + 0x10, 0x80, 0xb6, 0x41, 0x10, 0x80, 0xa0, 0x0e, 0xd1, 0x33, 0x0a, 0x00, + 0xf7, 0x32, 0x1b, 0x24, 0x0f, 0xcc, 0xd6, 0x32, 0x2d, 0x18, 0xf7, 0x45, + 0x00, 0x0c, 0x0c, 0x84, 0x09, 0x6e, 0xa7, 0xca, 0x48, 0xc8, 0xf6, 0x45, + 0xb4, 0x0e, 0xf0, 0x45, 0x94, 0x0c, 0x52, 0x94, 0x0f, 0x00, 0x82, 0x0e, + 0x54, 0xfc, 0x38, 0x01, 0x21, 0x2d, 0x77, 0x8d, 0x95, 0x0c, 0x15, 0xb4, + 0xec, 0xff, 0xbe, 0x0c, 0xf0, 0x45, 0x94, 0x0c, 0xb4, 0x0e, 0x52, 0xb4, + 0xf3, 0xff, 0x82, 0x0e, 0x15, 0x94, 0x90, 0xff, 0xa2, 0x41, 0x10, 0x80, + 0xb1, 0x30, 0x0a, 0x00, 0x42, 0x30, 0x1b, 0x24, 0xe2, 0x45, 0x95, 0x0c, + 0x48, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x01, 0xef, 0xb3, 0x0c, 0x09, 0x6e, + 0x42, 0x30, 0x2d, 0x18, 0xc2, 0x45, 0xbd, 0xfa, 0x1c, 0x00, 0xe2, 0x40, + 0x7b, 0xff, 0x3d, 0x23, 0x40, 0x50, 0x1a, 0x47, 0xa2, 0x41, 0x10, 0x80, + 0xea, 0x86, 0x92, 0x32, 0xdc, 0x05, 0x42, 0x30, 0xfb, 0x19, 0xc2, 0x45, + 0xb0, 0x41, 0x05, 0x80, 0x10, 0x32, 0x59, 0x5e, 0xf0, 0x45, 0x94, 0x0c, + 0x54, 0x94, 0xa4, 0xff, 0xe0, 0x32, 0x02, 0x00, 0x06, 0xcc, 0x00, 0x0c, + 0xf0, 0x45, 0x00, 0x0c, 0x54, 0x94, 0x9c, 0xff, 0x00, 0x0c, 0x62, 0xfc, + 0x38, 0x01, 0xb1, 0x2d, 0xf7, 0x8d, 0x82, 0x0c, 0x62, 0xfc, 0x00, 0x06, + 0xe3, 0xb6, 0xf2, 0xff, 0x00, 0x0c, 0x62, 0xfc, 0x98, 0x04, 0xe3, 0x40, + 0x2d, 0x00, 0x30, 0x6a, 0xb5, 0x14, 0x11, 0x00, 0x75, 0x14, 0x10, 0x00, + 0x44, 0x15, 0x30, 0x00, 0xc4, 0x14, 0x31, 0x00, 0x24, 0x15, 0x32, 0x00, + 0x15, 0x15, 0x12, 0x00, 0xf5, 0x14, 0x13, 0x00, 0x64, 0x15, 0x33, 0x00, + 0x6e, 0x44, 0x43, 0x01, 0x10, 0x1b, 0xd5, 0x14, 0x14, 0x00, 0x44, 0x15, + 0x34, 0x00, 0xdd, 0x44, 0x28, 0x01, 0x10, 0x43, 0xb5, 0x14, 0x15, 0x00, + 0x24, 0x15, 0x35, 0x00, 0x03, 0x01, 0x90, 0x1a, 0x67, 0x01, 0x10, 0x23, + 0xdc, 0x44, 0x46, 0x01, 0x10, 0x23, 0xdc, 0x44, 0x25, 0x01, 0x10, 0x23, + 0xdc, 0x44, 0xbd, 0x2d, 0xe3, 0x40, 0x60, 0xff, 0x62, 0xfc, 0x9c, 0x04, + 0xe3, 0x40, 0x2d, 0x00, 0x30, 0x6a, 0xb5, 0x14, 0x11, 0x00, 0x75, 0x14, + 0x10, 0x00, 0x44, 0x15, 0x30, 0x00, 0xc4, 0x14, 0x31, 0x00, 0x24, 0x15, + 0x32, 0x00, 0x15, 0x15, 0x12, 0x00, 0xf5, 0x14, 0x13, 0x00, 0x64, 0x15, + 0x33, 0x00, 0x6e, 0x44, 0x43, 0x01, 0x10, 0x1b, 0xd5, 0x14, 0x14, 0x00, + 0x44, 0x15, 0x34, 0x00, 0xdd, 0x44, 0x28, 0x01, 0x10, 0x43, 0xb5, 0x14, + 0x15, 0x00, 0x24, 0x15, 0x35, 0x00, 0x03, 0x01, 0x90, 0x1a, 0x67, 0x01, + 0x10, 0x23, 0xdc, 0x44, 0x46, 0x01, 0x10, 0x23, 0xdc, 0x44, 0x25, 0x01, + 0x10, 0x23, 0xdc, 0x44, 0xbd, 0x2d, 0xe3, 0x40, 0x2f, 0xff, 0xa2, 0xfc, + 0x94, 0x04, 0xe5, 0x40, 0xef, 0xfe, 0x65, 0x14, 0x30, 0x00, 0xc5, 0x15, + 0x31, 0x00, 0x95, 0x14, 0x10, 0x00, 0x75, 0x15, 0x11, 0x00, 0xa5, 0x15, + 0x32, 0x00, 0x55, 0x15, 0x12, 0x00, 0x85, 0x15, 0x33, 0x00, 0x35, 0x15, + 0x13, 0x00, 0xc5, 0x14, 0x34, 0x00, 0x15, 0x15, 0x14, 0x00, 0x5c, 0x44, + 0xcb, 0x01, 0x10, 0x73, 0xf5, 0x14, 0x15, 0x00, 0xc3, 0x01, 0x90, 0x1a, + 0xaa, 0x01, 0x10, 0x6b, 0xa5, 0x14, 0x35, 0x00, 0xa3, 0x01, 0x90, 0x1a, + 0x89, 0x01, 0x10, 0x63, 0x83, 0x01, 0x90, 0x1a, 0xc8, 0x00, 0x10, 0x33, + 0xde, 0x44, 0x6f, 0x44, 0xdd, 0x44, 0xbd, 0x2d, 0xa3, 0x8d, 0xa3, 0x41, + 0x09, 0x80, 0xa3, 0x30, 0xd4, 0x4c, 0x51, 0x0b, 0x63, 0x14, 0xd4, 0x4c, + 0xa5, 0x15, 0x02, 0x00, 0x85, 0x15, 0x03, 0x00, 0x5c, 0x44, 0xcb, 0x00, + 0x10, 0x5b, 0x54, 0x0b, 0x63, 0x01, 0x90, 0x1a, 0xaa, 0x01, 0x10, 0x53, + 0x55, 0x0a, 0x43, 0x01, 0x90, 0x1a, 0x89, 0x01, 0x10, 0x4b, 0x23, 0x01, + 0x90, 0x1a, 0xc8, 0x00, 0x10, 0x43, 0x03, 0x01, 0x90, 0x1a, 0x7c, 0x44, + 0xdf, 0x44, 0xbd, 0x2d, 0xa3, 0x40, 0xa0, 0xfe, 0x42, 0x34, 0xd4, 0x02, + 0x42, 0xb0, 0x0a, 0x00, 0x02, 0xb4, 0xd6, 0xfe, 0xa2, 0x41, 0x10, 0x80, + 0x9b, 0xce, 0x42, 0x30, 0x41, 0x13, 0x92, 0x32, 0x70, 0x04, 0xf0, 0x45, + 0x94, 0x0c, 0x54, 0x94, 0xcf, 0xfe, 0xc2, 0x0e, 0xb5, 0x41, 0x10, 0x80, + 0xe0, 0x0e, 0x0e, 0xcc, 0xb5, 0x32, 0x2d, 0x18, 0x57, 0xfc, 0x1c, 0x00, + 0xe8, 0xca, 0xf6, 0x0e, 0xd5, 0x45, 0x5d, 0xf8, 0x1c, 0x00, 0xf0, 0x45, + 0x96, 0x0c, 0x54, 0x94, 0x33, 0x00, 0xc2, 0x0e, 0x11, 0x15, 0x0a, 0x00, + 0x9b, 0x0a, 0x76, 0x14, 0x10, 0x00, 0xf6, 0x14, 0x11, 0x00, 0x96, 0x14, + 0x12, 0x00, 0x1c, 0x09, 0x51, 0x15, 0x0d, 0x00, 0xd6, 0x14, 0x13, 0x00, + 0x03, 0x01, 0x10, 0x1b, 0x7d, 0x44, 0x31, 0x15, 0x0e, 0x00, 0xb6, 0x14, + 0x14, 0x00, 0xdf, 0x44, 0x54, 0x44, 0x11, 0x15, 0x0f, 0x00, 0x96, 0x14, + 0x15, 0x00, 0xd3, 0x44, 0x46, 0x01, 0x10, 0x33, 0xd6, 0x44, 0x25, 0x01, + 0x10, 0x2b, 0xd5, 0x44, 0x04, 0x01, 0x10, 0x1b, 0xd3, 0x44, 0x2d, 0x2d, + 0xa2, 0x40, 0xd3, 0xff, 0x0c, 0x84, 0x17, 0xb4, 0xc9, 0xff, 0x09, 0x6e, + 0xf0, 0x45, 0x96, 0x0c, 0xf6, 0x0e, 0x54, 0xb4, 0xcf, 0xff, 0xc2, 0x0e, + 0x17, 0x94, 0x88, 0xfe, 0x01, 0xef, 0x57, 0xfc, 0x1c, 0x00, 0xb3, 0x0c, + 0x47, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x09, 0x6e, 0x42, 0x30, 0x2d, 0x18, + 0xc2, 0x45, 0xfd, 0xfa, 0x20, 0x00, 0x02, 0x94, 0x3b, 0xfe, 0xa2, 0x41, + 0x10, 0x80, 0x3c, 0xce, 0x00, 0x0c, 0x00, 0x0c, 0xc5, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x5d, 0x22, 0x6c, 0xd0, 0x57, 0xef, 0x05, 0x0e, 0x24, 0x0e, + 0xa0, 0x0c, 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, 0x09, 0x6e, 0xa2, 0x41, + 0x09, 0x80, 0x30, 0x15, 0x00, 0x00, 0x10, 0x15, 0x01, 0x00, 0x82, 0x0b, + 0x03, 0x0b, 0x84, 0x0a, 0x05, 0x0a, 0x42, 0x14, 0xd0, 0x4c, 0x40, 0x31, + 0x00, 0x02, 0x81, 0xed, 0x49, 0xc9, 0x3d, 0x19, 0x57, 0x00, 0x1d, 0x19, + 0x58, 0x00, 0xfd, 0x18, 0x59, 0x00, 0xdd, 0x18, 0x5a, 0x00, 0xbd, 0x18, + 0x5b, 0x00, 0x62, 0x94, 0x2d, 0x00, 0x9d, 0x18, 0x5c, 0x00, 0x51, 0xfc, + 0x98, 0x00, 0x71, 0xfc, 0x94, 0x00, 0xc2, 0x14, 0x4a, 0x01, 0xa2, 0x14, + 0x4b, 0x01, 0x82, 0x14, 0x4c, 0x01, 0x02, 0x15, 0x48, 0x01, 0xe2, 0x14, + 0x49, 0x01, 0x42, 0x14, 0x4d, 0x01, 0xdd, 0x18, 0x53, 0x00, 0xbd, 0x18, + 0x54, 0x00, 0x5d, 0x18, 0x56, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x9d, 0x18, + 0x55, 0x00, 0x1d, 0x19, 0x51, 0x00, 0xfd, 0x18, 0x52, 0x00, 0x0e, 0xef, + 0x7d, 0x60, 0x50, 0x80, 0xd7, 0xee, 0x09, 0x6e, 0x42, 0x30, 0xf5, 0x22, + 0xc2, 0x45, 0x7d, 0x60, 0x4d, 0x90, 0x5d, 0x22, 0x6c, 0x50, 0x1e, 0x47, + 0x5d, 0x18, 0x5d, 0x00, 0xa5, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x01, 0x80, + 0x06, 0xef, 0xa5, 0x30, 0xd4, 0x4c, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0x9d, 0x30, 0x5e, 0x00, 0xc8, 0xcf, 0x51, 0xfc, 0x98, 0x00, 0x00, 0x0c, + 0xe1, 0x4f, 0x3d, 0x23, 0x18, 0xd0, 0x44, 0xfc, 0x30, 0x01, 0xc4, 0x0e, + 0xad, 0x68, 0x11, 0x94, 0x61, 0x00, 0x86, 0x0e, 0xa2, 0x41, 0x09, 0x80, + 0x00, 0x0d, 0x20, 0x0d, 0x02, 0xf9, 0x40, 0x4d, 0x22, 0xf9, 0x44, 0x4d, + 0xa2, 0x41, 0x02, 0x80, 0x96, 0x0c, 0xd4, 0x0c, 0x42, 0x30, 0x25, 0x46, + 0x31, 0x32, 0x58, 0xff, 0xc2, 0x45, 0xb2, 0x41, 0x05, 0x80, 0x52, 0x32, + 0x59, 0x5e, 0xf2, 0x45, 0x91, 0x0c, 0x51, 0x94, 0x30, 0x00, 0xc2, 0x0f, + 0xb3, 0x41, 0x09, 0x80, 0xb5, 0x41, 0x01, 0x80, 0x56, 0x30, 0x0c, 0x06, + 0xb7, 0x41, 0x01, 0x80, 0x13, 0x32, 0xd4, 0x4c, 0xb5, 0x32, 0xa1, 0xa4, + 0xf7, 0x32, 0xbd, 0xa4, 0x06, 0xcc, 0x44, 0xc8, 0xf2, 0x45, 0x9e, 0x0c, + 0x51, 0x94, 0x1b, 0x00, 0xc2, 0x0f, 0x01, 0x2b, 0x53, 0x34, 0xd4, 0x4c, + 0x02, 0x2a, 0xb0, 0x0c, 0xd6, 0x44, 0xd4, 0x44, 0x2f, 0x2d, 0x9e, 0x30, + 0x78, 0x00, 0x70, 0x8d, 0x05, 0xef, 0xf5, 0x45, 0x00, 0x0c, 0x6c, 0xad, + 0x84, 0x48, 0x06, 0xef, 0xf7, 0x45, 0xb0, 0x0c, 0xf2, 0x45, 0x9e, 0x0c, + 0x94, 0x52, 0x80, 0x00, 0x51, 0xb4, 0xe7, 0xff, 0xc2, 0x0f, 0x94, 0xd2, + 0x80, 0x00, 0x14, 0xb4, 0x05, 0x00, 0xa6, 0x41, 0x09, 0x80, 0x3d, 0x23, + 0x18, 0x50, 0x10, 0x47, 0xb6, 0xfc, 0x08, 0x06, 0xb9, 0x41, 0x09, 0x80, + 0x96, 0x30, 0x6c, 0x07, 0xc6, 0x30, 0xd4, 0x4c, 0x39, 0x33, 0xe5, 0xec, + 0x3d, 0x23, 0x18, 0x50, 0x99, 0x45, 0x21, 0x4c, 0x5c, 0xfc, 0xe4, 0x81, + 0x20, 0x6d, 0x9c, 0xcf, 0x5c, 0xf8, 0xe4, 0x81, 0xe5, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0x1d, 0x23, 0x14, 0xd0, 0x42, 0xfe, 0x58, 0xbf, 0xb3, 0x41, + 0x05, 0x80, 0x73, 0x32, 0x59, 0x5e, 0x52, 0x32, 0x20, 0x02, 0xf3, 0x45, + 0x92, 0x0c, 0x52, 0x94, 0x2d, 0x00, 0xb5, 0x41, 0x10, 0x80, 0xb4, 0x41, + 0x10, 0x80, 0xb7, 0x41, 0x05, 0x80, 0x02, 0x0e, 0xc0, 0x32, 0x01, 0x00, + 0xb5, 0x32, 0x0b, 0x1f, 0x94, 0x32, 0x1d, 0x1f, 0xf7, 0x32, 0xe1, 0xe8, + 0x30, 0x32, 0x2c, 0x00, 0xf5, 0x45, 0x91, 0x0c, 0x50, 0xfc, 0x68, 0x00, + 0xe2, 0x40, 0x0c, 0x00, 0xc0, 0x0e, 0xf4, 0x45, 0x91, 0x0c, 0xf3, 0x45, + 0x90, 0x0c, 0x52, 0xb4, 0xf1, 0xff, 0x02, 0x0e, 0x56, 0x0c, 0x1d, 0x23, + 0x14, 0x50, 0x0e, 0x47, 0x50, 0xfc, 0x98, 0x00, 0xa2, 0x40, 0xf0, 0xff, + 0xf7, 0x45, 0x90, 0x0c, 0xe2, 0x40, 0xed, 0xff, 0xec, 0xcf, 0xc0, 0x0e, + 0xf1, 0xcf, 0xc0, 0x32, 0x01, 0x00, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0xfd, 0x22, 0x10, 0xd0, 0x42, 0xfe, 0x58, 0xbf, 0xb3, 0x41, + 0x05, 0x80, 0xc4, 0x0e, 0x52, 0x32, 0x20, 0x02, 0x73, 0x32, 0x59, 0x5e, + 0xf3, 0x45, 0x92, 0x0c, 0x52, 0x94, 0x21, 0x00, 0xb5, 0x41, 0x10, 0x80, + 0xb4, 0x41, 0x10, 0x80, 0x02, 0x0e, 0xb5, 0x32, 0x0b, 0x1f, 0x09, 0xcc, + 0x94, 0x32, 0x1d, 0x1f, 0xf4, 0x45, 0x00, 0x0c, 0xf3, 0x45, 0x90, 0x0c, + 0x52, 0x94, 0x11, 0x00, 0x02, 0x0e, 0x30, 0x32, 0x2c, 0x00, 0xf5, 0x45, + 0x91, 0x0c, 0x02, 0x69, 0x2a, 0x69, 0x56, 0x00, 0x50, 0x12, 0x70, 0xad, + 0x91, 0x0c, 0xf4, 0x45, 0x00, 0x0c, 0x40, 0x0c, 0xfd, 0x22, 0x10, 0x50, + 0x0c, 0x47, 0x01, 0xed, 0xfd, 0x22, 0x10, 0x50, 0x0c, 0x47, 0x00, 0x0c, + 0xe5, 0x4f, 0x1d, 0x23, 0x14, 0xd0, 0xb0, 0x41, 0x09, 0x80, 0x10, 0x32, + 0x19, 0xef, 0xf0, 0x45, 0x10, 0xee, 0x12, 0xad, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x14, 0x1c, 0x4d, 0x05, 0x8d, 0xb9, 0x41, 0x10, 0x80, 0x1d, 0x23, + 0x14, 0x50, 0x0e, 0x47, 0x81, 0xee, 0x01, 0xee, 0x39, 0x33, 0x65, 0x22, + 0x1d, 0x23, 0x14, 0x50, 0x99, 0x45, 0x1d, 0x4c, 0xf0, 0x45, 0x04, 0xee, + 0x72, 0xad, 0xb7, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x05, 0x80, 0xff, 0xee, + 0x97, 0x30, 0x4c, 0x9b, 0xb6, 0x41, 0x08, 0x80, 0x42, 0x30, 0xf1, 0x4b, + 0xc2, 0x45, 0xb2, 0x41, 0x05, 0x80, 0x52, 0x32, 0x59, 0x5e, 0xd2, 0x45, + 0x96, 0x30, 0x60, 0x03, 0x02, 0x0e, 0xd6, 0x32, 0x60, 0x03, 0xf2, 0x45, + 0x82, 0x0c, 0xd0, 0x96, 0x15, 0x00, 0xb4, 0x41, 0x05, 0x80, 0xb3, 0x41, + 0x10, 0x80, 0x22, 0x0e, 0xb0, 0x0e, 0x94, 0x32, 0x61, 0x5e, 0x73, 0x32, + 0x3f, 0x1e, 0xf4, 0x45, 0x90, 0x0c, 0xf3, 0x45, 0x95, 0x0c, 0x91, 0x0c, + 0xf2, 0x45, 0x11, 0x0e, 0xb1, 0x0e, 0xd0, 0xb6, 0xf6, 0xff, 0x22, 0x0e, + 0xa2, 0x41, 0x05, 0x80, 0x97, 0x30, 0x4c, 0x9b, 0x42, 0x30, 0xf9, 0x4b, + 0xc2, 0x45, 0xb6, 0x41, 0x08, 0x80, 0xd2, 0x45, 0x96, 0x30, 0x68, 0x03, + 0x02, 0x0e, 0xd6, 0x32, 0x68, 0x03, 0xf2, 0x45, 0x82, 0x0c, 0xd0, 0x96, + 0xb0, 0xff, 0xb4, 0x41, 0x05, 0x80, 0xb3, 0x41, 0x10, 0x80, 0x22, 0x0e, + 0xb0, 0x0e, 0x94, 0x32, 0x61, 0x5e, 0x73, 0x32, 0x3f, 0x1e, 0xf4, 0x45, + 0x90, 0x0c, 0xf3, 0x45, 0x95, 0x0c, 0x91, 0x0c, 0xf2, 0x45, 0x11, 0x0e, + 0xb1, 0x0e, 0xd0, 0xb6, 0xf6, 0xff, 0x22, 0x0e, 0x1d, 0x23, 0x14, 0x50, + 0x0e, 0x47, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x25, 0x23, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0x95, 0xee, 0xe2, 0x45, 0x00, 0x0c, 0x08, 0x8d, 0xe5, 0x4b, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x89, 0xef, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0xb9, 0x41, 0x10, 0x80, 0x39, 0x33, 0x2b, 0x23, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0x4c, 0x48, 0xe7, 0xcb, 0x44, 0xc8, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x01, 0xbf, 0xe2, 0x45, 0x00, 0x0c, + 0xe7, 0x4b, 0xb9, 0x41, 0x02, 0x80, 0xc0, 0x0c, 0xbc, 0x30, 0x00, 0x81, + 0x80, 0x0c, 0x39, 0x33, 0x89, 0xf2, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, + 0xf1, 0x4f, 0x4c, 0x48, 0xe7, 0xcb, 0x44, 0xc8, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0xd1, 0x47, 0xe2, 0x45, 0x00, 0x0c, 0xe7, 0x4b, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0x30, 0xd4, 0x4c, 0x02, 0xf8, 0xd4, 0x4c, 0xa2, 0x41, + 0x09, 0x80, 0x02, 0x18, 0xd0, 0x4c, 0x32, 0xa8, 0x08, 0x47, 0x00, 0x0c, + 0xd0, 0x0b, 0x65, 0x15, 0x01, 0x00, 0x46, 0x14, 0x30, 0x00, 0x86, 0x14, + 0x31, 0x00, 0x45, 0x15, 0x02, 0x00, 0x66, 0x14, 0x32, 0x00, 0x25, 0x15, + 0x03, 0x00, 0xa6, 0x15, 0x33, 0x00, 0x05, 0x15, 0x04, 0x00, 0x8b, 0x00, + 0x10, 0x23, 0x57, 0x44, 0x86, 0x15, 0x34, 0x00, 0xd4, 0x44, 0xd5, 0x0a, + 0x6a, 0x00, 0x10, 0x1b, 0x86, 0x14, 0x35, 0x00, 0xda, 0x44, 0xa9, 0x01, + 0x10, 0x13, 0xda, 0x44, 0x88, 0x01, 0x10, 0x13, 0xda, 0x44, 0x85, 0x00, + 0x10, 0x13, 0xda, 0x44, 0xbd, 0x2d, 0x03, 0x94, 0x4c, 0x00, 0x01, 0xed, + 0xa3, 0x41, 0x09, 0x80, 0x83, 0x31, 0xd4, 0x4c, 0x83, 0x14, 0xd4, 0x4c, + 0xec, 0x15, 0x01, 0x00, 0x6c, 0x14, 0x02, 0x00, 0xcc, 0x15, 0x03, 0x00, + 0xac, 0x15, 0x04, 0x00, 0x67, 0x44, 0xeb, 0x01, 0x10, 0x7b, 0xe4, 0x01, + 0x90, 0x22, 0x6a, 0x00, 0x10, 0x1b, 0x8c, 0x15, 0x05, 0x00, 0xdc, 0x44, + 0xc9, 0x01, 0x10, 0x23, 0xdc, 0x44, 0xa8, 0x01, 0x10, 0x23, 0xdc, 0x44, + 0x85, 0x01, 0x10, 0x23, 0xdc, 0x44, 0xbd, 0x2d, 0xe3, 0x40, 0x27, 0x00, + 0xe6, 0x69, 0xe3, 0x40, 0x23, 0x00, 0x83, 0x14, 0x31, 0x00, 0x83, 0x15, + 0x30, 0x00, 0xc3, 0x14, 0x32, 0x00, 0x43, 0x14, 0x33, 0x00, 0x8b, 0x00, + 0x10, 0x5b, 0x87, 0x01, 0x10, 0x3b, 0x83, 0x14, 0x34, 0x00, 0x67, 0x01, + 0x90, 0x3a, 0xca, 0x00, 0x10, 0x53, 0x63, 0x14, 0x35, 0x00, 0x47, 0x01, + 0x90, 0x3a, 0x49, 0x00, 0x10, 0x13, 0xd7, 0x44, 0x88, 0x00, 0x10, 0x43, + 0x02, 0x01, 0x90, 0x12, 0x6b, 0x44, 0xd5, 0x44, 0x2d, 0x2d, 0x9f, 0x45, + 0x42, 0xb0, 0x01, 0x00, 0x40, 0x0c, 0xbf, 0x45, 0xad, 0x4e, 0x66, 0xb0, + 0x24, 0x00, 0x3d, 0x23, 0x80, 0xd2, 0x1d, 0xf8, 0x74, 0x02, 0x8f, 0xad, + 0x64, 0xfe, 0x30, 0x01, 0x64, 0xfc, 0x5c, 0x07, 0x8a, 0x8d, 0x04, 0x0e, + 0xe3, 0xfe, 0x00, 0x00, 0x27, 0x35, 0x1c, 0x00, 0x17, 0xfd, 0x04, 0x00, + 0x09, 0x95, 0x05, 0x00, 0x47, 0x0e, 0x3d, 0x23, 0x80, 0x52, 0x9f, 0x45, + 0x55, 0x4d, 0x44, 0xfc, 0x9c, 0x04, 0x85, 0x0e, 0x11, 0x8d, 0x26, 0x0e, + 0xa2, 0xfc, 0x44, 0x00, 0xe5, 0x40, 0x0c, 0x00, 0x20, 0x6b, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0x15, 0xf1, 0xc2, 0x45, 0xb4, 0x30, 0x10, 0x00, + 0x02, 0xb4, 0xce, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x10, 0xff, 0x94, 0x04, + 0x18, 0x94, 0xe3, 0xff, 0xd4, 0x32, 0x10, 0x00, 0xa2, 0x41, 0x09, 0x80, + 0xd8, 0x0c, 0xb6, 0x0c, 0x42, 0x30, 0x15, 0xf1, 0xe2, 0x45, 0x90, 0x0c, + 0x58, 0x8d, 0xb5, 0x41, 0x09, 0x80, 0x55, 0x14, 0xd4, 0x4c, 0xe2, 0x40, + 0xbf, 0x01, 0xb5, 0x32, 0xd4, 0x4c, 0x55, 0x14, 0x01, 0x00, 0xe2, 0x40, + 0xb9, 0x01, 0x52, 0xfc, 0x18, 0x00, 0x42, 0xd0, 0x00, 0x01, 0x02, 0x94, + 0xf2, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x50, 0xfc, 0xc4, 0x04, 0x22, 0x2d, + 0x02, 0xb4, 0xe4, 0x01, 0xa2, 0x41, 0x10, 0x80, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xd9, 0x1a, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x41, 0x10, 0x80, + 0x04, 0xef, 0xb4, 0x30, 0x20, 0x00, 0x42, 0x30, 0x4d, 0x13, 0xe2, 0x45, + 0x80, 0x0c, 0xa5, 0x41, 0x00, 0x30, 0x80, 0x30, 0x80, 0x00, 0xa5, 0x50, + 0x21, 0x24, 0x46, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x9d, 0x20, 0x10, 0x90, + 0xfd, 0x30, 0x30, 0x01, 0xc0, 0x0c, 0xc7, 0xca, 0xa8, 0xca, 0xb1, 0x30, + 0xdc, 0xff, 0x42, 0x30, 0x7d, 0x1c, 0xc2, 0x45, 0x94, 0x30, 0x24, 0x00, + 0xc2, 0x0f, 0x5d, 0xfc, 0x80, 0x01, 0x22, 0x09, 0x28, 0x2d, 0x02, 0xb4, + 0xac, 0x01, 0xa2, 0x41, 0x10, 0x80, 0xdd, 0x32, 0x10, 0x00, 0x5d, 0x30, + 0x38, 0x01, 0x96, 0x0c, 0x02, 0xfd, 0x00, 0x00, 0xa1, 0x6b, 0x22, 0x6b, + 0xa3, 0x6a, 0x7d, 0x30, 0x58, 0x02, 0x28, 0x6d, 0x04, 0xf9, 0x00, 0x00, + 0xc1, 0xeb, 0x42, 0xeb, 0xc3, 0xea, 0x62, 0xb4, 0xf1, 0xff, 0x48, 0x6e, + 0xdd, 0x20, 0x30, 0x11, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3f, 0x21, + 0xf8, 0x86, 0xe2, 0x45, 0x00, 0x0c, 0x53, 0xfc, 0x40, 0x00, 0x42, 0x00, + 0x6c, 0x02, 0xe2, 0x40, 0x39, 0x00, 0x9d, 0xfc, 0x50, 0x01, 0x36, 0x8e, + 0x5d, 0x14, 0x2f, 0x02, 0xa2, 0xb0, 0x04, 0x00, 0xa5, 0x40, 0x30, 0x00, + 0xf0, 0x34, 0xa6, 0x04, 0xc2, 0x0a, 0xc7, 0x00, 0xec, 0x38, 0xa5, 0xd0, + 0xfe, 0x00, 0xa6, 0x00, 0x90, 0x43, 0x08, 0xb4, 0x25, 0x00, 0x58, 0x4c, + 0x2a, 0x05, 0x2d, 0x2d, 0xc2, 0x00, 0x90, 0x13, 0x1f, 0xad, 0x5d, 0x05, + 0x2d, 0x2d, 0x28, 0x06, 0x43, 0x0a, 0x01, 0xed, 0xf5, 0x2f, 0x47, 0x00, + 0x10, 0x38, 0x87, 0x00, 0x50, 0x12, 0xe2, 0x40, 0x13, 0x00, 0x53, 0xfc, + 0x08, 0x00, 0x82, 0x40, 0xd8, 0x01, 0x00, 0x0c, 0x53, 0xfc, 0x00, 0x00, + 0x22, 0x2e, 0x04, 0xb4, 0xe7, 0x01, 0x40, 0x00, 0x4c, 0x08, 0xa2, 0x41, + 0x10, 0x80, 0x08, 0x84, 0x42, 0x30, 0x49, 0x1a, 0xe2, 0x45, 0x93, 0x0c, + 0x53, 0xfc, 0xfc, 0x06, 0xe2, 0x40, 0x11, 0x00, 0x53, 0xfc, 0x08, 0x00, + 0x82, 0x40, 0x0d, 0x00, 0x00, 0x0c, 0x53, 0xfc, 0x08, 0x06, 0xa2, 0x40, + 0x08, 0x00, 0x50, 0xfc, 0x38, 0x01, 0x42, 0x00, 0x6c, 0x00, 0x02, 0x94, + 0x95, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x50, 0x14, 0x4e, 0x07, 0x08, 0xad, + 0xa2, 0x41, 0x10, 0x80, 0x50, 0xfc, 0x60, 0x07, 0x26, 0x2d, 0x09, 0x8d, + 0xa2, 0x41, 0x10, 0x80, 0xfd, 0x30, 0x74, 0x02, 0x1e, 0x84, 0x42, 0x30, + 0x2f, 0x25, 0xe2, 0x45, 0x90, 0x0c, 0x50, 0xfc, 0xc8, 0x04, 0x02, 0xb4, + 0x40, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x53, 0xfc, 0x40, 0x00, 0x42, 0x00, + 0x2c, 0x06, 0xe2, 0x40, 0x14, 0x00, 0x94, 0x60, 0x1b, 0x00, 0x54, 0x60, + 0x1f, 0x00, 0x94, 0x60, 0x18, 0x10, 0x54, 0x60, 0x1c, 0x10, 0x90, 0xf8, + 0x30, 0x06, 0x50, 0xf8, 0x34, 0x06, 0x52, 0xfc, 0x10, 0x00, 0x9d, 0x14, + 0x0d, 0x02, 0x50, 0xf8, 0x38, 0x06, 0x90, 0x18, 0x02, 0x07, 0x50, 0xfc, + 0xd4, 0x04, 0x5e, 0xb4, 0x06, 0x00, 0x00, 0x31, 0x01, 0x00, 0x50, 0xfc, + 0xd0, 0x04, 0xa2, 0x40, 0xe0, 0xfe, 0xa2, 0x41, 0x10, 0x80, 0xf8, 0x86, + 0x52, 0x85, 0x42, 0x30, 0xdf, 0x17, 0x10, 0xf9, 0xd0, 0x04, 0xd0, 0xfb, + 0xd4, 0x04, 0xc2, 0x45, 0x1d, 0xf9, 0x78, 0x02, 0x52, 0xfc, 0x10, 0x00, + 0x1d, 0xfd, 0x78, 0x02, 0xd2, 0x20, 0x00, 0x10, 0x7d, 0x30, 0x30, 0x01, + 0x5d, 0x20, 0x10, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xaf, 0x1a, + 0x90, 0x0c, 0xc2, 0x45, 0x1d, 0xf9, 0x18, 0x00, 0x50, 0xfc, 0xc4, 0x04, + 0x42, 0xd0, 0x00, 0x40, 0x02, 0x94, 0x19, 0x01, 0x5d, 0xfc, 0x8c, 0x01, + 0x50, 0xfc, 0xb0, 0x04, 0x02, 0x94, 0xa5, 0x00, 0x5d, 0x14, 0x0e, 0x02, + 0xb1, 0x41, 0x10, 0x80, 0xbe, 0x41, 0x10, 0x80, 0x31, 0x32, 0x0b, 0x1f, + 0xde, 0x33, 0x1d, 0x1f, 0x5d, 0xfc, 0x5c, 0x01, 0xe2, 0x40, 0x1a, 0x01, + 0xa0, 0x0b, 0x01, 0xef, 0xb4, 0x34, 0x22, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, 0xbd, 0xfc, 0x74, 0x02, + 0x73, 0x32, 0x54, 0x04, 0x93, 0x0c, 0xd5, 0x44, 0xd1, 0x45, 0x5d, 0xf8, + 0x74, 0x02, 0xa2, 0x41, 0x10, 0x80, 0xb5, 0x0c, 0x42, 0x30, 0x15, 0x24, + 0xe2, 0x45, 0x90, 0x0c, 0x22, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x98, 0x86, + 0x42, 0x30, 0xb7, 0x18, 0xc2, 0x45, 0xdd, 0x30, 0x30, 0x01, 0x9d, 0xfc, + 0x74, 0x02, 0xdd, 0x20, 0x6c, 0x11, 0xb1, 0x0c, 0xd4, 0x44, 0x9d, 0x30, + 0x74, 0x02, 0x87, 0xc8, 0x9d, 0xfc, 0x84, 0x01, 0x5d, 0xf8, 0x74, 0x02, + 0xa2, 0x41, 0x10, 0x80, 0x85, 0xc8, 0x9d, 0xfc, 0x78, 0x01, 0xa6, 0xca, + 0x42, 0x30, 0xf3, 0x15, 0x84, 0xc8, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x40, + 0xaa, 0x00, 0x8d, 0x8c, 0x5d, 0xfc, 0xf0, 0x01, 0xe2, 0x40, 0x09, 0x00, + 0x20, 0x0b, 0xa2, 0x41, 0x10, 0x80, 0x98, 0x86, 0x42, 0x30, 0x05, 0x1c, + 0xc2, 0x45, 0xf2, 0x14, 0x24, 0x00, 0xfe, 0x45, 0x93, 0x0c, 0x5d, 0x30, + 0x38, 0x01, 0xa0, 0x6b, 0x21, 0x6b, 0xa2, 0x6a, 0x23, 0x6a, 0x7d, 0x30, + 0x58, 0x02, 0x28, 0x6d, 0xf6, 0xf8, 0x00, 0x00, 0xd6, 0xf8, 0x04, 0x00, + 0xb6, 0xf8, 0x08, 0x00, 0x96, 0xf8, 0x0c, 0x00, 0x62, 0xb4, 0xef, 0xff, + 0xd6, 0x32, 0x10, 0x00, 0xdd, 0x20, 0x30, 0x11, 0xa2, 0x41, 0x10, 0x80, + 0xf8, 0x86, 0x42, 0x30, 0x45, 0x21, 0xe2, 0x45, 0x00, 0x0c, 0x7d, 0xfc, + 0xe8, 0x01, 0x5d, 0x14, 0x3b, 0x02, 0xfd, 0xfc, 0xe0, 0x01, 0x66, 0xc8, + 0x7d, 0xfc, 0xe4, 0x01, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xb7, 0x0c, + 0x78, 0x87, 0x42, 0x30, 0x2b, 0x17, 0xc2, 0x45, 0x7d, 0xf8, 0x14, 0x00, + 0x7d, 0xfc, 0x74, 0x02, 0xd3, 0x44, 0xa2, 0x0c, 0x5d, 0xf8, 0x74, 0x02, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x75, 0x15, 0xe2, 0x45, 0x90, 0x0c, + 0x1c, 0xce, 0x00, 0x0c, 0x52, 0x85, 0xf8, 0x86, 0x42, 0x30, 0xab, 0x24, + 0xe2, 0x45, 0x00, 0x0c, 0x14, 0xce, 0x00, 0x0c, 0x46, 0xce, 0xb8, 0x32, + 0x30, 0x00, 0x01, 0xee, 0xa5, 0x41, 0x10, 0x00, 0x44, 0x00, 0x58, 0x10, + 0x50, 0x18, 0x27, 0x06, 0x5d, 0xfc, 0x74, 0x02, 0xd3, 0x33, 0xe4, 0x05, + 0xb1, 0x41, 0x10, 0x80, 0xd5, 0x44, 0x90, 0xf8, 0xb0, 0x04, 0x31, 0x32, + 0x0b, 0x1f, 0x9e, 0x0c, 0xd1, 0x45, 0x5d, 0xf8, 0x74, 0x02, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x93, 0x18, 0xe2, 0x45, 0x93, 0x0c, 0x9e, 0x0c, + 0xbe, 0x41, 0x10, 0x80, 0xde, 0x33, 0x1d, 0x1f, 0xfe, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x99, 0x18, 0xe2, 0x45, 0x90, 0x0c, + 0x3d, 0xcf, 0x5d, 0xfc, 0x5c, 0x01, 0x9d, 0xfc, 0x00, 0x02, 0x42, 0x30, + 0x39, 0x21, 0xe2, 0x45, 0xb0, 0x0c, 0x51, 0xce, 0xdd, 0x32, 0x10, 0x00, + 0x42, 0x30, 0x1d, 0x19, 0xe2, 0x45, 0x90, 0x0c, 0x1b, 0xce, 0xa2, 0x41, + 0x10, 0x80, 0xf3, 0x0c, 0xd0, 0x30, 0x08, 0x06, 0xb0, 0x30, 0x70, 0x03, + 0x90, 0x0c, 0x42, 0x30, 0x19, 0x17, 0xc2, 0x45, 0x5d, 0xfa, 0x10, 0x00, + 0x06, 0xce, 0x50, 0xfc, 0xc4, 0x04, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, + 0x90, 0x0c, 0xbd, 0xce, 0x00, 0x0c, 0xfe, 0x45, 0x93, 0x0c, 0x5d, 0x30, + 0x58, 0x02, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x90, 0x0c, 0x81, 0xef, + 0x03, 0xef, 0x42, 0x30, 0x73, 0x1a, 0xc2, 0x45, 0xa0, 0x30, 0xc0, 0x00, + 0x03, 0xed, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x81, 0xef, 0x1a, 0xef, + 0xbd, 0x30, 0x58, 0x02, 0x42, 0x30, 0x05, 0x19, 0xe2, 0x45, 0x90, 0x0c, + 0x00, 0x94, 0xa3, 0xfd, 0x00, 0x0c, 0xfd, 0x14, 0x34, 0x02, 0xdd, 0xfc, + 0x68, 0x01, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xcc, 0x86, 0x42, 0x30, + 0x15, 0x1b, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x94, 0xdb, 0xfe, 0x5d, 0xfc, + 0x74, 0x02, 0x42, 0x50, 0x00, 0x20, 0xd6, 0xce, 0x5d, 0xf8, 0x74, 0x02, + 0x00, 0x85, 0xe8, 0xce, 0xb4, 0x34, 0x22, 0x00, 0x42, 0x30, 0x15, 0x18, + 0xe2, 0x45, 0x90, 0x0c, 0xe2, 0x40, 0x67, 0xfe, 0x53, 0xfc, 0x00, 0x00, + 0x22, 0x2d, 0xa2, 0x40, 0x62, 0xfe, 0xa4, 0x41, 0x08, 0x80, 0x84, 0xfc, + 0x54, 0x04, 0x53, 0xfc, 0x30, 0x07, 0x82, 0x00, 0x90, 0x13, 0x02, 0x94, + 0x58, 0xfe, 0xa2, 0x41, 0x10, 0x80, 0x04, 0xef, 0xb3, 0x30, 0x08, 0x07, + 0x42, 0x30, 0x83, 0x25, 0xe2, 0x45, 0x05, 0xee, 0x50, 0xce, 0x50, 0x14, + 0x4e, 0x07, 0x53, 0x14, 0xeb, 0x07, 0xa2, 0x40, 0x48, 0xfe, 0x50, 0xfc, + 0xa8, 0x04, 0x02, 0x94, 0x44, 0xfe, 0x01, 0xed, 0x53, 0x18, 0xeb, 0x07, + 0xa2, 0x41, 0x10, 0x80, 0xcc, 0x86, 0x42, 0x30, 0x4f, 0x1a, 0xe2, 0x45, + 0x00, 0x0c, 0x26, 0xce, 0x53, 0xfc, 0xfc, 0x06, 0x53, 0xf8, 0x00, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x90, 0xee, 0x42, 0x30, 0x55, 0x17, 0xe2, 0x45, + 0x93, 0x0c, 0x13, 0xce, 0xa2, 0x41, 0x10, 0x80, 0xf1, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0x18, 0x4d, 0xe7, 0xcb, 0xdd, 0x20, 0x28, 0x90, + 0x09, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0x62, 0x14, 0x2d, 0x4d, 0x01, 0xed, + 0x43, 0x94, 0x31, 0x00, 0xa3, 0x41, 0x09, 0x80, 0xc5, 0x60, 0x1f, 0x00, + 0xa3, 0x41, 0x09, 0x80, 0x43, 0xfc, 0x40, 0x4d, 0xe3, 0xfc, 0x44, 0x4d, + 0x85, 0x60, 0x1b, 0x00, 0xc5, 0x60, 0x1c, 0x10, 0xfa, 0x44, 0x85, 0x60, + 0x18, 0x10, 0x93, 0x8f, 0xa6, 0x0c, 0xa6, 0x41, 0x03, 0x00, 0x29, 0x05, + 0xc6, 0x30, 0xe0, 0x1c, 0xc2, 0x00, 0x90, 0x13, 0x10, 0xad, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0xe8, 0x4c, 0x28, 0x6b, 0x60, 0x6f, 0x28, 0xeb, + 0x27, 0x6b, 0x60, 0x6f, 0x27, 0xeb, 0xe7, 0x4b, 0x83, 0xf8, 0x40, 0x4d, + 0xa3, 0xf8, 0x44, 0x4d, 0x08, 0x47, 0x42, 0x30, 0xe8, 0x4c, 0x27, 0x6b, + 0x60, 0x6f, 0xf5, 0xcf, 0x27, 0xeb, 0x43, 0x14, 0x49, 0x4d, 0xa4, 0xc8, + 0x20, 0x6d, 0x43, 0x18, 0x49, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x65, 0xf9, 0xe2, 0x45, 0x00, 0x0c, 0xc4, 0xcf, 0xa4, 0x48, 0x00, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x05, 0x0f, 0xe5, 0xcb, + 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x82, 0x14, 0x24, 0x4d, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xf8, 0xa5, 0x8e, 0xee, 0x81, 0xed, + 0x64, 0xb4, 0x04, 0x00, 0xa2, 0x18, 0x16, 0x00, 0x02, 0x18, 0x12, 0x00, + 0xe5, 0x4b, 0x06, 0x47, 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x79, 0x0f, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x82, 0x14, 0x24, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x38, 0xa6, + 0x8e, 0xee, 0x81, 0xed, 0x64, 0xb4, 0x04, 0x00, 0xa2, 0x18, 0x16, 0x00, + 0x02, 0x18, 0x12, 0x00, 0xe5, 0x4b, 0x06, 0x47, 0x44, 0x60, 0x27, 0x00, + 0x65, 0xfc, 0x50, 0x02, 0x44, 0x60, 0x24, 0x10, 0x63, 0x14, 0x94, 0x00, + 0xa4, 0x41, 0x09, 0x80, 0x44, 0x18, 0x25, 0x4d, 0x9f, 0x45, 0x60, 0x00, + 0x90, 0x13, 0x00, 0x0c, 0xa2, 0x41, 0x02, 0xa5, 0x62, 0xfc, 0x8c, 0x28, + 0x60, 0x00, 0x0c, 0x38, 0x63, 0x50, 0x00, 0x04, 0x62, 0xf8, 0x8c, 0x28, + 0x62, 0xfc, 0x80, 0x28, 0xb1, 0x25, 0xc0, 0xe9, 0x62, 0xfc, 0x84, 0x28, + 0xb1, 0x25, 0xd0, 0xe9, 0x42, 0xfc, 0x88, 0x28, 0x21, 0x25, 0x9f, 0x45, + 0x60, 0xe9, 0x00, 0x0c, 0xe9, 0x4f, 0x80, 0x86, 0x9d, 0x20, 0x10, 0x90, + 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0xa2, 0x41, 0x02, 0xa5, 0x4a, 0x45, + 0x62, 0xfc, 0x8c, 0x28, 0xb0, 0x41, 0x01, 0x80, 0x10, 0x32, 0xbd, 0xa4, + 0x60, 0x00, 0x0c, 0x38, 0x63, 0x50, 0x00, 0x04, 0x62, 0xf8, 0x8c, 0x28, + 0x62, 0xfc, 0x80, 0x28, 0x91, 0x6e, 0x09, 0x6e, 0xb1, 0x25, 0x68, 0xc8, + 0x62, 0xfc, 0x84, 0x28, 0x03, 0xef, 0xb1, 0x25, 0x67, 0xc8, 0x42, 0xfc, + 0x88, 0x28, 0x21, 0x25, 0xd0, 0x45, 0x5d, 0xf8, 0x18, 0x00, 0x8f, 0x6e, + 0x9d, 0x30, 0x13, 0x00, 0xf0, 0x45, 0x03, 0xef, 0x02, 0xef, 0x8d, 0x6e, + 0xd0, 0x45, 0x9d, 0x30, 0x16, 0x00, 0x0a, 0x45, 0x5d, 0x20, 0x10, 0x10, + 0x0c, 0x47, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x64, 0x45, + 0xa0, 0x30, 0xd0, 0x00, 0x44, 0x0e, 0x42, 0x30, 0x51, 0x1e, 0xe2, 0x45, + 0x12, 0xee, 0x02, 0x0e, 0xa2, 0x41, 0x09, 0x80, 0x22, 0xfe, 0x18, 0x4d, + 0x80, 0x30, 0xd8, 0xff, 0x05, 0x09, 0x71, 0x14, 0x18, 0x00, 0x01, 0x8a, + 0x83, 0x0a, 0x80, 0x89, 0x8f, 0xed, 0x82, 0x89, 0x84, 0x09, 0x11, 0x0a, + 0x20, 0x25, 0xd3, 0x44, 0x62, 0x50, 0x01, 0x00, 0x44, 0x25, 0xd5, 0x44, + 0x31, 0x26, 0x84, 0x89, 0x05, 0x8a, 0x03, 0x89, 0x51, 0x60, 0x05, 0x00, + 0x51, 0x60, 0x02, 0x10, 0x22, 0x25, 0xd3, 0x44, 0x2f, 0x2d, 0xa1, 0x25, + 0x04, 0x89, 0x85, 0x89, 0x96, 0x09, 0xe3, 0x40, 0x05, 0x00, 0x42, 0x50, + 0x10, 0x00, 0xa1, 0x25, 0x04, 0x89, 0x85, 0x89, 0x97, 0x09, 0xe3, 0x40, + 0x06, 0x00, 0x42, 0x50, 0x20, 0x00, 0x62, 0x00, 0x2c, 0x7a, 0x04, 0x89, + 0x85, 0x89, 0x98, 0x09, 0xe3, 0x40, 0x06, 0x00, 0x42, 0x50, 0x40, 0x00, + 0x62, 0x00, 0x2c, 0x7a, 0x04, 0x89, 0x85, 0x89, 0x90, 0x09, 0xbe, 0x25, + 0xd3, 0x44, 0x42, 0x00, 0x3c, 0x3b, 0xaf, 0x2d, 0x31, 0x26, 0x05, 0x8a, + 0x84, 0x89, 0x99, 0x09, 0x63, 0x00, 0x00, 0x50, 0xd3, 0x44, 0x2f, 0x2d, + 0xa1, 0x25, 0x04, 0x89, 0x85, 0x89, 0x1b, 0x09, 0x9a, 0x09, 0x20, 0x25, + 0xd3, 0x44, 0xa1, 0x25, 0x0f, 0x89, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xf9, 0xf8, 0xc2, 0x45, 0x70, 0x18, 0x10, 0x00, 0xa4, 0x41, 0x06, 0x00, + 0x84, 0x30, 0x80, 0x1a, 0x44, 0x06, 0x90, 0x60, 0x09, 0x80, 0x44, 0x00, + 0x90, 0x13, 0x90, 0x60, 0x06, 0x90, 0xb4, 0x05, 0x70, 0x60, 0x0d, 0x80, + 0x70, 0x60, 0x0a, 0x90, 0x51, 0x60, 0x17, 0x00, 0x60, 0x50, 0x01, 0xff, + 0x51, 0x60, 0x14, 0x10, 0x62, 0x00, 0x90, 0x1b, 0xa3, 0x40, 0x26, 0x00, + 0x83, 0x09, 0x42, 0x30, 0x00, 0x02, 0x42, 0x00, 0x40, 0x50, 0x63, 0x50, + 0x20, 0x00, 0x83, 0x89, 0x0e, 0x89, 0xa2, 0x41, 0x10, 0x80, 0xca, 0x86, + 0x42, 0x30, 0x61, 0x1a, 0xc2, 0x45, 0x10, 0x18, 0x11, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x62, 0xfc, 0x54, 0x04, 0xb9, 0x41, 0x10, 0x80, 0xa2, 0x41, + 0x09, 0x80, 0x62, 0xf8, 0x28, 0x4d, 0x90, 0x0c, 0x81, 0xed, 0xa2, 0x41, + 0x09, 0x80, 0x39, 0x33, 0x3f, 0x1e, 0x62, 0x18, 0x2c, 0x4d, 0x24, 0x45, + 0x99, 0x45, 0x11, 0x4c, 0x42, 0x30, 0x80, 0x00, 0x21, 0x25, 0xdf, 0xcf, + 0x0e, 0x89, 0x00, 0x0c, 0x45, 0x14, 0x14, 0x06, 0xe2, 0x40, 0x53, 0x00, + 0xa3, 0x41, 0x09, 0x80, 0x43, 0x14, 0x2d, 0x4d, 0xa2, 0x40, 0x4d, 0x00, + 0x45, 0xfc, 0x24, 0x01, 0x42, 0x14, 0x94, 0x00, 0xa2, 0x40, 0x47, 0x00, + 0xed, 0x4f, 0x57, 0x45, 0x44, 0x60, 0x3b, 0x00, 0x24, 0x0e, 0x44, 0x60, + 0x38, 0x10, 0x42, 0xb0, 0xe8, 0x03, 0x3f, 0xad, 0x05, 0x0e, 0x01, 0xed, + 0x43, 0x18, 0x2d, 0x4d, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, 0xd0, 0x00, + 0x42, 0x30, 0x51, 0x1e, 0xe2, 0x45, 0x1a, 0xee, 0xa3, 0x41, 0x09, 0x80, + 0x82, 0x0c, 0x43, 0xf8, 0x18, 0x4d, 0xa2, 0x41, 0x01, 0x80, 0x1a, 0xef, + 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0xb1, 0x30, 0x24, 0x00, 0x50, 0xfc, + 0x9c, 0x04, 0x2e, 0x8d, 0x40, 0x0c, 0x50, 0xfc, 0x24, 0x01, 0x62, 0xfc, + 0xfc, 0x06, 0xe3, 0x40, 0x26, 0x00, 0x22, 0x69, 0x82, 0x40, 0x23, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x15, 0x18, 0xc2, 0x45, 0x90, 0x30, + 0xf4, 0xff, 0x1c, 0x8d, 0x40, 0x0c, 0x02, 0x6a, 0xf0, 0xfc, 0xcc, 0x00, + 0xb0, 0xfc, 0x20, 0x01, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xdd, 0x45, + 0xe2, 0x45, 0xc0, 0x0c, 0x0e, 0xcc, 0x10, 0x18, 0x3f, 0x00, 0x9f, 0x45, + 0x40, 0x0c, 0x03, 0xed, 0x02, 0x6a, 0x44, 0xc8, 0xa2, 0x41, 0x09, 0x80, + 0x00, 0x85, 0x42, 0x30, 0x51, 0xfd, 0xe2, 0x45, 0xa0, 0x0c, 0x40, 0x0c, + 0x17, 0x45, 0x0a, 0x47, 0xdd, 0x4f, 0xdd, 0x22, 0x2c, 0xd0, 0x05, 0xfe, + 0x70, 0x00, 0x84, 0x0e, 0xc5, 0x68, 0x50, 0x16, 0x1d, 0x00, 0x90, 0x14, + 0x28, 0x00, 0xb0, 0x30, 0x1a, 0x00, 0x52, 0x02, 0x6c, 0x01, 0xd0, 0x30, + 0x1e, 0x00, 0x12, 0x94, 0x06, 0x00, 0x64, 0x02, 0x00, 0x40, 0x40, 0x32, + 0x02, 0x00, 0x64, 0x02, 0x00, 0x50, 0xa2, 0x41, 0x09, 0x80, 0xe2, 0x87, + 0x42, 0x30, 0x51, 0xfd, 0xc2, 0x45, 0x1d, 0xf8, 0x10, 0x00, 0x50, 0x14, + 0x1f, 0x00, 0x90, 0x14, 0x1e, 0x00, 0x87, 0xed, 0x20, 0x25, 0xd4, 0x44, + 0x82, 0x00, 0x6c, 0x10, 0x64, 0x94, 0x7e, 0x00, 0x72, 0x50, 0x01, 0x00, + 0x2c, 0x2e, 0xbd, 0x2d, 0xe2, 0x00, 0xac, 0x22, 0x83, 0x00, 0x18, 0x90, + 0xa2, 0x02, 0xec, 0x11, 0x85, 0x8f, 0x01, 0xee, 0xfe, 0x6d, 0x02, 0xee, + 0x83, 0x00, 0x10, 0x20, 0x70, 0x14, 0x2a, 0x00, 0xb0, 0x14, 0x29, 0x00, + 0xb0, 0x25, 0xdd, 0x44, 0x83, 0x00, 0x10, 0x22, 0xa5, 0x41, 0x09, 0x80, + 0xc5, 0x14, 0x35, 0x4d, 0xb2, 0x50, 0x04, 0x00, 0xdd, 0x2e, 0x93, 0x00, + 0x90, 0x23, 0x28, 0xae, 0xc5, 0x00, 0x18, 0x90, 0xa2, 0x41, 0x10, 0x80, + 0xb5, 0x0c, 0x42, 0x30, 0xe9, 0x19, 0xe2, 0x45, 0x94, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x01, 0xef, 0xb5, 0x0c, 0x42, 0x30, 0xe3, 0x1f, 0xe2, 0x45, + 0x91, 0x0c, 0xb0, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x90, 0xfc, + 0x18, 0x4d, 0x02, 0x18, 0x2d, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, + 0x2c, 0x4d, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3f, 0x1e, 0xe2, 0x45, + 0x00, 0x0c, 0x10, 0xf8, 0x18, 0x4d, 0xdd, 0x22, 0x2c, 0x50, 0x12, 0x47, + 0x42, 0x00, 0x2c, 0x01, 0x90, 0x14, 0x1d, 0x00, 0x49, 0xc8, 0x50, 0x14, + 0x28, 0x00, 0xd5, 0x0c, 0xb2, 0x0c, 0x48, 0xc8, 0x50, 0x60, 0x27, 0x00, + 0x10, 0x61, 0x23, 0x00, 0x84, 0x00, 0xac, 0x08, 0x50, 0x60, 0x24, 0x10, + 0x10, 0x61, 0x20, 0x10, 0x64, 0xc8, 0x47, 0xc8, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0x91, 0xef, 0xc2, 0x45, 0x1d, 0xf9, 0x18, 0x00, 0xb0, 0x41, + 0x09, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x90, 0xfc, 0x18, 0x4d, 0x02, 0x18, + 0x2d, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x2c, 0x4d, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x3f, 0x1e, 0xe2, 0x45, 0x00, 0x0c, 0x10, 0xf8, + 0x18, 0x4d, 0xdd, 0x22, 0x2c, 0x50, 0x12, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0x16, 0x25, 0x4d, 0x01, 0xed, 0x50, 0xb4, 0xae, 0xff, 0xa2, 0x41, + 0x01, 0x80, 0x94, 0xfc, 0x14, 0x00, 0xf4, 0xfc, 0xd8, 0x00, 0xb4, 0xfc, + 0x2c, 0x01, 0x42, 0x30, 0xdd, 0x45, 0xe2, 0x45, 0x01, 0xef, 0xa1, 0xcf, + 0x14, 0x1a, 0x4b, 0x00, 0xf1, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x35, 0x61, 0x55, 0x45, 0xe2, 0x45, 0x25, 0x0e, 0xa2, 0x41, 0x09, 0x80, + 0x02, 0x16, 0x25, 0x4d, 0x01, 0xed, 0x50, 0x94, 0x03, 0x00, 0x40, 0x0c, + 0x15, 0x45, 0x08, 0x47, 0x12, 0x6a, 0xf1, 0xfc, 0xcc, 0x00, 0xb1, 0xfc, + 0x20, 0x01, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xdd, 0x45, 0xe2, 0x45, + 0x01, 0xef, 0x11, 0x1a, 0x3f, 0x00, 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, + 0xe5, 0x4f, 0x3e, 0xed, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xdd, 0x22, + 0x1c, 0xd0, 0x42, 0x30, 0xb7, 0x24, 0xa4, 0x0e, 0x85, 0x0e, 0x01, 0xee, + 0x89, 0x6e, 0x47, 0x0e, 0x26, 0x0e, 0xc2, 0x45, 0x7d, 0x16, 0x48, 0x00, + 0x02, 0x0e, 0x82, 0x0c, 0xa2, 0x41, 0x01, 0x80, 0x3e, 0xef, 0x42, 0x30, + 0x51, 0xa8, 0xe2, 0x45, 0xa0, 0x0c, 0x40, 0x30, 0x26, 0x01, 0x50, 0x60, + 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x6d, 0x14, 0xe2, 0x45, 0x95, 0x0c, 0x50, 0x60, 0x1b, 0x80, 0x13, 0xb4, + 0x77, 0x00, 0x50, 0x60, 0x18, 0x90, 0x54, 0x14, 0x00, 0x00, 0x50, 0x18, + 0x3c, 0x00, 0x11, 0x09, 0x90, 0x09, 0x20, 0x25, 0xd3, 0x44, 0x42, 0x00, + 0xec, 0x11, 0x50, 0x18, 0x24, 0x00, 0x54, 0x14, 0x03, 0x00, 0x42, 0x00, + 0xac, 0x08, 0x50, 0x18, 0x25, 0x00, 0x10, 0x09, 0x42, 0x00, 0x6c, 0x10, + 0x50, 0x60, 0x29, 0x80, 0x50, 0x60, 0x26, 0x90, 0x11, 0x09, 0x90, 0x09, + 0x20, 0x25, 0xd3, 0x44, 0xa8, 0x2d, 0x89, 0x8d, 0xaa, 0x2d, 0x01, 0xed, + 0x50, 0x18, 0x2a, 0x00, 0x11, 0x09, 0x90, 0x09, 0x20, 0x25, 0xd3, 0x44, + 0xaa, 0x2d, 0x89, 0x8d, 0xac, 0x2d, 0x01, 0xed, 0x50, 0x18, 0x2b, 0x00, + 0x11, 0x09, 0x90, 0x09, 0x20, 0x25, 0xd3, 0x44, 0xac, 0x2d, 0xa3, 0x40, + 0x39, 0x00, 0x42, 0x00, 0xac, 0x22, 0x50, 0x18, 0x2d, 0x00, 0x1c, 0x09, + 0x9b, 0x09, 0xa4, 0x41, 0x09, 0x80, 0x20, 0x25, 0xd3, 0x44, 0xa1, 0x25, + 0x50, 0x18, 0x2e, 0x00, 0x70, 0x18, 0x2f, 0x00, 0x71, 0x60, 0x05, 0x00, + 0x51, 0x60, 0x09, 0x00, 0xb0, 0x30, 0x24, 0x00, 0x71, 0x60, 0x02, 0x10, + 0x51, 0x60, 0x06, 0x10, 0x1a, 0xef, 0x70, 0x60, 0x33, 0x80, 0x70, 0x60, + 0x30, 0x90, 0x50, 0x60, 0x37, 0x80, 0x50, 0x60, 0x34, 0x90, 0x50, 0x62, + 0x3b, 0x80, 0xa2, 0x41, 0x01, 0x80, 0x50, 0x62, 0x38, 0x90, 0x84, 0x30, + 0x54, 0x4c, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x10, 0x18, 0x3d, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x90, 0x0c, 0x42, 0x30, 0x19, 0x1d, 0xe2, 0x45, + 0xbe, 0xee, 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, 0x01, 0xed, 0x50, 0x18, + 0x2c, 0x00, 0x11, 0x09, 0x90, 0x09, 0x20, 0x25, 0xc0, 0xcf, 0xd3, 0x44, + 0xa2, 0x41, 0x10, 0x80, 0x70, 0x1a, 0x3d, 0x00, 0x90, 0x0c, 0x42, 0x30, + 0x19, 0x1d, 0xe2, 0x45, 0xbe, 0xee, 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, + 0xc5, 0x4f, 0x3d, 0x23, 0x50, 0xd0, 0x45, 0x62, 0x49, 0x00, 0x11, 0x6d, + 0x24, 0x0e, 0x45, 0x62, 0x46, 0x10, 0x48, 0xc8, 0x49, 0xc8, 0x17, 0x6d, + 0x4b, 0xc8, 0x4c, 0xc8, 0x44, 0x30, 0xb8, 0x00, 0x62, 0x0e, 0x4f, 0xc8, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xa7, 0x25, 0x05, 0x0e, 0xdd, 0x20, + 0x80, 0x90, 0x1d, 0x38, 0x28, 0x00, 0xc2, 0x45, 0x1d, 0x38, 0x34, 0x00, + 0x52, 0x00, 0x00, 0x18, 0x93, 0x0c, 0x50, 0xc8, 0x62, 0x0e, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0xf1, 0x4b, 0xe2, 0x45, 0xff, 0xee, 0x53, 0x02, + 0x50, 0x41, 0x08, 0x01, 0x00, 0x10, 0x48, 0x02, 0x50, 0x41, 0x08, 0x01, + 0x00, 0x10, 0x11, 0x01, 0x50, 0x51, 0x4a, 0xfc, 0x98, 0x03, 0x29, 0x8d, + 0x08, 0x31, 0x9c, 0x03, 0x50, 0x30, 0x50, 0x00, 0xb3, 0x41, 0x10, 0x80, + 0xb0, 0x32, 0x4a, 0x00, 0x11, 0x01, 0x50, 0xa1, 0xd0, 0x32, 0x15, 0x00, + 0xc0, 0x0f, 0x73, 0x32, 0xcb, 0x1c, 0xea, 0x0e, 0x4e, 0xc8, 0x4e, 0x48, + 0x94, 0xfc, 0x00, 0x00, 0xf6, 0x14, 0x20, 0x00, 0xd6, 0x14, 0x10, 0x00, + 0xb6, 0x14, 0x00, 0x00, 0x3e, 0xd1, 0xff, 0x00, 0x24, 0xc9, 0xa5, 0xca, + 0xd3, 0x45, 0x5d, 0xf8, 0x18, 0x00, 0x97, 0xfc, 0x98, 0x03, 0xc2, 0x4f, + 0xc2, 0x4e, 0x9e, 0x00, 0x90, 0x23, 0x69, 0xae, 0x88, 0x4e, 0x50, 0x48, + 0x42, 0x02, 0x50, 0x11, 0x24, 0x25, 0x42, 0x02, 0x50, 0x11, 0x24, 0x25, + 0xa2, 0x05, 0x83, 0x34, 0x54, 0x03, 0x1e, 0x8e, 0x03, 0xf8, 0x98, 0x03, + 0x83, 0xfc, 0x4c, 0x03, 0x42, 0x30, 0x4c, 0x03, 0x22, 0x05, 0x82, 0x94, + 0x15, 0x00, 0xcc, 0x48, 0xa3, 0xfc, 0x50, 0x03, 0x41, 0xeb, 0x60, 0xea, + 0x17, 0x6e, 0x50, 0xea, 0x83, 0x34, 0x54, 0x03, 0xdd, 0x34, 0x34, 0x00, + 0x43, 0xf8, 0x50, 0x03, 0x43, 0xf8, 0x4c, 0x03, 0x68, 0x06, 0xac, 0xc8, + 0x03, 0x38, 0x54, 0x03, 0x9d, 0x38, 0x34, 0x00, 0x52, 0xb0, 0x0a, 0x00, + 0xe2, 0x40, 0x62, 0x01, 0xf0, 0x16, 0x45, 0x00, 0xb7, 0x0e, 0xb4, 0x41, + 0x10, 0x80, 0x09, 0xcc, 0x94, 0x32, 0x13, 0x23, 0xfe, 0x4e, 0xb7, 0x02, + 0x50, 0x13, 0x02, 0xb4, 0x3e, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x52, 0x87, + 0xf4, 0x45, 0xb7, 0x0c, 0x75, 0x8d, 0x62, 0x0e, 0x5d, 0xfc, 0x80, 0x00, + 0x77, 0xd0, 0xff, 0x00, 0xa0, 0x89, 0x50, 0x14, 0x45, 0x00, 0x43, 0x94, + 0x34, 0x01, 0x24, 0x25, 0x22, 0x05, 0x62, 0xfc, 0xc8, 0x00, 0x8f, 0x48, + 0xbe, 0x6d, 0x62, 0xf8, 0xc8, 0x00, 0x5d, 0xfc, 0x80, 0x00, 0x20, 0x09, + 0x24, 0x25, 0x22, 0x05, 0x62, 0xfc, 0xc8, 0x00, 0xb0, 0x6d, 0x62, 0xf8, + 0xc8, 0x00, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xf9, 0x4b, 0xe2, 0x45, + 0x00, 0x0c, 0x99, 0x69, 0x01, 0xed, 0x43, 0xb4, 0x26, 0x01, 0x53, 0x0c, + 0x5d, 0x34, 0x34, 0x00, 0x02, 0x94, 0x20, 0x01, 0xab, 0x4a, 0x97, 0x6d, + 0x75, 0x94, 0xe8, 0x00, 0x75, 0x30, 0x14, 0x00, 0x6f, 0xc8, 0xa3, 0x41, + 0x10, 0x80, 0x63, 0x30, 0x73, 0x1d, 0x72, 0xc8, 0xa3, 0x41, 0x10, 0x80, + 0x63, 0x30, 0x41, 0x13, 0x6e, 0xc8, 0xa3, 0x41, 0x10, 0x80, 0x63, 0x30, + 0x99, 0x24, 0x70, 0xc8, 0xa3, 0x41, 0x10, 0x80, 0xb4, 0x41, 0x10, 0x80, + 0x63, 0x30, 0xcd, 0x23, 0x40, 0x0e, 0x94, 0x32, 0xaf, 0x23, 0xf5, 0xfe, + 0x00, 0x00, 0x71, 0xcc, 0x71, 0xc8, 0x95, 0x6b, 0x80, 0x0c, 0x40, 0x31, + 0x02, 0x00, 0x44, 0x30, 0xd2, 0x02, 0xc4, 0x00, 0x10, 0x28, 0x24, 0x25, + 0xaf, 0x44, 0xb2, 0x8e, 0x22, 0x05, 0xa1, 0x6a, 0xd6, 0x15, 0x0a, 0x00, + 0x76, 0x15, 0x0b, 0x00, 0x85, 0x15, 0x49, 0x01, 0x45, 0x14, 0x48, 0x01, + 0x25, 0x17, 0x4a, 0x01, 0xf6, 0x15, 0x0c, 0x00, 0x05, 0x17, 0x4b, 0x01, + 0xb6, 0x15, 0x0d, 0x00, 0x8b, 0x01, 0x10, 0x5b, 0x4e, 0x00, 0x10, 0x13, + 0x96, 0x15, 0x0e, 0x00, 0xc5, 0x15, 0x4c, 0x01, 0x62, 0x01, 0x90, 0x12, + 0x2f, 0x03, 0x10, 0x7b, 0x76, 0x15, 0x0f, 0x00, 0xa5, 0x14, 0x4d, 0x01, + 0xe2, 0x01, 0x90, 0x12, 0x0d, 0x03, 0x10, 0x6b, 0xa2, 0x01, 0x90, 0x12, + 0xcc, 0x01, 0x10, 0x63, 0x82, 0x01, 0x90, 0x12, 0xab, 0x00, 0x10, 0x2b, + 0xd5, 0x44, 0x2d, 0x2d, 0xe2, 0x40, 0x05, 0x00, 0x40, 0x6e, 0x44, 0xb5, + 0xc6, 0xff, 0x44, 0x30, 0xd2, 0x02, 0x51, 0xfc, 0x0c, 0x0b, 0x20, 0x69, + 0x44, 0x00, 0x50, 0x13, 0x0a, 0x8d, 0x5d, 0xfc, 0x84, 0x00, 0x81, 0xed, + 0x64, 0x00, 0x10, 0x20, 0x20, 0x69, 0xe2, 0x44, 0x5d, 0xfc, 0x84, 0x00, + 0x20, 0xea, 0x50, 0x02, 0x50, 0x11, 0x42, 0x14, 0x15, 0x00, 0x81, 0xed, + 0x42, 0xd0, 0xf7, 0x00, 0x62, 0x94, 0x65, 0x00, 0x4f, 0x48, 0x1a, 0x85, + 0xb0, 0x0c, 0x44, 0xc8, 0x50, 0x48, 0x95, 0x0c, 0xe2, 0x45, 0x42, 0x4e, + 0x51, 0x48, 0xb5, 0x0c, 0xe2, 0x45, 0x11, 0x6e, 0x17, 0x6d, 0x57, 0x94, + 0x5f, 0x00, 0x77, 0xfc, 0x00, 0x00, 0x5d, 0x34, 0x34, 0x00, 0xb7, 0x0e, + 0xe3, 0x0e, 0x2e, 0x6d, 0x5d, 0x38, 0x34, 0x00, 0x75, 0xfc, 0x00, 0x00, + 0x55, 0xfc, 0x04, 0x00, 0x15, 0xf8, 0x00, 0x00, 0x15, 0xf8, 0x04, 0x00, + 0x31, 0xe9, 0xa0, 0xe9, 0x50, 0x60, 0x49, 0x00, 0x95, 0x0c, 0x50, 0x60, + 0x46, 0x10, 0x62, 0x0c, 0x26, 0x25, 0x34, 0x05, 0x24, 0x25, 0x34, 0x05, + 0x24, 0x25, 0x22, 0x05, 0xd4, 0x45, 0xa2, 0xfc, 0x58, 0x03, 0xd5, 0xfe, + 0x70, 0x00, 0x80, 0x30, 0x88, 0x00, 0x56, 0x34, 0x00, 0x00, 0xa2, 0xd0, + 0x8c, 0x00, 0x85, 0x94, 0x6f, 0x00, 0x82, 0xee, 0x42, 0xd0, 0xfc, 0x00, + 0x80, 0x30, 0x80, 0x00, 0x82, 0xb4, 0x63, 0xff, 0x01, 0xef, 0x50, 0x02, + 0x50, 0x11, 0x42, 0x14, 0x15, 0x00, 0x85, 0xed, 0x62, 0x94, 0x82, 0x00, + 0x00, 0x0c, 0x03, 0xad, 0x01, 0xed, 0x51, 0x18, 0xb1, 0x0c, 0xd5, 0xfe, + 0x2c, 0x00, 0x15, 0x69, 0xb6, 0xfc, 0x04, 0x02, 0x21, 0x2e, 0x07, 0x8e, + 0xc5, 0x17, 0x26, 0x00, 0x91, 0xfc, 0x4c, 0x0b, 0xc4, 0x96, 0x7d, 0x00, + 0x01, 0xee, 0x22, 0x2d, 0x07, 0x8d, 0x4e, 0x48, 0x51, 0xfc, 0x50, 0x0b, + 0x56, 0x94, 0x6b, 0x00, 0x01, 0xed, 0x4e, 0x48, 0x95, 0x0c, 0xe2, 0x45, + 0x42, 0x4e, 0x17, 0x6d, 0x57, 0xb4, 0xa5, 0xff, 0x77, 0xfc, 0x00, 0x00, + 0xb4, 0x41, 0x10, 0x80, 0xb5, 0x41, 0x04, 0x80, 0xa2, 0x41, 0x10, 0x80, + 0x94, 0x32, 0xa3, 0x23, 0xb5, 0x32, 0x19, 0x02, 0xc2, 0x32, 0xe7, 0x1b, + 0xf4, 0x45, 0x11, 0x6e, 0x42, 0x0e, 0xd2, 0x87, 0x24, 0x8d, 0x53, 0x0c, + 0xd0, 0x60, 0x49, 0x00, 0xb0, 0x14, 0x45, 0x00, 0xd5, 0x45, 0xd0, 0x60, + 0x46, 0x10, 0xe2, 0x40, 0xf1, 0xff, 0x91, 0xfc, 0x74, 0x0b, 0xf6, 0x45, + 0xb2, 0x0c, 0xec, 0xcf, 0x00, 0x0c, 0xd2, 0x86, 0x42, 0x30, 0x37, 0x14, + 0xc2, 0x45, 0xd0, 0x14, 0x45, 0x00, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, + 0xf9, 0x4b, 0xc2, 0x45, 0x9d, 0xfc, 0x3c, 0x00, 0x99, 0x69, 0x01, 0xed, + 0x43, 0x94, 0xe0, 0xfe, 0x5d, 0x34, 0x34, 0x00, 0x53, 0x0c, 0x3d, 0x23, + 0x50, 0x50, 0x1e, 0x47, 0xa0, 0x0e, 0x9f, 0xce, 0xe0, 0x32, 0x03, 0x00, + 0x91, 0xfc, 0x4c, 0x0b, 0x40, 0x6b, 0xa6, 0xb4, 0x8d, 0xff, 0x00, 0x0c, + 0xa4, 0x14, 0x1c, 0x00, 0x01, 0xee, 0x85, 0xb4, 0x87, 0xff, 0xb6, 0x30, + 0x18, 0x00, 0x42, 0xd0, 0x00, 0x03, 0xd1, 0xfc, 0x74, 0x0b, 0x42, 0x70, + 0x00, 0x03, 0x96, 0x30, 0x1e, 0x00, 0x45, 0x00, 0x18, 0x20, 0xc0, 0x0a, + 0x52, 0x48, 0xe6, 0x14, 0x94, 0x00, 0xd7, 0x2e, 0x95, 0x0c, 0xe2, 0x45, + 0x01, 0xef, 0x72, 0xcf, 0x56, 0x34, 0x00, 0x00, 0x82, 0xcf, 0x11, 0x18, + 0xb1, 0x0c, 0x5e, 0xb4, 0x94, 0xff, 0x00, 0x0c, 0x56, 0xfc, 0x98, 0x01, + 0xc2, 0x45, 0x96, 0xfc, 0x9c, 0x01, 0x8e, 0xcf, 0x4e, 0x48, 0x9e, 0xb4, + 0x82, 0xff, 0x00, 0x0c, 0x56, 0xfc, 0x98, 0x01, 0xc2, 0x45, 0x96, 0xfc, + 0x9c, 0x01, 0x7b, 0xcf, 0x15, 0x69, 0x00, 0x0c, 0xe5, 0x4f, 0xa7, 0x41, + 0x09, 0x80, 0x47, 0x14, 0x2c, 0x4d, 0xdd, 0x22, 0x1c, 0xd0, 0x04, 0x0e, + 0x25, 0x0e, 0x18, 0x8d, 0x46, 0x0e, 0xa2, 0x41, 0x08, 0x80, 0xa3, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0x54, 0x04, 0x63, 0xfc, 0x28, 0x4d, 0xb5, 0x05, + 0x62, 0x00, 0x90, 0x13, 0x15, 0x8d, 0x63, 0xb0, 0x65, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x82, 0x14, 0x49, 0x4d, 0x83, 0xed, 0x64, 0x94, 0x12, 0x00, + 0xb5, 0x41, 0x09, 0x80, 0xb9, 0x41, 0x04, 0x80, 0x52, 0x84, 0x90, 0x0c, + 0x39, 0x33, 0x1d, 0x8c, 0xdd, 0x22, 0x1c, 0x50, 0x99, 0x45, 0x1d, 0x4c, + 0xee, 0x8d, 0xa2, 0x41, 0x09, 0x80, 0xf4, 0xcf, 0xb9, 0x41, 0x04, 0x80, + 0x95, 0xfc, 0x18, 0x4d, 0x02, 0x18, 0x49, 0x4d, 0x70, 0xfe, 0x0c, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x02, 0x18, 0x2d, 0x4d, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x3f, 0x1e, 0xc2, 0x45, 0x07, 0x18, 0x2c, 0x4d, 0x93, 0xfc, + 0x14, 0x00, 0x80, 0x32, 0x01, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x51, 0xfd, 0x00, 0x85, 0xa0, 0x0c, 0x84, 0xca, 0xc2, 0x45, 0x15, 0xf8, + 0x18, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x16, 0x25, 0x4d, 0x95, 0xb6, + 0xcd, 0xff, 0xb9, 0x41, 0x04, 0x80, 0x93, 0xfc, 0x14, 0x00, 0xf3, 0xfc, + 0xd8, 0x00, 0xb3, 0xfc, 0x2c, 0x01, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0xdd, 0x45, 0xe2, 0x45, 0x01, 0xef, 0xbc, 0xcf, 0xb3, 0x1a, 0x4b, 0x00, + 0xe9, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0xdd, 0x22, 0x14, 0xd0, 0x42, 0x30, + 0x55, 0x14, 0x04, 0x0e, 0x22, 0xee, 0xa5, 0x0e, 0x86, 0x0e, 0x32, 0x4a, + 0x70, 0x4a, 0xc2, 0x45, 0x5d, 0xfe, 0x44, 0x00, 0x50, 0x60, 0x0b, 0x80, + 0x50, 0x60, 0x08, 0x90, 0xb0, 0x62, 0x03, 0x80, 0xb0, 0x62, 0x00, 0x90, + 0x90, 0x62, 0x07, 0x80, 0x90, 0x62, 0x04, 0x90, 0x53, 0xfc, 0x88, 0x00, + 0xd8, 0x86, 0x50, 0x60, 0x2b, 0x80, 0x50, 0x60, 0x28, 0x90, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x85, 0xbc, 0xe2, 0x45, 0x00, 0x0c, 0x51, 0x34, + 0x78, 0x00, 0x91, 0x34, 0x7a, 0x00, 0x71, 0x34, 0x7c, 0x00, 0xd4, 0x44, + 0xd3, 0x44, 0x2f, 0x2d, 0x02, 0xb4, 0xde, 0x00, 0x06, 0xef, 0x51, 0xfc, + 0x58, 0x00, 0xe2, 0x40, 0x0a, 0x00, 0x50, 0x60, 0x3b, 0x00, 0x50, 0x60, + 0x38, 0x10, 0x42, 0x50, 0x00, 0x01, 0x50, 0x60, 0x3b, 0x80, 0x50, 0x60, + 0x38, 0x90, 0x51, 0xfc, 0x50, 0x00, 0xe2, 0x40, 0x18, 0x00, 0x70, 0x60, + 0x27, 0x00, 0x70, 0x60, 0x24, 0x10, 0x83, 0x50, 0x02, 0x00, 0x90, 0x60, + 0x27, 0x80, 0x90, 0x60, 0x24, 0x90, 0xa0, 0x6a, 0x21, 0x6a, 0xb0, 0x60, + 0x43, 0x80, 0xb0, 0x60, 0x40, 0x90, 0x90, 0x60, 0x47, 0x80, 0x90, 0x60, + 0x44, 0x90, 0x24, 0x6a, 0x04, 0xb4, 0xc9, 0x00, 0xac, 0x6e, 0xb1, 0xfc, + 0x54, 0x00, 0xe5, 0x40, 0x03, 0x00, 0x55, 0x69, 0xa2, 0x40, 0x75, 0x00, + 0x51, 0x34, 0x70, 0x00, 0xe2, 0x40, 0x11, 0x00, 0x50, 0x60, 0x27, 0x00, + 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, 0x20, 0x00, 0x50, 0x60, 0x27, 0x80, + 0x50, 0x60, 0x24, 0x90, 0x51, 0x34, 0x70, 0x00, 0xa1, 0x25, 0x50, 0x18, + 0x50, 0x00, 0x70, 0x18, 0x51, 0x00, 0x71, 0x34, 0x72, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, 0x31, 0x26, 0x90, 0x18, 0x53, 0x00, + 0x70, 0x18, 0x52, 0x00, 0x71, 0xfc, 0x48, 0x00, 0x01, 0xee, 0xb1, 0x69, + 0x70, 0x60, 0x2f, 0x80, 0x70, 0x60, 0x2c, 0x90, 0x71, 0xfc, 0x4c, 0x00, + 0x70, 0x60, 0x33, 0x80, 0x70, 0x60, 0x30, 0x90, 0x9a, 0x69, 0x35, 0x05, + 0x50, 0x60, 0x37, 0x80, 0x50, 0x60, 0x34, 0x90, 0x53, 0xfc, 0x5c, 0x01, + 0x82, 0x94, 0x70, 0x00, 0x00, 0x0c, 0x82, 0xed, 0x62, 0xb4, 0x15, 0x00, + 0x83, 0xed, 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, + 0x40, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, 0x70, 0x60, + 0x57, 0x80, 0x70, 0x60, 0x54, 0x90, 0x51, 0xfc, 0x6c, 0x00, 0x50, 0x60, + 0x5b, 0x80, 0x50, 0x60, 0x58, 0x90, 0x52, 0xfc, 0x0c, 0x00, 0x82, 0xed, + 0x62, 0x94, 0x07, 0x00, 0x88, 0xed, 0x62, 0x94, 0x04, 0x00, 0x40, 0x0c, + 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0x52, 0xfc, 0x98, 0x00, 0x51, 0xb4, + 0xf9, 0xff, 0x40, 0x0c, 0x50, 0x60, 0x27, 0x00, 0x81, 0xed, 0x50, 0x60, + 0x24, 0x10, 0x42, 0x50, 0x80, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, + 0x24, 0x90, 0x70, 0x60, 0x3f, 0x80, 0x70, 0x60, 0x3c, 0x90, 0x40, 0x0c, + 0xdd, 0x22, 0x14, 0x50, 0x0c, 0x47, 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, + 0x24, 0x10, 0x62, 0x50, 0x08, 0x00, 0x70, 0x60, 0x27, 0x80, 0x70, 0x60, + 0x24, 0x90, 0x50, 0x6a, 0xd1, 0x69, 0x90, 0x60, 0x4b, 0x80, 0x90, 0x60, + 0x48, 0x90, 0x70, 0x60, 0x4f, 0x80, 0x70, 0x60, 0x4c, 0x90, 0xd4, 0x69, + 0x03, 0x94, 0x74, 0xff, 0x42, 0x50, 0x18, 0x00, 0x50, 0x60, 0x27, 0x80, + 0x50, 0x60, 0x24, 0x90, 0x54, 0x69, 0x70, 0x30, 0x6a, 0x00, 0x50, 0x60, + 0x69, 0x80, 0x50, 0x60, 0x66, 0x90, 0x90, 0x60, 0x65, 0x00, 0x54, 0x6b, + 0xa2, 0x41, 0x01, 0x80, 0x90, 0x60, 0x62, 0x10, 0xdc, 0x6e, 0x42, 0x30, + 0xbd, 0xa4, 0xe2, 0x45, 0x46, 0x06, 0x5c, 0xcf, 0x51, 0x34, 0x70, 0x00, + 0x50, 0x60, 0x27, 0x00, 0x94, 0xcf, 0x82, 0xed, 0x50, 0x60, 0x27, 0x00, + 0xb1, 0x30, 0x78, 0x00, 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, 0x01, 0x00, + 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, 0xa2, 0x41, 0x01, 0x80, + 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x90, 0x30, 0x5c, 0x00, 0x0f, 0xcf, + 0x00, 0x0c, 0x63, 0x50, 0x06, 0x00, 0x70, 0x60, 0x27, 0x80, 0x70, 0x60, + 0x24, 0x90, 0xa4, 0x69, 0x70, 0x60, 0x65, 0x80, 0x70, 0x60, 0x62, 0x90, + 0x24, 0x6b, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0x90, 0x30, 0x6a, 0x00, 0x24, 0xcf, 0x00, 0x0c, 0xcd, 0x4f, 0x3d, 0x23, + 0x40, 0xd0, 0x05, 0x32, 0x78, 0x00, 0xb6, 0x41, 0x05, 0x80, 0xa4, 0x0e, + 0xd6, 0x32, 0x59, 0x5e, 0x90, 0x0c, 0xe5, 0x0e, 0xd6, 0x45, 0xdd, 0xf8, + 0x70, 0x00, 0x42, 0x0e, 0x50, 0xb4, 0x04, 0x00, 0x60, 0x0e, 0x79, 0xcc, + 0x6a, 0xed, 0x62, 0x0e, 0xf6, 0x45, 0x92, 0x0c, 0x42, 0x0e, 0x50, 0xb6, + 0xfa, 0xff, 0x53, 0x30, 0x01, 0x00, 0xf6, 0x45, 0x92, 0x0c, 0x52, 0x94, + 0x53, 0x00, 0x82, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xb7, 0x24, + 0x4c, 0xc8, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xd5, 0x03, 0x4d, 0xc8, + 0xb0, 0x41, 0x05, 0x80, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, + 0x10, 0x32, 0x0d, 0x96, 0xb1, 0x41, 0x10, 0x80, 0xd0, 0x45, 0x5d, 0xf8, + 0x38, 0x00, 0x31, 0x32, 0x11, 0x1f, 0xc0, 0x30, 0xe8, 0x03, 0x81, 0xee, + 0x0a, 0x8d, 0x11, 0x6e, 0xf1, 0x45, 0x00, 0x0c, 0xf0, 0x45, 0x00, 0x0c, + 0xc0, 0x30, 0xe8, 0x03, 0x81, 0xee, 0x78, 0xad, 0x11, 0x6e, 0x54, 0xfc, + 0x50, 0x00, 0xe2, 0x40, 0x2b, 0x00, 0x24, 0x69, 0x62, 0x30, 0x6a, 0x00, + 0x54, 0xfc, 0x54, 0x00, 0xe2, 0x40, 0x28, 0x00, 0x24, 0x69, 0x02, 0xee, + 0x34, 0x05, 0x4b, 0xc8, 0x4c, 0x48, 0xe2, 0x45, 0x97, 0x6e, 0xc2, 0x0f, + 0xd3, 0x0c, 0x82, 0x0c, 0x29, 0x8d, 0x82, 0xef, 0x5c, 0x48, 0xb5, 0x60, + 0x03, 0x00, 0x86, 0xca, 0x45, 0xc8, 0xb5, 0x60, 0x00, 0x10, 0x4d, 0x48, + 0xe4, 0xca, 0xe2, 0x45, 0x7e, 0x4e, 0xab, 0x48, 0x4e, 0x48, 0xe2, 0x45, + 0x9e, 0x0c, 0xf6, 0x45, 0x94, 0x0c, 0x52, 0xb4, 0xcf, 0xff, 0x82, 0x0e, + 0x40, 0x0c, 0x3d, 0x23, 0x40, 0x50, 0x1a, 0x47, 0x54, 0xfc, 0x54, 0x00, + 0x59, 0xad, 0xea, 0xed, 0x40, 0x0c, 0x34, 0x05, 0x4b, 0xc8, 0x4c, 0x48, + 0x02, 0xee, 0xe2, 0x45, 0x97, 0x6e, 0xc2, 0x0f, 0xd3, 0x0c, 0x82, 0x0c, + 0x59, 0xad, 0x82, 0xef, 0x40, 0x30, 0x97, 0xff, 0x3d, 0x23, 0x40, 0x50, + 0x1a, 0x47, 0x4b, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x97, 0x6e, 0x42, 0x30, + 0xb7, 0x24, 0xe2, 0x45, 0x02, 0xee, 0x72, 0x8d, 0x02, 0x0e, 0x82, 0x0c, + 0xa2, 0x41, 0x01, 0x80, 0x6a, 0xef, 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, + 0xa0, 0x0c, 0x35, 0x62, 0x03, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x22, 0xee, + 0x42, 0x30, 0x55, 0x14, 0xc2, 0x45, 0x35, 0x62, 0x00, 0x10, 0x50, 0x60, + 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0x30, 0x62, 0x03, 0x80, 0x30, 0x62, + 0x00, 0x90, 0xbc, 0x48, 0x10, 0x60, 0x07, 0x80, 0xa2, 0x41, 0x03, 0x80, + 0x90, 0x0c, 0x42, 0x30, 0x85, 0xbc, 0xc2, 0x45, 0x10, 0x60, 0x04, 0x90, + 0xab, 0x48, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, 0xe2, 0x45, + 0x90, 0x0c, 0x40, 0x0c, 0x3d, 0x23, 0x40, 0x50, 0x1a, 0x47, 0x00, 0x0c, + 0xe5, 0x4f, 0xdd, 0x22, 0x1c, 0xd0, 0x60, 0x29, 0x67, 0x32, 0xdc, 0xff, + 0x73, 0x0c, 0x42, 0xd0, 0xfc, 0x00, 0x42, 0x70, 0x80, 0x00, 0x40, 0x00, + 0x18, 0x18, 0xe7, 0x30, 0x46, 0x00, 0x3e, 0x05, 0x44, 0xc8, 0xa2, 0x41, + 0x10, 0x80, 0x84, 0x0e, 0x45, 0x0e, 0x02, 0xee, 0x89, 0x6e, 0x42, 0x30, + 0xb7, 0x24, 0xe2, 0x45, 0x26, 0x0e, 0xb4, 0xfe, 0x34, 0x00, 0x15, 0x94, + 0xa6, 0x01, 0x02, 0x0e, 0x40, 0x30, 0x25, 0x01, 0x74, 0xfc, 0xa0, 0x06, + 0x50, 0x60, 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0x10, 0x60, 0x03, 0x80, + 0x10, 0x60, 0x00, 0x90, 0x01, 0xed, 0x50, 0x60, 0x07, 0x80, 0x50, 0x60, + 0x04, 0x90, 0x55, 0xfc, 0x68, 0xff, 0x50, 0x60, 0x2b, 0x80, 0x50, 0x60, + 0x28, 0x90, 0x37, 0x69, 0xe2, 0x40, 0xaa, 0x01, 0x50, 0x60, 0x13, 0x00, + 0x50, 0x60, 0x10, 0x10, 0x42, 0x50, 0x02, 0x00, 0x50, 0x60, 0x13, 0x80, + 0x50, 0x60, 0x10, 0x90, 0x37, 0x6a, 0x48, 0x6a, 0x90, 0x60, 0x17, 0x80, + 0x90, 0x60, 0x14, 0x90, 0x42, 0x50, 0x01, 0x00, 0x50, 0x60, 0x13, 0x80, + 0x50, 0x60, 0x10, 0x90, 0x35, 0x69, 0x02, 0x94, 0x6c, 0x01, 0xb8, 0x69, + 0x42, 0xfc, 0xf8, 0xfe, 0x70, 0x60, 0x1f, 0x80, 0x70, 0x60, 0x1c, 0x90, + 0x50, 0x60, 0x23, 0x80, 0x50, 0x60, 0x20, 0x90, 0x50, 0x60, 0x27, 0x00, + 0x50, 0x60, 0x24, 0x10, 0x62, 0x50, 0x02, 0x00, 0x70, 0x60, 0x27, 0x80, + 0x70, 0x60, 0x24, 0x90, 0x91, 0x60, 0x1b, 0x00, 0x71, 0x60, 0x1f, 0x00, + 0x91, 0x60, 0x18, 0x10, 0x71, 0x60, 0x1c, 0x10, 0x90, 0x60, 0x43, 0x80, + 0x90, 0x60, 0x40, 0x90, 0x70, 0x60, 0x47, 0x80, 0x13, 0xb4, 0x31, 0x01, + 0x70, 0x60, 0x44, 0x90, 0x18, 0x29, 0x19, 0x2a, 0x9a, 0x29, 0xd4, 0x44, + 0xd3, 0x44, 0x2f, 0x2d, 0x02, 0xb4, 0xc2, 0x00, 0xd0, 0xed, 0x10, 0x29, + 0x42, 0xd0, 0xfc, 0x00, 0x62, 0x94, 0xd7, 0x00, 0x60, 0x30, 0x80, 0x00, + 0x62, 0x94, 0xe5, 0x00, 0x00, 0x0c, 0x71, 0x34, 0x20, 0x00, 0x8f, 0x8d, + 0x31, 0x26, 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, + 0x20, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, 0x70, 0x18, + 0x50, 0x00, 0x90, 0x18, 0x51, 0x00, 0x71, 0x34, 0x22, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, 0x31, 0x26, 0x70, 0x18, 0x52, 0x00, + 0x90, 0x18, 0x53, 0x00, 0x7d, 0x20, 0x48, 0x10, 0xb1, 0x69, 0x45, 0x05, + 0x01, 0xee, 0x70, 0x60, 0x2f, 0x80, 0x70, 0x60, 0x2c, 0x90, 0x50, 0x60, + 0x37, 0x80, 0x50, 0x60, 0x34, 0x90, 0x55, 0xfc, 0x3c, 0x00, 0x82, 0x94, + 0x6f, 0x00, 0x82, 0xed, 0x62, 0x94, 0x1d, 0x00, 0x83, 0xed, 0x10, 0x60, + 0x33, 0x80, 0x10, 0x60, 0x30, 0x90, 0x52, 0xfc, 0x1c, 0x00, 0xa4, 0x41, + 0x00, 0x1c, 0xa3, 0x41, 0x00, 0x04, 0x94, 0x44, 0x62, 0x94, 0x3e, 0x00, + 0xa3, 0x41, 0x00, 0x08, 0x62, 0x94, 0x4a, 0x00, 0xa4, 0x48, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, + 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, + 0x24, 0x10, 0x42, 0x50, 0x40, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, + 0x24, 0x90, 0x70, 0x60, 0x57, 0x80, 0x70, 0x60, 0x54, 0x90, 0x92, 0x1c, + 0x26, 0x00, 0x74, 0x1c, 0x64, 0x00, 0x42, 0x25, 0x44, 0x05, 0x26, 0x25, + 0x44, 0x05, 0x24, 0x25, 0x62, 0x00, 0x3c, 0xab, 0x03, 0x00, 0x3c, 0x70, + 0xa4, 0x41, 0x00, 0x1c, 0xa3, 0x41, 0x00, 0x04, 0x42, 0x46, 0x50, 0x60, + 0x5b, 0x80, 0x50, 0x60, 0x58, 0x90, 0x10, 0x60, 0x33, 0x80, 0x10, 0x60, + 0x30, 0x90, 0x52, 0xfc, 0x1c, 0x00, 0x94, 0x44, 0x62, 0xb4, 0xc6, 0xff, + 0xa3, 0x41, 0x00, 0x08, 0x02, 0xed, 0x50, 0x60, 0x33, 0x80, 0xa4, 0x48, + 0x50, 0x60, 0x30, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, + 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, + 0x01, 0xed, 0x50, 0x60, 0x33, 0x80, 0xa4, 0x48, 0x50, 0x60, 0x30, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, 0xe2, 0x45, 0x90, 0x0c, + 0x40, 0x0c, 0xdd, 0x22, 0x1c, 0x50, 0x0e, 0x47, 0x50, 0x60, 0x27, 0x00, + 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, 0x40, 0x00, 0x50, 0x60, 0x27, 0x80, + 0x50, 0x60, 0x24, 0x90, 0x70, 0x60, 0x57, 0x80, 0x70, 0x60, 0x54, 0x90, + 0x72, 0x1c, 0x26, 0x00, 0x32, 0x25, 0x34, 0x05, 0x26, 0x25, 0x34, 0x05, + 0x24, 0x25, 0x50, 0x60, 0x5b, 0x80, 0x7d, 0xcf, 0x50, 0x60, 0x58, 0x90, + 0x50, 0x60, 0x27, 0x00, 0x06, 0xef, 0x98, 0x6e, 0x50, 0x60, 0x24, 0x10, + 0x42, 0x50, 0x01, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, + 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x90, 0x30, + 0x5c, 0x00, 0x10, 0x29, 0xd0, 0xed, 0x42, 0xd0, 0xfc, 0x00, 0x62, 0xb4, + 0x2d, 0xff, 0x60, 0x30, 0x80, 0x00, 0x50, 0x60, 0x3b, 0x00, 0x60, 0x30, + 0x80, 0x00, 0x50, 0x60, 0x38, 0x10, 0x42, 0x50, 0x00, 0x01, 0x50, 0x60, + 0x3b, 0x80, 0x50, 0x60, 0x38, 0x90, 0x10, 0x29, 0x42, 0xd0, 0xfc, 0x00, + 0x62, 0xb4, 0x1d, 0xff, 0x00, 0x0c, 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, + 0x24, 0x10, 0x62, 0x50, 0x08, 0x00, 0x70, 0x60, 0x27, 0x80, 0x70, 0x60, + 0x24, 0x90, 0x91, 0x60, 0x1b, 0x00, 0x71, 0x60, 0x1f, 0x00, 0x91, 0x60, + 0x18, 0x10, 0x71, 0x60, 0x1c, 0x10, 0x90, 0x60, 0x4b, 0x80, 0x90, 0x60, + 0x48, 0x90, 0x70, 0x60, 0x4f, 0x80, 0x13, 0x94, 0x02, 0xff, 0x70, 0x60, + 0x4c, 0x90, 0x42, 0x50, 0x18, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, + 0x24, 0x90, 0x70, 0x62, 0x69, 0x80, 0x70, 0x62, 0x66, 0x90, 0x50, 0x60, + 0x65, 0x00, 0x90, 0x30, 0x6a, 0x00, 0xd3, 0x0c, 0x50, 0x60, 0x62, 0x10, + 0x28, 0x06, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0xb1, 0x30, 0x24, 0x00, 0xe8, 0xce, 0x71, 0x34, 0x20, 0x00, 0x42, 0x50, + 0x06, 0x00, 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, 0x70, 0x62, + 0x65, 0x80, 0xa2, 0x41, 0x01, 0x80, 0x70, 0x62, 0x62, 0x90, 0xd3, 0x0c, + 0xb1, 0x30, 0x24, 0x00, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x90, 0x30, + 0x6a, 0x00, 0xbd, 0xce, 0x18, 0x29, 0x9c, 0xfc, 0xe4, 0x81, 0x40, 0x6e, + 0x91, 0xce, 0x9c, 0xf8, 0xe4, 0x81, 0x5c, 0xfc, 0xe4, 0x81, 0x74, 0xfc, + 0xa0, 0x06, 0x20, 0x6d, 0x5c, 0xf8, 0xe4, 0x81, 0x40, 0x30, 0x25, 0x01, + 0x50, 0x60, 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0x10, 0x60, 0x03, 0x80, + 0x10, 0x60, 0x00, 0x90, 0x01, 0xed, 0x50, 0x60, 0x07, 0x80, 0x50, 0x60, + 0x04, 0x90, 0x55, 0xfc, 0x68, 0xff, 0x50, 0x60, 0x2b, 0x80, 0x50, 0x60, + 0x28, 0x90, 0x37, 0x69, 0xa2, 0x40, 0x56, 0xfe, 0x50, 0x60, 0x13, 0x00, + 0x63, 0xce, 0x50, 0x60, 0x10, 0x10, 0x00, 0x0c, 0xe5, 0x4f, 0xfd, 0x22, + 0x18, 0xd0, 0x36, 0x4a, 0xc4, 0x0e, 0x65, 0x0e, 0x51, 0x30, 0xdb, 0x01, + 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x89, 0x6e, 0x01, 0xee, 0x42, 0x30, + 0xb7, 0x24, 0xa6, 0x0e, 0x87, 0x0e, 0xc2, 0x45, 0x5d, 0xfe, 0x50, 0x00, + 0x02, 0x94, 0x5f, 0x00, 0x02, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x55, 0x14, 0xc2, 0x45, 0x9d, 0xfc, 0x48, 0x00, 0x50, 0x60, 0x0b, 0x80, + 0x50, 0x60, 0x08, 0x90, 0x56, 0xfc, 0x18, 0x00, 0xb5, 0x0c, 0xb5, 0x41, + 0x01, 0x80, 0x50, 0x60, 0x1b, 0x80, 0x50, 0x60, 0x18, 0x90, 0x53, 0xfc, + 0x20, 0x00, 0xd4, 0x0c, 0x90, 0x30, 0x40, 0x00, 0x50, 0x60, 0x17, 0x80, + 0x50, 0x60, 0x14, 0x90, 0x50, 0x60, 0x13, 0x00, 0xb5, 0x32, 0xbd, 0xa4, + 0x50, 0x60, 0x10, 0x10, 0x42, 0x50, 0x01, 0x00, 0x50, 0x60, 0x13, 0x80, + 0x50, 0x60, 0x10, 0x90, 0x53, 0xfc, 0xd0, 0x00, 0x25, 0x69, 0x50, 0x60, + 0x1f, 0x80, 0x50, 0x60, 0x1c, 0x90, 0x10, 0x60, 0x23, 0x80, 0x10, 0x60, + 0x20, 0x90, 0x90, 0x62, 0x3f, 0x80, 0xd5, 0x45, 0x90, 0x62, 0x3c, 0x90, + 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, 0x01, 0x00, + 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, 0x30, 0x62, 0xda, 0x81, + 0x9b, 0xac, 0x30, 0x62, 0xd7, 0x91, 0x12, 0x40, 0x0e, 0x00, 0xa4, 0x48, + 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, 0x24, 0x10, 0x42, 0x50, 0x20, 0x00, + 0x50, 0x60, 0x27, 0x80, 0x50, 0x60, 0x24, 0x90, 0x50, 0x1a, 0xd6, 0x01, + 0xa4, 0x48, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x13, 0x1d, 0xe2, 0x45, + 0x90, 0x0c, 0xfd, 0x22, 0x18, 0x50, 0x0e, 0x47, 0xb5, 0x48, 0xd1, 0x0c, + 0xd5, 0x45, 0x90, 0x30, 0xdb, 0x01, 0x50, 0x60, 0x27, 0x00, 0x50, 0x60, + 0x24, 0x10, 0x42, 0x50, 0x80, 0x00, 0x50, 0x60, 0x27, 0x80, 0xd9, 0xcf, + 0x50, 0x60, 0x24, 0x90, 0xe5, 0x4f, 0x54, 0x48, 0x79, 0x45, 0x32, 0x4a, + 0x46, 0xc8, 0x53, 0x48, 0x24, 0xca, 0x67, 0x0e, 0x45, 0xc8, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x59, 0x33, 0xc2, 0x45, 0x07, 0xfe, 0x70, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3f, 0x1e, 0xc2, 0x45, 0x91, 0xfc, + 0x7c, 0x02, 0x11, 0xf8, 0x7c, 0x02, 0x11, 0xf8, 0x80, 0x02, 0x00, 0x28, + 0x53, 0xfe, 0x48, 0x00, 0xa2, 0xed, 0x10, 0xd2, 0xfc, 0x00, 0x10, 0x72, + 0x20, 0x00, 0x1c, 0xed, 0x03, 0x02, 0x58, 0x10, 0x52, 0x00, 0xd0, 0x91, + 0x02, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x50, 0xff, 0xff, 0x42, 0x30, + 0x51, 0x1e, 0xe2, 0x45, 0x92, 0x0c, 0x0d, 0x8d, 0x51, 0xf8, 0x7c, 0x02, + 0xb3, 0xfc, 0x70, 0x00, 0x54, 0x87, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0xbd, 0xa4, 0xe2, 0x45, 0x8a, 0x06, 0x51, 0xfa, 0x80, 0x02, 0x39, 0x45, + 0x0e, 0x47, 0x00, 0x0c, 0xdd, 0x4f, 0x3d, 0x23, 0x20, 0xd0, 0x56, 0x4a, + 0x58, 0x29, 0x24, 0x0e, 0x32, 0xfd, 0x08, 0x00, 0x81, 0xed, 0x80, 0x30, + 0x21, 0x04, 0x24, 0x01, 0x58, 0x18, 0xe3, 0x0e, 0xa8, 0x2d, 0x42, 0xd0, + 0x00, 0x01, 0x05, 0x0e, 0xb1, 0xfe, 0x30, 0x01, 0xda, 0x4a, 0xdc, 0x4b, + 0x77, 0x00, 0x90, 0xba, 0x09, 0x8d, 0xf5, 0xc8, 0x55, 0xfc, 0x40, 0x00, + 0x77, 0x50, 0x00, 0x01, 0x42, 0x00, 0xac, 0x01, 0x43, 0x00, 0x18, 0xb8, + 0x58, 0x48, 0x97, 0x48, 0x62, 0xfc, 0x54, 0x01, 0x57, 0x50, 0x00, 0x10, + 0x2f, 0x2d, 0xbe, 0x2d, 0x62, 0x00, 0x18, 0xb8, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xc1, 0x23, 0xe2, 0x45, 0x98, 0xee, 0x80, 0x6a, 0xb3, 0x41, + 0x01, 0x80, 0x73, 0x32, 0xbd, 0xa4, 0x82, 0x0e, 0x06, 0xef, 0x22, 0x6e, + 0xd3, 0x45, 0xa5, 0x30, 0x30, 0x00, 0x06, 0xef, 0xb1, 0x30, 0x48, 0x07, + 0xd3, 0x45, 0x94, 0x30, 0x0a, 0x00, 0x80, 0x6a, 0x06, 0xef, 0x94, 0x30, + 0x10, 0x00, 0xd3, 0x45, 0xa5, 0x30, 0x30, 0x00, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x34, 0x4a, 0x4d, 0xa2, 0x40, 0x08, 0x01, 0x55, 0x34, 0x0c, 0x00, + 0x71, 0x14, 0x27, 0x06, 0x3f, 0x2e, 0x82, 0x00, 0x90, 0x13, 0xe2, 0x40, + 0x04, 0x00, 0x95, 0x38, 0x0c, 0x00, 0x71, 0x14, 0x27, 0x06, 0xe3, 0x40, + 0x0a, 0x00, 0x55, 0x34, 0x0c, 0x00, 0x62, 0x00, 0x3c, 0xab, 0x03, 0x00, + 0x3c, 0x70, 0x03, 0x46, 0x03, 0xb4, 0xf3, 0x00, 0x35, 0x05, 0x09, 0x29, + 0x0a, 0x2a, 0x8b, 0x29, 0xd4, 0x44, 0xd3, 0x44, 0x2f, 0x2d, 0x02, 0x94, + 0xd9, 0x00, 0xb1, 0x41, 0x10, 0x80, 0x97, 0x48, 0x31, 0x32, 0xb5, 0x23, + 0xf1, 0x45, 0x8a, 0xee, 0x20, 0xed, 0x54, 0x38, 0x00, 0x00, 0xf4, 0x3a, + 0x18, 0x00, 0x55, 0x34, 0x0c, 0x00, 0x06, 0xef, 0xb0, 0x30, 0x12, 0x00, + 0x94, 0x30, 0x1c, 0x00, 0xd3, 0x45, 0x54, 0x38, 0x1a, 0x00, 0xb0, 0x14, + 0x38, 0x00, 0x97, 0x48, 0xf1, 0x45, 0xa4, 0x4c, 0x20, 0x88, 0x70, 0x14, + 0x38, 0x00, 0x8c, 0x6e, 0x82, 0x30, 0x02, 0x00, 0xa1, 0x89, 0xd3, 0x45, + 0xd0, 0x14, 0x38, 0x00, 0x76, 0x92, 0x09, 0x00, 0x08, 0xed, 0x97, 0x48, + 0x76, 0x02, 0x18, 0x10, 0xa2, 0x30, 0x02, 0x00, 0xf1, 0x45, 0x62, 0x0e, + 0x81, 0xed, 0xa0, 0x89, 0x62, 0x1a, 0x01, 0x00, 0x52, 0xfd, 0x10, 0x00, + 0x8a, 0x40, 0x6d, 0x01, 0x82, 0x32, 0x02, 0x00, 0x5b, 0x48, 0x05, 0xee, + 0xa0, 0x0c, 0x82, 0x00, 0x10, 0x20, 0x60, 0x0e, 0x08, 0xef, 0x40, 0x0c, + 0xd3, 0x03, 0x50, 0x18, 0xb1, 0x2d, 0x95, 0x8d, 0x74, 0x31, 0x01, 0x00, + 0x72, 0xfc, 0x04, 0x00, 0xd0, 0x6e, 0xa6, 0x05, 0xb2, 0x29, 0xc6, 0x05, + 0xbe, 0x6d, 0x83, 0x00, 0x3c, 0xab, 0x04, 0x00, 0x3c, 0x70, 0x43, 0x46, + 0xc5, 0x94, 0x0a, 0x00, 0x74, 0x18, 0x00, 0x00, 0x52, 0xfd, 0x10, 0x00, + 0x8b, 0x0e, 0x62, 0x4e, 0x53, 0x01, 0x50, 0x1b, 0xe3, 0xad, 0x26, 0x6d, + 0xc5, 0x02, 0x50, 0x13, 0xa2, 0x40, 0xf6, 0x00, 0x57, 0xd0, 0x00, 0x11, + 0xa2, 0x40, 0xd0, 0x00, 0xb3, 0x41, 0x09, 0x80, 0x53, 0x34, 0x72, 0x4c, + 0xa2, 0x40, 0xb0, 0x00, 0x37, 0xd1, 0x00, 0x01, 0xa9, 0x40, 0x7c, 0x00, + 0x55, 0xfc, 0x44, 0x00, 0x42, 0x00, 0xec, 0x03, 0x32, 0x8d, 0x58, 0x48, + 0x42, 0xfc, 0x54, 0x01, 0x42, 0x00, 0x2c, 0x04, 0xa2, 0x40, 0x2b, 0x00, + 0xd0, 0xfc, 0xc4, 0x00, 0x12, 0xaf, 0xa2, 0x41, 0x10, 0x80, 0x97, 0x48, + 0xf1, 0x45, 0x83, 0xee, 0x82, 0x0e, 0x40, 0x30, 0xc7, 0xff, 0x54, 0x18, + 0x00, 0x00, 0x01, 0xed, 0x14, 0x18, 0x02, 0x00, 0x54, 0x18, 0x01, 0x00, + 0x3d, 0x23, 0x20, 0x50, 0x12, 0x47, 0xe0, 0x0c, 0xb0, 0x30, 0xc8, 0x00, + 0x80, 0x30, 0x7f, 0x00, 0x42, 0x30, 0xf7, 0x11, 0x04, 0xc8, 0xc2, 0x45, + 0x1d, 0xf8, 0x14, 0x00, 0xe2, 0x40, 0x09, 0x00, 0xa1, 0x09, 0x63, 0xb0, + 0x03, 0x00, 0xa3, 0x40, 0x04, 0x00, 0xa4, 0x09, 0x63, 0x50, 0x40, 0x00, + 0xa4, 0x89, 0xb0, 0xfc, 0xc4, 0x00, 0xd7, 0x8e, 0x09, 0xed, 0x45, 0xc8, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x30, 0x4c, 0x10, 0x32, 0xc8, 0x00, + 0x44, 0xc8, 0xa6, 0x41, 0x09, 0x80, 0xa2, 0x41, 0x10, 0x80, 0x8c, 0xef, + 0x90, 0x0c, 0xc6, 0x30, 0x24, 0x4c, 0x42, 0x30, 0x6d, 0x17, 0xc2, 0x45, + 0x1d, 0xf8, 0x18, 0x00, 0x28, 0x84, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xbb, 0x23, 0xc2, 0x45, 0x9d, 0xfc, 0x5c, 0x00, 0x97, 0x48, 0xf1, 0x45, + 0x83, 0xee, 0x82, 0x0e, 0x40, 0x30, 0xc7, 0xff, 0x54, 0x18, 0x00, 0x00, + 0x01, 0xed, 0x14, 0x18, 0x02, 0x00, 0x54, 0x18, 0x01, 0x00, 0x3d, 0x23, + 0x20, 0x50, 0x12, 0x47, 0x97, 0x48, 0x31, 0x32, 0xb5, 0x23, 0xf1, 0x45, + 0x84, 0xee, 0x14, 0x38, 0x00, 0x00, 0xf4, 0x3a, 0x18, 0x00, 0x55, 0x34, + 0x0c, 0x00, 0x31, 0xcf, 0x54, 0x38, 0x1a, 0x00, 0xf9, 0xce, 0x55, 0x38, + 0x0c, 0x00, 0x0d, 0xcf, 0x55, 0x38, 0x0c, 0x00, 0xb2, 0xfc, 0x0c, 0x00, + 0x97, 0x48, 0xd0, 0x6e, 0xf1, 0x45, 0xd2, 0x26, 0xa4, 0xed, 0xa0, 0x89, + 0x72, 0xfc, 0x0c, 0x00, 0x82, 0x32, 0x02, 0x00, 0xb2, 0x25, 0xa1, 0x89, + 0x52, 0xfc, 0x0c, 0x00, 0x82, 0x40, 0x72, 0xff, 0xe0, 0x0e, 0xb3, 0x41, + 0x10, 0x80, 0xc0, 0x0f, 0x73, 0x32, 0xe9, 0x16, 0xc0, 0x32, 0x01, 0x00, + 0x52, 0xfc, 0x00, 0x00, 0xc2, 0x4f, 0xe2, 0x02, 0x50, 0x11, 0x21, 0x6a, + 0xd3, 0x45, 0xf7, 0x32, 0x34, 0x00, 0x54, 0x18, 0x00, 0x00, 0x84, 0x4e, + 0xd4, 0x1a, 0xff, 0xff, 0x52, 0xfc, 0x0c, 0x00, 0x5e, 0x00, 0x50, 0x13, + 0xa2, 0x40, 0xec, 0xff, 0x55, 0xcf, 0x00, 0x0c, 0x97, 0x48, 0xf1, 0x45, + 0x85, 0xee, 0x82, 0x0e, 0x5a, 0xed, 0x54, 0x18, 0x00, 0x00, 0x03, 0xed, + 0x54, 0x18, 0x01, 0x00, 0x73, 0x34, 0x72, 0x4c, 0x14, 0x18, 0x04, 0x00, + 0x3a, 0x25, 0x35, 0x05, 0x24, 0x25, 0x34, 0x05, 0x42, 0x00, 0xec, 0x79, + 0xa1, 0x25, 0x54, 0x18, 0x02, 0x00, 0x38, 0xcf, 0x74, 0x18, 0x03, 0x00, + 0x97, 0x48, 0xf1, 0x45, 0x84, 0xee, 0x82, 0x0e, 0x21, 0xed, 0x54, 0x18, + 0x00, 0x00, 0x02, 0xed, 0x54, 0x18, 0x01, 0x00, 0x55, 0x48, 0x14, 0x18, + 0x02, 0x00, 0x86, 0xed, 0x21, 0x69, 0x62, 0x94, 0x49, 0x00, 0x87, 0xed, + 0x62, 0xb4, 0x54, 0x00, 0x55, 0x48, 0xa0, 0x69, 0x35, 0x69, 0x34, 0x6a, + 0x62, 0x30, 0xfd, 0xff, 0x64, 0x00, 0x50, 0x13, 0x43, 0x00, 0x58, 0x20, + 0x44, 0x0c, 0x10, 0xcf, 0x54, 0x18, 0x03, 0x00, 0x97, 0x48, 0xb6, 0x00, + 0xd0, 0xb1, 0xd1, 0x45, 0xb6, 0x30, 0x02, 0x00, 0xb2, 0xed, 0xa0, 0x89, + 0xc2, 0x1a, 0x01, 0x00, 0x52, 0xfd, 0x10, 0x00, 0x62, 0x4e, 0x82, 0x32, + 0x02, 0x00, 0x53, 0x01, 0x50, 0x13, 0x02, 0x94, 0xf7, 0xfe, 0x5b, 0x48, + 0x73, 0x00, 0x00, 0x08, 0x63, 0x02, 0x50, 0x19, 0x05, 0xee, 0xb4, 0x25, + 0x82, 0x00, 0x10, 0x20, 0xd3, 0x03, 0x50, 0x10, 0x21, 0x2d, 0x11, 0x8d, + 0x62, 0x4e, 0x52, 0xfc, 0x04, 0x00, 0x34, 0x05, 0x22, 0x29, 0x44, 0x05, + 0x2e, 0x6d, 0x82, 0x00, 0x3c, 0xab, 0x04, 0x00, 0x3c, 0x70, 0x42, 0x46, + 0x54, 0x18, 0x00, 0x00, 0x52, 0xfd, 0x10, 0x00, 0x82, 0x4e, 0x53, 0x01, + 0x50, 0x13, 0x68, 0xad, 0xb6, 0x6d, 0xd6, 0xce, 0x57, 0xd0, 0x00, 0x11, + 0x55, 0x48, 0xa0, 0x69, 0x35, 0x69, 0x34, 0x6a, 0x62, 0x30, 0xfa, 0xff, + 0x64, 0x00, 0x50, 0x13, 0x43, 0x00, 0x58, 0x20, 0x44, 0x0c, 0xca, 0xce, + 0x54, 0x18, 0x03, 0x00, 0x20, 0x69, 0x24, 0x69, 0xc5, 0xce, 0x54, 0x18, + 0x03, 0x00, 0x60, 0x0e, 0xb9, 0xce, 0xa0, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0xbd, 0x22, 0x10, 0xd0, 0x42, 0x30, 0x51, 0x1e, 0x24, 0x0e, + 0x65, 0x0e, 0x44, 0xee, 0xa0, 0x50, 0xff, 0xff, 0x86, 0x0e, 0xe2, 0x45, + 0x47, 0x0e, 0x28, 0x8d, 0x02, 0x0e, 0x24, 0x6e, 0xa2, 0x41, 0x01, 0x80, + 0x7c, 0x84, 0x42, 0x30, 0xbd, 0xa4, 0xe2, 0x45, 0x00, 0x0c, 0x4f, 0x48, + 0x81, 0xed, 0x8d, 0xe9, 0x6e, 0x48, 0x40, 0x00, 0x90, 0x13, 0x0e, 0xe9, + 0xa2, 0x41, 0x05, 0x80, 0x8b, 0xe9, 0x91, 0x0c, 0x50, 0x1a, 0x28, 0x00, + 0x42, 0x30, 0x5d, 0x5e, 0xe2, 0x45, 0x0c, 0xe8, 0xc4, 0x86, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0x7d, 0x5e, 0xe2, 0x45, 0x00, 0x0c, 0x92, 0x69, + 0x40, 0x0c, 0xb0, 0x6d, 0x92, 0xe9, 0xbd, 0x22, 0x10, 0x50, 0x0a, 0x47, + 0xfc, 0xcf, 0x40, 0x30, 0xf4, 0xff, 0x00, 0x0c, 0xe9, 0x4f, 0xfd, 0x22, + 0x10, 0xd0, 0xb3, 0x41, 0x05, 0x80, 0x73, 0x32, 0x59, 0x5e, 0xf3, 0x45, + 0x84, 0x0e, 0x22, 0x0e, 0xf3, 0x45, 0x82, 0x0c, 0x34, 0x96, 0x16, 0x00, + 0xb6, 0x41, 0x05, 0x80, 0xb5, 0x41, 0x10, 0x80, 0x02, 0x0e, 0x51, 0x0e, + 0xd6, 0x32, 0x61, 0x5e, 0x03, 0xcc, 0xb5, 0x32, 0x3f, 0x1e, 0x02, 0x0e, + 0xf6, 0x45, 0x91, 0x0c, 0xf5, 0x45, 0x92, 0x0c, 0x90, 0x0c, 0xf3, 0x45, + 0x30, 0x0e, 0x14, 0xb6, 0xf6, 0xff, 0x50, 0x0e, 0x14, 0xf8, 0x08, 0x00, + 0xfd, 0x22, 0x10, 0x50, 0x0c, 0x47, 0x00, 0x0c, 0xed, 0x4f, 0x4e, 0x48, + 0xe9, 0xcb, 0x44, 0xc8, 0x4f, 0x48, 0x45, 0xc8, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0xc5, 0x86, 0xe2, 0x45, 0x00, 0x0c, 0xa3, 0x41, 0x02, 0x80, + 0x82, 0x30, 0xc4, 0x00, 0x63, 0x30, 0xc9, 0x14, 0xc3, 0x45, 0x5d, 0xf8, + 0x18, 0x00, 0xe9, 0x4b, 0x46, 0x48, 0x0a, 0x47, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xe8, 0x00, 0x8b, 0xed, 0x62, 0xf8, 0xb0, 0x00, 0x9f, 0x45, + 0x02, 0xf8, 0xd0, 0x00, 0xe9, 0x4f, 0x68, 0x45, 0xc4, 0xfc, 0x74, 0x0b, + 0xa2, 0x41, 0x09, 0x80, 0xe2, 0xfc, 0xc0, 0xbe, 0x66, 0xfc, 0x90, 0x00, + 0x04, 0x0e, 0x67, 0x00, 0x90, 0x1b, 0x03, 0x94, 0x50, 0x00, 0x45, 0x0c, + 0xe6, 0x14, 0x96, 0x00, 0x81, 0xed, 0x67, 0x94, 0x59, 0x00, 0x00, 0x0c, + 0xa2, 0x60, 0x17, 0x00, 0x6d, 0x6a, 0xb1, 0x41, 0x05, 0x80, 0xa2, 0x60, + 0x14, 0x10, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xdd, 0x1f, 0xe2, 0x45, + 0xdd, 0x2e, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc9, 0x34, 0xc2, 0x45, + 0x31, 0x32, 0x65, 0x57, 0x01, 0xed, 0x50, 0x18, 0xb3, 0x0c, 0xa2, 0x41, + 0x05, 0x80, 0xa0, 0x0c, 0x09, 0x6e, 0x42, 0x30, 0x29, 0x56, 0xc2, 0x45, + 0xb2, 0x41, 0x00, 0xa4, 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, + 0x1c, 0xfe, 0x7c, 0x82, 0x14, 0xef, 0x81, 0xee, 0x00, 0x6d, 0x09, 0x6e, + 0x5c, 0xf8, 0x7c, 0x82, 0xf1, 0x45, 0x00, 0x0c, 0x5c, 0xfc, 0x84, 0x82, + 0x1c, 0xfa, 0x7c, 0x82, 0xa2, 0x40, 0x0e, 0x00, 0x5c, 0xfc, 0x7c, 0x82, + 0xa2, 0x40, 0x0a, 0x00, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, 0xa0, 0x00, + 0xa2, 0x40, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, 0x00, 0x18, + 0x52, 0xfc, 0x84, 0x04, 0x02, 0x40, 0xda, 0xff, 0x00, 0x0c, 0x28, 0x45, + 0x0c, 0x47, 0x64, 0xfc, 0xc0, 0x0c, 0x03, 0x94, 0xb3, 0xff, 0x81, 0xed, + 0x86, 0x14, 0x96, 0x00, 0x64, 0xb4, 0xae, 0xff, 0x00, 0x0c, 0x06, 0xf8, + 0x90, 0x00, 0xaa, 0xcf, 0xd0, 0xfc, 0x74, 0x0b, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0x9d, 0xf0, 0xe2, 0x45, 0x00, 0x0c, 0xe0, 0x40, 0xe7, 0xff, + 0x44, 0x30, 0xca, 0xff, 0x42, 0xb0, 0x02, 0x00, 0xa2, 0x40, 0x0b, 0x00, + 0xf5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0xe5, 0xcb, 0x42, 0x30, 0x89, 0x97, + 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0x40, 0x0c, 0x06, 0x47, 0x05, 0x40, + 0xf3, 0xff, 0x40, 0x0c, 0xbf, 0x45, 0x00, 0x0c, 0xed, 0x4f, 0x2a, 0xed, + 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x66, 0x45, 0x02, 0xee, 0x25, 0x0e, + 0x42, 0x30, 0xb7, 0x24, 0x89, 0x6e, 0xc2, 0x45, 0x51, 0xfe, 0x08, 0x00, + 0x34, 0x8d, 0x02, 0x0e, 0x40, 0x30, 0x2b, 0x01, 0x50, 0x60, 0x0b, 0x80, + 0x50, 0x60, 0x08, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x6d, 0x14, + 0xe2, 0x45, 0x92, 0x0c, 0x50, 0x60, 0x1b, 0x80, 0x50, 0x60, 0x18, 0x90, + 0x51, 0x34, 0x1c, 0x06, 0xa3, 0x41, 0x09, 0x80, 0x63, 0x14, 0x48, 0x4d, + 0x21, 0x26, 0x90, 0x18, 0x25, 0x00, 0x50, 0x18, 0x24, 0x00, 0x51, 0x14, + 0x1b, 0x06, 0xaa, 0xee, 0x50, 0x18, 0x26, 0x00, 0x51, 0x14, 0x14, 0x06, + 0x50, 0x18, 0x27, 0x00, 0x51, 0x14, 0x12, 0x06, 0x70, 0x18, 0x29, 0x00, + 0x50, 0x18, 0x28, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x19, 0x1d, + 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0x26, 0x45, 0x0a, 0x47, 0xfd, 0xcf, + 0x40, 0x30, 0xf4, 0xff, 0xed, 0x4f, 0x66, 0x45, 0x45, 0xfc, 0x24, 0x01, + 0x49, 0xee, 0xaf, 0xed, 0x42, 0x14, 0x94, 0x00, 0x25, 0x0e, 0x45, 0xfe, + 0x08, 0x00, 0x44, 0x00, 0x18, 0x18, 0xa2, 0x41, 0x10, 0x80, 0x89, 0x6e, + 0x02, 0xee, 0x42, 0x30, 0xb7, 0x24, 0xc2, 0x45, 0x7d, 0xf8, 0x10, 0x00, + 0x02, 0x94, 0x6c, 0x00, 0x02, 0x0e, 0x40, 0x30, 0x2c, 0x01, 0x50, 0x60, + 0x0b, 0x80, 0x50, 0x60, 0x08, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x6d, 0x14, 0xe2, 0x45, 0x92, 0x0c, 0xa3, 0x41, 0x09, 0x80, 0x63, 0x34, + 0x4a, 0x4d, 0xa4, 0x41, 0x09, 0x80, 0xa4, 0x14, 0x70, 0x4c, 0x50, 0x60, + 0x1b, 0x80, 0x31, 0x26, 0x50, 0x60, 0x18, 0x90, 0x70, 0x18, 0x2c, 0x00, + 0xb0, 0x18, 0x26, 0x00, 0x90, 0x18, 0x2d, 0x00, 0x51, 0xfc, 0x24, 0x01, + 0x82, 0xed, 0x22, 0x69, 0x50, 0x60, 0x2b, 0x80, 0x50, 0x60, 0x28, 0x90, + 0x51, 0xfc, 0xf4, 0x05, 0x62, 0x94, 0x2c, 0x00, 0x00, 0x0c, 0x51, 0xfc, + 0x24, 0x01, 0x42, 0x14, 0x94, 0x00, 0x1d, 0x8d, 0xa4, 0x48, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0x25, 0x4d, 0x06, 0x8d, 0x01, 0xed, 0x10, 0x18, + 0x24, 0x00, 0x50, 0x18, 0x25, 0x00, 0x01, 0xed, 0xa5, 0x41, 0x09, 0x80, + 0x50, 0x18, 0x2e, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x1a, 0xef, 0xa5, 0x30, + 0x54, 0x4c, 0x90, 0x30, 0x2f, 0x00, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, + 0x10, 0x18, 0x27, 0x00, 0xa4, 0x48, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x19, 0x1d, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0x26, 0x45, 0x0a, 0x47, + 0x51, 0xfc, 0xdc, 0x04, 0x07, 0x8d, 0x81, 0xed, 0x01, 0xed, 0x50, 0x18, + 0x24, 0x00, 0xcd, 0xcf, 0x50, 0x18, 0x25, 0x00, 0x51, 0x14, 0x3f, 0x00, + 0x62, 0xb4, 0xc7, 0xff, 0x00, 0x0c, 0x10, 0x18, 0x24, 0x00, 0xc3, 0xcf, + 0x50, 0x18, 0x25, 0x00, 0xe9, 0xcf, 0x40, 0x30, 0xf4, 0xff, 0x00, 0x0c, + 0xd5, 0x4f, 0x01, 0xed, 0x1d, 0x23, 0x34, 0xd0, 0x86, 0x0e, 0xa4, 0x0e, + 0xc5, 0x0e, 0x46, 0x94, 0x13, 0x00, 0xe7, 0x0e, 0x5c, 0x48, 0xf7, 0x0c, + 0xd4, 0x0c, 0x46, 0xc8, 0x5b, 0x48, 0xb6, 0x0c, 0x45, 0xc8, 0x5a, 0x48, + 0x44, 0xc8, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x8d, 0xd8, 0xe2, 0x45, + 0x95, 0x0c, 0x1d, 0x23, 0x34, 0x50, 0x16, 0x47, 0xb0, 0x41, 0x10, 0x80, + 0xb1, 0x41, 0x10, 0x80, 0x10, 0x32, 0x17, 0x1f, 0xb3, 0x41, 0x09, 0x80, + 0xb2, 0x41, 0x09, 0x80, 0x04, 0xcc, 0x31, 0x32, 0x11, 0x1f, 0xf1, 0x45, + 0x00, 0x0c, 0x11, 0x6e, 0xf0, 0x45, 0xa0, 0x0c, 0x73, 0xfc, 0xb0, 0x9b, + 0x52, 0xfc, 0x30, 0x4d, 0xc0, 0x30, 0x10, 0x27, 0x81, 0xee, 0x43, 0xb4, + 0xf2, 0xff, 0x11, 0x6e, 0x5c, 0x48, 0xf7, 0x0c, 0xd4, 0x0c, 0x46, 0xc8, + 0x5b, 0x48, 0xb6, 0x0c, 0x45, 0xc8, 0x5a, 0x48, 0x44, 0xc8, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x8d, 0xd8, 0xe2, 0x45, 0x95, 0x0c, 0x1d, 0x23, + 0x34, 0x50, 0x16, 0x47, 0x44, 0x60, 0x0b, 0x00, 0x81, 0xed, 0x44, 0x60, + 0x08, 0x10, 0x62, 0xb4, 0x09, 0x00, 0xb9, 0x41, 0x04, 0x80, 0xa3, 0x41, + 0x09, 0x80, 0x43, 0xfc, 0x30, 0x4d, 0x20, 0x6d, 0x43, 0xf8, 0x30, 0x4d, + 0x39, 0x33, 0x6d, 0xc4, 0xb9, 0x45, 0x00, 0x0c, 0x01, 0xed, 0x44, 0x94, + 0x1f, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x17, 0x8e, 0x02, 0xed, 0x44, 0x94, + 0x05, 0x00, 0x03, 0xed, 0x44, 0x94, 0x0a, 0x00, 0x00, 0x0c, 0xbf, 0x45, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x54, 0x4d, 0xa4, 0x8a, 0xa5, 0x8a, + 0x9f, 0x45, 0xa6, 0x8a, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x54, 0x4d, + 0xa7, 0x8a, 0x9f, 0x45, 0xa8, 0x8a, 0xa2, 0x41, 0x09, 0x80, 0x9f, 0x45, + 0xa2, 0x18, 0x55, 0x4d, 0x42, 0x30, 0x54, 0x4d, 0xa2, 0x8a, 0x9f, 0x45, + 0xa3, 0x8a, 0x00, 0x0c, 0xb9, 0x41, 0x09, 0x80, 0x90, 0xee, 0x39, 0x33, + 0xf5, 0x15, 0x99, 0x45, 0x84, 0x00, 0xec, 0x11, 0xb9, 0x41, 0x09, 0x80, + 0x88, 0xee, 0x39, 0x33, 0xf5, 0x15, 0x99, 0x45, 0x84, 0x00, 0xac, 0x12, + 0x49, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x9d, 0x22, 0x5c, 0xd1, 0x42, 0x30, + 0x81, 0x59, 0x04, 0x0e, 0x25, 0x0e, 0x46, 0x0e, 0xc2, 0x45, 0x64, 0xfe, + 0x9c, 0x04, 0x50, 0x14, 0x20, 0x06, 0x05, 0xad, 0x98, 0x6d, 0x9d, 0x22, + 0x5c, 0x51, 0x9f, 0x45, 0xb9, 0x4c, 0x53, 0xfc, 0x00, 0x00, 0x67, 0xc8, + 0x42, 0x30, 0x30, 0x00, 0x48, 0xc8, 0x60, 0x0c, 0x40, 0x0c, 0x5d, 0x20, + 0x10, 0x90, 0xa2, 0x41, 0x10, 0x80, 0x95, 0x6f, 0xc0, 0x0c, 0xb2, 0x30, + 0xe2, 0xff, 0x91, 0x30, 0x1e, 0x00, 0x42, 0x30, 0x7d, 0x1c, 0xc2, 0x45, + 0x1d, 0xf8, 0x18, 0x00, 0x50, 0x14, 0x1c, 0x06, 0x08, 0x8d, 0x5e, 0x48, + 0x20, 0x09, 0x24, 0x2d, 0x04, 0x8d, 0x01, 0xed, 0x04, 0xcc, 0x50, 0x18, + 0x1e, 0x06, 0x10, 0x18, 0x1e, 0x06, 0x50, 0xfc, 0x68, 0x06, 0x21, 0x6a, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe9, 0x16, 0xe2, 0x45, 0x00, 0x0c, + 0x42, 0xb0, 0x24, 0x00, 0x02, 0x94, 0x5d, 0x00, 0xa2, 0x41, 0x09, 0x80, + 0x83, 0xed, 0x62, 0x18, 0x48, 0x4d, 0x79, 0x48, 0x03, 0x94, 0x59, 0x00, + 0x7a, 0x48, 0x84, 0xed, 0x62, 0x18, 0x48, 0x4d, 0x7b, 0x48, 0x03, 0x94, + 0x57, 0x00, 0x7c, 0x48, 0x85, 0xed, 0x62, 0x18, 0x48, 0x4d, 0x7e, 0x48, + 0x03, 0x94, 0x55, 0x00, 0xb0, 0x41, 0x09, 0x80, 0x83, 0x1c, 0x0c, 0x00, + 0x86, 0xee, 0xa2, 0x18, 0x48, 0x4d, 0x44, 0x40, 0xac, 0xff, 0x10, 0x18, + 0x54, 0x4d, 0x36, 0x09, 0x04, 0xef, 0x08, 0xee, 0xa6, 0x2e, 0xa6, 0x00, + 0x58, 0x20, 0xa4, 0x0c, 0x28, 0x2d, 0x42, 0x6e, 0x44, 0x00, 0x18, 0x28, + 0xa5, 0x30, 0x11, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x9d, 0x30, 0x50, 0x01, + 0x02, 0xef, 0x42, 0x30, 0xbd, 0xa4, 0xe2, 0x45, 0xd6, 0x06, 0x9d, 0xfc, + 0x50, 0x01, 0x44, 0x00, 0xec, 0x18, 0x02, 0x94, 0x8e, 0xff, 0xa6, 0x41, + 0x09, 0x80, 0x46, 0x30, 0x55, 0x4d, 0xa3, 0x41, 0x09, 0x80, 0x06, 0x18, + 0x55, 0x4d, 0x81, 0xef, 0x84, 0x00, 0xec, 0x11, 0x90, 0xee, 0x63, 0x30, + 0xf5, 0x15, 0x21, 0x88, 0x22, 0x88, 0x23, 0x88, 0x24, 0x88, 0x25, 0x88, + 0x26, 0x88, 0x27, 0x88, 0xc3, 0x45, 0xf0, 0x18, 0x54, 0x4d, 0x9d, 0xfc, + 0x50, 0x01, 0x88, 0xee, 0xc3, 0x45, 0x84, 0x00, 0xac, 0x12, 0x6f, 0xcf, + 0x00, 0x0c, 0x82, 0xed, 0xa6, 0xcf, 0x62, 0x18, 0x48, 0x4d, 0x03, 0xb4, + 0xa6, 0xff, 0x7b, 0x48, 0xa8, 0xcf, 0x00, 0x0c, 0x03, 0xb4, 0xa8, 0xff, + 0x7e, 0x48, 0xaa, 0xcf, 0x00, 0x0c, 0x7f, 0x48, 0x83, 0x8d, 0x86, 0xed, + 0x62, 0x18, 0x48, 0x4d, 0xa2, 0x41, 0x09, 0x80, 0x58, 0xcf, 0x02, 0x18, + 0x54, 0x4d, 0x00, 0x0c, 0xe1, 0x4f, 0x1d, 0x23, 0x1c, 0xd0, 0xd0, 0x29, + 0x84, 0xef, 0x43, 0xd0, 0x0c, 0x00, 0xe2, 0x94, 0x4d, 0x00, 0x00, 0x0c, + 0x88, 0xed, 0x62, 0xb4, 0x52, 0x00, 0x40, 0x0c, 0x46, 0xfc, 0x74, 0x00, + 0xa2, 0xfe, 0x38, 0x00, 0x55, 0x14, 0x3f, 0x00, 0x02, 0x94, 0x49, 0x00, + 0x40, 0x0c, 0x55, 0x60, 0x17, 0x00, 0x55, 0x60, 0x14, 0x10, 0x02, 0x94, + 0x41, 0x00, 0xb0, 0x41, 0x10, 0x80, 0xb4, 0x41, 0x01, 0x80, 0xf5, 0x32, + 0x3f, 0x00, 0xc0, 0x0e, 0x10, 0x32, 0xdf, 0x1d, 0x81, 0xec, 0x60, 0x32, + 0x02, 0x00, 0x45, 0x32, 0x04, 0x00, 0x0d, 0xcc, 0x94, 0x32, 0xa1, 0xa4, + 0x63, 0x96, 0x32, 0x00, 0x00, 0x0c, 0x55, 0x60, 0x17, 0x00, 0x55, 0x60, + 0x14, 0x10, 0x56, 0x00, 0x90, 0x13, 0x27, 0x8d, 0x40, 0x0c, 0x56, 0x00, + 0x00, 0x10, 0xc2, 0x02, 0x50, 0x11, 0x22, 0x25, 0x55, 0x00, 0x50, 0x11, + 0x82, 0x60, 0x3c, 0x00, 0xc2, 0x4e, 0xd0, 0x45, 0x82, 0x60, 0x39, 0x10, + 0x77, 0x14, 0x00, 0x00, 0x23, 0xb6, 0xe4, 0xff, 0xf7, 0x32, 0x0a, 0x00, + 0xb5, 0x14, 0x1c, 0x00, 0x06, 0xef, 0x92, 0x0c, 0xf4, 0x45, 0xaa, 0x06, + 0x5e, 0x8d, 0x01, 0xed, 0x0a, 0xcc, 0x00, 0x0c, 0x04, 0x0e, 0x44, 0xfc, + 0x4c, 0x0b, 0x02, 0xee, 0xa0, 0x6b, 0x87, 0x94, 0x0c, 0x00, 0x00, 0x0c, + 0x40, 0x0c, 0x1d, 0x23, 0x1c, 0x50, 0x10, 0x47, 0xaa, 0x86, 0xf4, 0x45, + 0x06, 0xef, 0x4b, 0x8d, 0x01, 0xed, 0xf7, 0xcf, 0x00, 0x0c, 0x22, 0x16, + 0x1c, 0x00, 0x01, 0xed, 0x51, 0xb4, 0xf1, 0xff, 0x40, 0x0c, 0x63, 0xd0, + 0xfc, 0x00, 0x24, 0xed, 0x43, 0xb4, 0xeb, 0xff, 0x40, 0x0c, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, 0xc4, 0xc8, 0x50, 0xf8, 0xbc, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3d, 0x17, 0xc2, 0x45, 0x85, 0x34, + 0x00, 0x00, 0xc4, 0x48, 0x66, 0xfc, 0x70, 0x00, 0x26, 0x05, 0x20, 0x09, + 0x27, 0x2d, 0xa2, 0x40, 0x07, 0x00, 0x50, 0xfc, 0xc0, 0x0c, 0x30, 0x1a, + 0xb2, 0x0c, 0x20, 0x6d, 0x50, 0xf8, 0xc0, 0x0c, 0xa3, 0x41, 0x08, 0x80, + 0x63, 0x30, 0x88, 0x03, 0x83, 0x60, 0x57, 0x00, 0x01, 0xed, 0x83, 0x60, + 0x54, 0x10, 0x40, 0x6e, 0x83, 0x60, 0x57, 0x80, 0xc0, 0xcf, 0x83, 0x60, + 0x54, 0x90, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x68, 0x45, + 0xa0, 0x0c, 0x44, 0x0e, 0x42, 0x30, 0x17, 0x1f, 0x09, 0x6e, 0xc2, 0x45, + 0xb1, 0x41, 0x10, 0x80, 0x31, 0x32, 0x11, 0x1f, 0x52, 0x14, 0xad, 0x0c, + 0x28, 0xad, 0x40, 0x0c, 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, + 0x1c, 0xfe, 0x7c, 0x82, 0xc0, 0x30, 0xe8, 0x03, 0x81, 0xee, 0x00, 0x6d, + 0x09, 0x6e, 0x5c, 0xf8, 0x7c, 0x82, 0xf1, 0x45, 0x00, 0x0c, 0x5c, 0xfc, + 0x84, 0x82, 0x1c, 0xfa, 0x7c, 0x82, 0xa2, 0x40, 0xe7, 0xff, 0x5c, 0xfc, + 0x7c, 0x82, 0xa2, 0x40, 0xe3, 0xff, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, + 0xa0, 0x00, 0xa2, 0x40, 0xdd, 0xff, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, + 0x00, 0x18, 0x52, 0x14, 0xad, 0x0c, 0x5a, 0x8d, 0x40, 0x0c, 0x28, 0x45, + 0x0c, 0x47, 0x00, 0x0c, 0x72, 0x69, 0x64, 0x48, 0x09, 0xad, 0x05, 0x49, + 0x7a, 0x29, 0x22, 0xd1, 0x20, 0x00, 0x09, 0x94, 0x03, 0x00, 0x40, 0x00, + 0x4c, 0x29, 0x7a, 0xa9, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0xbd, 0x2d, + 0x64, 0xc8, 0x99, 0x45, 0x05, 0xc9, 0x00, 0x0c, 0x85, 0x40, 0x4b, 0x00, + 0x00, 0x0c, 0x24, 0xd1, 0x01, 0x00, 0x09, 0xb4, 0x3f, 0x00, 0x40, 0x0c, + 0x65, 0x90, 0x02, 0x00, 0xa6, 0xad, 0xc2, 0x2d, 0x88, 0x8d, 0x65, 0x90, + 0x04, 0x00, 0xc0, 0x29, 0xbc, 0x4c, 0x84, 0x4c, 0x34, 0x05, 0x65, 0x90, + 0x04, 0x00, 0x96, 0xad, 0xd2, 0x2d, 0x05, 0x0d, 0x00, 0x01, 0x0c, 0x08, + 0x04, 0x01, 0x50, 0x41, 0xc0, 0x0c, 0xc0, 0x69, 0x64, 0x05, 0x42, 0x6e, + 0x26, 0x05, 0x04, 0x01, 0x90, 0x3b, 0xf9, 0xaf, 0x62, 0x00, 0x90, 0x33, + 0x64, 0x05, 0xaf, 0x2d, 0x42, 0x00, 0x40, 0x80, 0x26, 0x05, 0xd2, 0x2d, + 0xe3, 0x40, 0x03, 0x00, 0xc0, 0x29, 0x84, 0x4c, 0x34, 0x05, 0xd1, 0x2e, + 0x84, 0x8e, 0xaf, 0x2d, 0xc0, 0x09, 0x34, 0x05, 0xaf, 0x2d, 0x42, 0x00, + 0x40, 0x80, 0x26, 0x05, 0xaf, 0x2d, 0x42, 0x00, 0x40, 0x80, 0x09, 0x94, + 0x0c, 0x00, 0x26, 0x05, 0xa0, 0x25, 0xbf, 0x2d, 0x42, 0x00, 0x2c, 0x3a, + 0x9f, 0x45, 0xd3, 0x44, 0x40, 0x09, 0xde, 0x6e, 0x40, 0x6e, 0xbe, 0xcf, + 0x20, 0x25, 0x9f, 0x45, 0x2f, 0x2d, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0xe5, 0xcb, 0x42, 0x30, 0xc1, 0x19, + 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0x12, 0x44, 0x2f, 0x2d, 0x06, 0x47, + 0xb5, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x58, 0x06, 0x42, 0x30, 0xdf, 0x1d, + 0x1d, 0x23, 0x74, 0xd0, 0x16, 0xc8, 0x46, 0x0e, 0xb0, 0x41, 0x01, 0x80, + 0x1d, 0x38, 0x5c, 0x00, 0x1d, 0x38, 0x5e, 0x00, 0x1d, 0x38, 0x60, 0x00, + 0x1d, 0x38, 0x62, 0x00, 0x1d, 0x38, 0x64, 0x00, 0x1d, 0x38, 0x66, 0x00, + 0x1d, 0x38, 0x68, 0x00, 0xc2, 0x45, 0x1d, 0x18, 0x6a, 0x00, 0x10, 0x32, + 0xbd, 0xa4, 0x9d, 0x30, 0x6a, 0x00, 0x01, 0xef, 0xa2, 0x0c, 0xf0, 0x45, + 0x22, 0x0e, 0x7d, 0x14, 0x6a, 0x00, 0x04, 0xee, 0x39, 0x25, 0x82, 0x94, + 0x6c, 0x00, 0xb7, 0x2d, 0x86, 0xed, 0x62, 0x94, 0x06, 0x00, 0x00, 0x0c, + 0x40, 0x0c, 0x1d, 0x23, 0x74, 0x50, 0x9f, 0x45, 0x4d, 0x4c, 0x00, 0xf8, + 0x00, 0x00, 0x00, 0xf8, 0x04, 0x00, 0x00, 0xf8, 0x08, 0x00, 0x00, 0xf8, + 0x0c, 0x00, 0x00, 0xf8, 0x10, 0x00, 0x00, 0xf8, 0x14, 0x00, 0x00, 0xf8, + 0x18, 0x00, 0x00, 0xf8, 0x1c, 0x00, 0x00, 0xf8, 0x20, 0x00, 0x00, 0xf8, + 0x24, 0x00, 0x12, 0x29, 0x08, 0x8d, 0x60, 0x0e, 0x62, 0x02, 0x00, 0x40, + 0x21, 0x25, 0x53, 0x00, 0x90, 0x12, 0x62, 0xd2, 0xff, 0xff, 0x16, 0x09, + 0xba, 0xed, 0x62, 0x94, 0x07, 0x00, 0x86, 0xed, 0x62, 0x94, 0x04, 0x00, + 0x91, 0xed, 0x62, 0xb4, 0xd4, 0xff, 0x40, 0x0c, 0x91, 0x32, 0x04, 0x00, + 0xdd, 0x32, 0x10, 0x00, 0xb4, 0x0c, 0x96, 0x0c, 0x24, 0xef, 0x04, 0xc8, + 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0x09, 0xc8, 0x0a, 0xc8, + 0x0b, 0xc8, 0x0c, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, 0x0f, 0xc8, 0x10, 0xc8, + 0x11, 0xc8, 0x12, 0xc8, 0x13, 0xc8, 0x14, 0xc8, 0xd0, 0x45, 0x1d, 0xf8, + 0x54, 0x00, 0x1b, 0x6e, 0x20, 0xef, 0xf0, 0x45, 0x94, 0x6e, 0x16, 0x09, + 0x02, 0xef, 0xb4, 0x0c, 0x9d, 0x30, 0x56, 0x00, 0xd0, 0x45, 0x5d, 0x18, + 0x55, 0x00, 0x16, 0x09, 0xba, 0xed, 0x62, 0x94, 0xbc, 0x00, 0x91, 0xed, + 0x62, 0x94, 0xe2, 0x00, 0x86, 0xed, 0x62, 0x94, 0x0b, 0x01, 0xb1, 0x32, + 0x38, 0x00, 0x24, 0xef, 0xb6, 0x0c, 0xf0, 0x45, 0x94, 0x0c, 0x9b, 0xcf, + 0x40, 0x0c, 0x00, 0xf8, 0x00, 0x00, 0x00, 0xf8, 0x04, 0x00, 0x00, 0xf8, + 0x08, 0x00, 0x00, 0xf8, 0x0c, 0x00, 0x00, 0xf8, 0x10, 0x00, 0x11, 0x29, + 0x63, 0x02, 0x00, 0x10, 0x08, 0x8d, 0x80, 0x0e, 0x82, 0x02, 0x00, 0x40, + 0x21, 0x25, 0x54, 0x00, 0x90, 0xa2, 0x94, 0xd2, 0xff, 0xff, 0x19, 0x09, + 0x81, 0xed, 0x82, 0xd0, 0xef, 0x00, 0x64, 0x94, 0x04, 0x00, 0x86, 0xed, + 0x62, 0xb4, 0x7b, 0xff, 0x40, 0x0c, 0xb5, 0x41, 0x09, 0x80, 0xd1, 0x36, + 0x0a, 0x00, 0xe2, 0x86, 0xb5, 0x32, 0xc1, 0x19, 0x1a, 0x88, 0x1b, 0x88, + 0xd5, 0x45, 0x51, 0x31, 0x0a, 0x00, 0x12, 0x44, 0x02, 0xef, 0xbd, 0x30, + 0x5e, 0x00, 0x8a, 0x0c, 0xd0, 0x45, 0x5d, 0x38, 0x5e, 0x00, 0x5d, 0x34, + 0x5e, 0x00, 0xc2, 0x96, 0x04, 0x00, 0x00, 0x0c, 0x12, 0xb4, 0x5f, 0xff, + 0x01, 0xed, 0x19, 0x09, 0x81, 0xed, 0x62, 0x94, 0xe8, 0x00, 0x74, 0x02, + 0xd0, 0xa1, 0x86, 0xed, 0x62, 0x94, 0x04, 0x00, 0x91, 0xed, 0x62, 0xb4, + 0x52, 0xff, 0x40, 0x0c, 0xf1, 0x32, 0x08, 0x00, 0xdd, 0x32, 0x10, 0x00, + 0xb7, 0x0c, 0x96, 0x0c, 0x0c, 0xef, 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, + 0x07, 0xc8, 0x08, 0xc8, 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0c, 0xc8, + 0x0d, 0xc8, 0x0e, 0xc8, 0x0f, 0xc8, 0x10, 0xc8, 0x11, 0xc8, 0x12, 0xc8, + 0x13, 0xc8, 0x14, 0xc8, 0xd0, 0x45, 0x1d, 0xf8, 0x54, 0x00, 0x08, 0xef, + 0x96, 0x6e, 0xf0, 0x45, 0x1b, 0x6e, 0x19, 0x09, 0x86, 0xed, 0x5d, 0x18, + 0x3d, 0x00, 0x19, 0x09, 0x62, 0x94, 0xd8, 0x00, 0x91, 0xed, 0x62, 0xb4, + 0x28, 0xff, 0x40, 0x0c, 0x71, 0x02, 0x50, 0x89, 0x12, 0x29, 0x0b, 0x8d, + 0x60, 0x32, 0x0c, 0x00, 0x62, 0x02, 0x00, 0x40, 0x21, 0x25, 0x53, 0x00, + 0x90, 0x9a, 0x73, 0xd2, 0xff, 0xff, 0x73, 0x32, 0x0c, 0x00, 0x02, 0xef, + 0x92, 0x6e, 0xd0, 0x45, 0x9d, 0x30, 0x3e, 0x00, 0x13, 0x29, 0x0c, 0xef, + 0x9b, 0x6e, 0x5d, 0x38, 0x68, 0x00, 0x97, 0x0c, 0x17, 0x88, 0xf0, 0x45, + 0x16, 0x88, 0xb3, 0x0c, 0xf5, 0x45, 0x97, 0x0c, 0x12, 0x44, 0xb6, 0x0c, + 0x97, 0x0c, 0x0c, 0xef, 0x91, 0x32, 0x06, 0x00, 0xd0, 0x45, 0x5d, 0x38, + 0x62, 0x00, 0x02, 0xef, 0xbd, 0x30, 0x62, 0x00, 0xf0, 0x45, 0x94, 0x0c, + 0x5d, 0x34, 0x62, 0x00, 0x7d, 0x34, 0x68, 0x00, 0x43, 0x94, 0xf2, 0xfe, + 0x00, 0x0c, 0x12, 0xb4, 0xf0, 0xfe, 0x40, 0x00, 0x90, 0x13, 0xed, 0xce, + 0x40, 0x0c, 0xb1, 0x32, 0x2a, 0x00, 0xb5, 0x0c, 0x02, 0xef, 0xf0, 0x45, + 0x33, 0x6e, 0x24, 0xef, 0x9b, 0x6e, 0x94, 0x0c, 0x11, 0x18, 0x2a, 0x00, + 0xd0, 0x45, 0x11, 0x18, 0x2b, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x94, 0x0c, + 0x42, 0x30, 0xc1, 0x19, 0xc2, 0x45, 0xb3, 0x30, 0x24, 0x00, 0x12, 0x44, + 0x02, 0xef, 0xaf, 0x6e, 0x95, 0x0c, 0xd0, 0x45, 0x5d, 0x38, 0x5c, 0x00, + 0x7d, 0x34, 0x5c, 0x00, 0x5d, 0x34, 0x64, 0x00, 0x43, 0x94, 0x2a, 0xff, + 0x24, 0xef, 0x12, 0x94, 0x27, 0xff, 0x24, 0xef, 0xc4, 0xce, 0x01, 0xed, + 0xb1, 0x32, 0x2e, 0x00, 0xb5, 0x0c, 0x02, 0xef, 0xf0, 0x45, 0x35, 0x6e, + 0x24, 0xef, 0x9b, 0x6e, 0x94, 0x0c, 0x11, 0x18, 0x2e, 0x00, 0xd0, 0x45, + 0x11, 0x18, 0x2f, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x94, 0x0c, 0x42, 0x30, + 0xc1, 0x19, 0xc2, 0x45, 0xb3, 0x30, 0x24, 0x00, 0x12, 0x44, 0x02, 0xef, + 0xbd, 0x30, 0x62, 0x00, 0x95, 0x0c, 0xd0, 0x45, 0x5d, 0x38, 0x62, 0x00, + 0x5d, 0x34, 0x62, 0x00, 0x7d, 0x34, 0x68, 0x00, 0x43, 0x94, 0x00, 0xff, + 0x24, 0xef, 0x12, 0x94, 0xfe, 0xfe, 0xb6, 0x0c, 0xe2, 0x40, 0xfb, 0xfe, + 0x98, 0xce, 0x01, 0xed, 0xb5, 0x0c, 0x02, 0xef, 0xd0, 0x45, 0x9d, 0x30, + 0x66, 0x00, 0x24, 0xef, 0x9b, 0x6e, 0x94, 0x0c, 0x11, 0x18, 0x38, 0x00, + 0xd0, 0x45, 0x11, 0x18, 0x39, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x94, 0x0c, + 0x42, 0x30, 0xc1, 0x19, 0xc2, 0x45, 0xb3, 0x30, 0x24, 0x00, 0x12, 0x44, + 0x02, 0xef, 0xb1, 0x6e, 0x95, 0x0c, 0xd0, 0x45, 0x5d, 0x38, 0x60, 0x00, + 0x7d, 0x34, 0x60, 0x00, 0x5d, 0x34, 0x66, 0x00, 0x43, 0xb4, 0xad, 0xff, + 0x24, 0xef, 0xd5, 0xce, 0xb6, 0x0c, 0x71, 0x02, 0x50, 0x99, 0x33, 0x32, + 0x02, 0x00, 0x02, 0xef, 0xb1, 0x0c, 0xf0, 0x45, 0x33, 0x6e, 0xfc, 0x86, + 0x13, 0x18, 0x02, 0x00, 0xd5, 0x45, 0x13, 0x18, 0x03, 0x00, 0x12, 0x44, + 0x02, 0xef, 0xaf, 0x6e, 0x91, 0x0c, 0xd0, 0x45, 0x5d, 0x38, 0x5c, 0x00, + 0x7d, 0x34, 0x5c, 0x00, 0x5d, 0x34, 0x64, 0x00, 0x43, 0x94, 0x56, 0xfe, + 0x40, 0x02, 0x90, 0x13, 0x54, 0xce, 0x00, 0x0c, 0x74, 0xd0, 0xff, 0xff, + 0xb9, 0x8d, 0x54, 0x00, 0x00, 0x40, 0xa4, 0x41, 0xff, 0x00, 0x84, 0x50, + 0x00, 0xff, 0x94, 0x44, 0xb1, 0x25, 0xd3, 0x44, 0x2f, 0x2d, 0x73, 0x32, + 0x10, 0x00, 0x33, 0x02, 0x50, 0x89, 0x02, 0xef, 0xad, 0x6e, 0x9d, 0x30, + 0x3e, 0x00, 0xd0, 0x45, 0x5d, 0xf8, 0x58, 0x00, 0xb1, 0x0c, 0x02, 0xef, + 0xd0, 0x45, 0x9d, 0x30, 0x66, 0x00, 0x0c, 0xef, 0x9b, 0x6e, 0x97, 0x0c, + 0x10, 0x88, 0xf0, 0x45, 0x11, 0x88, 0x97, 0x0c, 0xd5, 0x45, 0xb4, 0x30, + 0x0c, 0x00, 0x12, 0x44, 0xb6, 0x0c, 0x97, 0x0c, 0x0c, 0xef, 0xd0, 0x45, + 0x5d, 0x38, 0x60, 0x00, 0x02, 0xef, 0xb1, 0x6e, 0xf0, 0x45, 0x91, 0x0c, + 0x7d, 0x34, 0x60, 0x00, 0x5d, 0x34, 0x66, 0x00, 0x43, 0x94, 0x1a, 0xfe, + 0x40, 0x02, 0x90, 0x13, 0x18, 0xce, 0x00, 0x0c, 0xd0, 0xcf, 0x2f, 0x2d, + 0x44, 0x14, 0x28, 0x00, 0xe2, 0x40, 0x1c, 0x00, 0xf1, 0x4f, 0x64, 0x45, + 0xb2, 0x41, 0x09, 0x80, 0x24, 0x0e, 0x00, 0x0e, 0x52, 0x32, 0x79, 0x1a, + 0x02, 0x25, 0x04, 0x05, 0x22, 0x25, 0x22, 0x05, 0x82, 0x60, 0x2e, 0x00, + 0xc0, 0x0c, 0x8e, 0xee, 0x82, 0x60, 0x2b, 0x10, 0xf2, 0x45, 0x00, 0x6c, + 0x51, 0x14, 0x28, 0x00, 0x50, 0x00, 0x90, 0x13, 0xa2, 0x40, 0xee, 0xff, + 0x24, 0x45, 0x08, 0x47, 0xbf, 0x45, 0x00, 0x0c, 0xf1, 0x4f, 0x64, 0x45, + 0x64, 0x60, 0x03, 0x00, 0x64, 0x60, 0x00, 0x10, 0x63, 0x30, 0xf4, 0xff, + 0x83, 0x40, 0x3b, 0x00, 0x46, 0x6c, 0x09, 0xcc, 0x81, 0xee, 0x50, 0x60, + 0x07, 0x00, 0x50, 0x60, 0x04, 0x10, 0xa7, 0x05, 0x83, 0x40, 0x31, 0x00, + 0x20, 0x04, 0x50, 0x60, 0x03, 0x00, 0x50, 0x60, 0x00, 0x10, 0xa2, 0xb4, + 0xf2, 0xff, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x14, 0x34, 0x4d, 0x1e, 0x8d, + 0xa2, 0x41, 0x10, 0x80, 0x50, 0x14, 0x28, 0x00, 0x17, 0x8d, 0xb2, 0x41, + 0x09, 0x80, 0x20, 0x0e, 0x52, 0x32, 0x79, 0x1a, 0x12, 0x25, 0x14, 0x05, + 0x22, 0x25, 0x20, 0x05, 0x82, 0x60, 0x2e, 0x00, 0xc0, 0x0c, 0x8e, 0xee, + 0x82, 0x60, 0x2b, 0x10, 0xf2, 0x45, 0x90, 0x6c, 0x50, 0x14, 0x28, 0x00, + 0x51, 0x00, 0x90, 0x13, 0x70, 0xad, 0x12, 0x25, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xc5, 0x1c, 0xe2, 0x45, 0x90, 0x0c, 0x40, 0x0c, 0x24, 0x45, + 0x08, 0x47, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe7, 0x24, 0xe2, 0x45, + 0x00, 0x0c, 0x40, 0x0c, 0x24, 0x45, 0x08, 0x47, 0xf1, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0xdf, 0x1d, 0x55, 0x45, 0x04, 0x0e, 0xe2, 0x45, + 0x25, 0x0e, 0x20, 0x29, 0x60, 0x30, 0x88, 0x00, 0x42, 0xd0, 0x8c, 0x00, + 0x62, 0x94, 0x03, 0x00, 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, 0xb9, 0x41, + 0x09, 0x80, 0x94, 0x6e, 0x90, 0x0c, 0x01, 0xef, 0x39, 0x33, 0x79, 0x1a, + 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, 0xd5, 0x4f, 0x3d, 0x23, + 0x30, 0xd0, 0x04, 0xfe, 0x74, 0x00, 0x84, 0x0e, 0xc5, 0x0e, 0x70, 0xfe, + 0x00, 0x00, 0x13, 0xb4, 0x40, 0x00, 0xa6, 0x0e, 0x8e, 0x69, 0x30, 0x32, + 0x3c, 0x00, 0x83, 0x14, 0x1c, 0x00, 0x43, 0x60, 0x17, 0x00, 0x86, 0xc8, + 0x43, 0x60, 0x14, 0x10, 0x62, 0x0c, 0x14, 0x29, 0x34, 0x05, 0xc2, 0x03, + 0x00, 0x20, 0x5e, 0x00, 0x50, 0xf1, 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, + 0x00, 0x18, 0x5c, 0xfe, 0x7c, 0x82, 0xfe, 0x32, 0x20, 0x00, 0xa0, 0x30, + 0xd0, 0x00, 0x52, 0x30, 0x01, 0x00, 0x5c, 0xf8, 0x7c, 0x82, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x51, 0x1e, 0xe2, 0x45, 0x97, 0x0c, 0x2b, 0xad, + 0x81, 0xed, 0x5c, 0xfc, 0x84, 0x82, 0x5c, 0xfa, 0x7c, 0x82, 0x10, 0xad, + 0x7f, 0xed, 0x5c, 0xfc, 0x7c, 0x82, 0xa2, 0x40, 0xbe, 0x00, 0xfa, 0x40, + 0x04, 0x00, 0x7a, 0xfc, 0xa0, 0x00, 0x86, 0xad, 0x7f, 0xed, 0x00, 0x00, + 0x7c, 0x57, 0x00, 0x00, 0x00, 0x18, 0x7f, 0xed, 0x3d, 0x23, 0x30, 0x50, + 0x16, 0x47, 0x01, 0xed, 0x53, 0x94, 0x08, 0x00, 0x00, 0x0c, 0x50, 0x14, + 0x51, 0x00, 0x82, 0x6c, 0x81, 0xed, 0x00, 0x0e, 0xc2, 0xcf, 0x46, 0xc8, + 0x50, 0x14, 0x4e, 0x00, 0x84, 0x6c, 0x81, 0xed, 0x00, 0x0e, 0xbb, 0xcf, + 0x46, 0xc8, 0x02, 0xee, 0x82, 0x60, 0x0b, 0x80, 0x82, 0x60, 0x08, 0x90, + 0xe2, 0x62, 0x03, 0x80, 0xe2, 0x62, 0x00, 0x90, 0x62, 0x60, 0x07, 0x80, + 0x62, 0x60, 0x04, 0x90, 0x83, 0xed, 0x62, 0x60, 0x0f, 0x80, 0x62, 0x60, + 0x0c, 0x90, 0xde, 0x33, 0x14, 0x00, 0xc2, 0x63, 0x13, 0x80, 0xc2, 0x63, + 0x10, 0x90, 0xa2, 0x62, 0x17, 0x80, 0xa6, 0x6d, 0xa2, 0x62, 0x14, 0x90, + 0x67, 0xc8, 0x15, 0x94, 0x95, 0x00, 0x02, 0x18, 0x19, 0x00, 0x66, 0x48, + 0xa7, 0x48, 0xb7, 0x41, 0x10, 0x80, 0x62, 0x18, 0x1b, 0x00, 0x74, 0x14, + 0x78, 0x00, 0x46, 0xc8, 0xf6, 0x0c, 0x57, 0x30, 0x89, 0x1c, 0x6e, 0x87, + 0xa4, 0xca, 0x65, 0xc8, 0xc2, 0x45, 0x5d, 0xf8, 0x20, 0x00, 0xd1, 0xff, + 0x00, 0x00, 0xd1, 0x97, 0x41, 0x00, 0x46, 0x48, 0x1e, 0x94, 0x3e, 0x00, + 0xa4, 0x41, 0x10, 0x80, 0x64, 0x30, 0xd1, 0x1c, 0xa4, 0x41, 0x10, 0x80, + 0x69, 0xc8, 0x64, 0x30, 0x45, 0x1e, 0xa4, 0x41, 0x10, 0x80, 0x6a, 0xc8, + 0x64, 0x30, 0x3f, 0x1e, 0x6b, 0xc8, 0x94, 0x2a, 0x46, 0xc8, 0x48, 0x48, + 0xde, 0x6e, 0x94, 0xaa, 0xde, 0xfc, 0x00, 0x00, 0xbe, 0xfc, 0x04, 0x00, + 0x1e, 0xf8, 0x00, 0x00, 0x1e, 0xf8, 0x04, 0x00, 0xe1, 0xea, 0x50, 0xeb, + 0x1e, 0xfd, 0x74, 0x00, 0xd4, 0x14, 0x78, 0x00, 0xa7, 0x48, 0xe8, 0xfe, + 0x00, 0x00, 0x9e, 0x0c, 0xc5, 0xc8, 0xf6, 0x0c, 0xa4, 0xca, 0xe2, 0x45, + 0xd7, 0x0c, 0x17, 0x94, 0x38, 0x00, 0x46, 0x48, 0x46, 0xc8, 0x49, 0x48, + 0xe2, 0x45, 0x9e, 0x0c, 0x4a, 0x48, 0x9e, 0x0c, 0xc2, 0x45, 0x1e, 0xf8, + 0x44, 0x00, 0xd1, 0xff, 0x00, 0x00, 0xd1, 0x97, 0x03, 0x00, 0x46, 0x48, + 0xbe, 0x40, 0xd1, 0xff, 0x13, 0x94, 0x42, 0x00, 0xa3, 0x41, 0x10, 0x80, + 0x62, 0x14, 0x19, 0x00, 0xa8, 0xad, 0x82, 0x0c, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x3f, 0x1e, 0xe2, 0x45, 0x00, 0x0c, 0x7c, 0xfc, 0x84, 0x82, + 0x5c, 0xfa, 0x7c, 0x82, 0x03, 0xb4, 0x5e, 0xff, 0x40, 0x0c, 0x7c, 0xfc, + 0x7c, 0x82, 0xa3, 0x40, 0x59, 0xff, 0xfa, 0x40, 0x04, 0x00, 0x7a, 0xfc, + 0xa0, 0x00, 0xa3, 0x40, 0x53, 0xff, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, + 0x00, 0x18, 0x4e, 0xcf, 0x40, 0x0c, 0x4c, 0xcf, 0x7f, 0xed, 0x9e, 0xfc, + 0x74, 0x00, 0x46, 0xc8, 0x4b, 0x48, 0xe2, 0x45, 0x4e, 0x6a, 0xc2, 0xcf, + 0x46, 0x48, 0xa2, 0x60, 0x03, 0x00, 0xa2, 0x60, 0x00, 0x10, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x4f, 0x23, 0xe2, 0x45, 0x00, 0x0c, 0xd6, 0xcf, + 0x7c, 0xfc, 0x84, 0x82, 0x74, 0xfc, 0x10, 0x00, 0x63, 0xfc, 0xd0, 0x00, + 0xb5, 0x69, 0x67, 0xcf, 0x62, 0x18, 0x18, 0x00, 0x0e, 0x6a, 0x63, 0x30, + 0x3f, 0x1e, 0xc3, 0x45, 0x5d, 0xf8, 0x18, 0x00, 0xb9, 0xcf, 0x46, 0x48, + 0xd5, 0x4f, 0x5d, 0x14, 0x6c, 0x00, 0x3d, 0x23, 0x30, 0xd0, 0xc5, 0x0e, + 0xc6, 0x0f, 0x04, 0x0e, 0x85, 0x32, 0x14, 0x00, 0x06, 0xb4, 0xe3, 0x00, + 0x48, 0xc8, 0x64, 0xfe, 0x74, 0x00, 0x73, 0xfc, 0x38, 0x00, 0x43, 0x60, + 0x17, 0x00, 0x43, 0x60, 0x14, 0x10, 0x02, 0x94, 0xd5, 0x00, 0xa0, 0x32, + 0x39, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x91, 0x1f, 0xb7, 0x41, + 0x08, 0x80, 0xb1, 0x41, 0x01, 0x80, 0x4a, 0xc8, 0xa2, 0x41, 0x09, 0x80, + 0xb2, 0x41, 0x09, 0x80, 0xf7, 0x32, 0x88, 0x03, 0x31, 0x32, 0xbd, 0xa4, + 0x8d, 0xcc, 0x4b, 0xc8, 0x73, 0xfc, 0x38, 0x00, 0x57, 0x60, 0x27, 0x00, + 0xc6, 0x03, 0x50, 0x31, 0x62, 0x26, 0x57, 0x60, 0x24, 0x10, 0x83, 0x00, + 0x50, 0x51, 0x06, 0xef, 0x20, 0x6d, 0x57, 0x60, 0x27, 0x80, 0x57, 0x60, + 0x24, 0x90, 0x57, 0x60, 0x17, 0x00, 0x57, 0x60, 0x14, 0x10, 0x2e, 0x6d, + 0x57, 0x60, 0x17, 0x80, 0x57, 0x60, 0x14, 0x90, 0xb6, 0x14, 0x0d, 0x00, + 0x6a, 0x14, 0x3e, 0x00, 0x4a, 0x15, 0x3d, 0x00, 0x58, 0x25, 0xb0, 0x25, + 0x43, 0x01, 0x90, 0x1a, 0x54, 0x05, 0x54, 0x00, 0x50, 0x11, 0xb1, 0x26, + 0xa0, 0x89, 0xa1, 0x8a, 0xb3, 0xfc, 0x38, 0x00, 0x56, 0x15, 0x0d, 0x00, + 0xca, 0x06, 0x45, 0x14, 0x41, 0x00, 0xa5, 0x14, 0x40, 0x00, 0x6a, 0x00, + 0x00, 0x20, 0x20, 0x25, 0xd5, 0x44, 0xa8, 0x48, 0x43, 0x01, 0x50, 0x19, + 0x74, 0x00, 0x50, 0x19, 0x55, 0x05, 0x2f, 0x2d, 0xa1, 0x26, 0x32, 0x89, + 0xb3, 0x8a, 0x73, 0xfc, 0x38, 0x00, 0xb6, 0x14, 0x0d, 0x00, 0x46, 0x06, + 0x64, 0x14, 0x3f, 0x00, 0x58, 0x25, 0x54, 0x05, 0x54, 0x00, 0x50, 0x11, + 0xa4, 0x89, 0x56, 0x14, 0x0d, 0x00, 0xb3, 0xfc, 0x38, 0x00, 0x28, 0x26, + 0x28, 0x06, 0x94, 0x00, 0x50, 0x21, 0x8a, 0x4c, 0xd1, 0x45, 0xa5, 0x30, + 0x2a, 0x00, 0x56, 0x14, 0x0d, 0x00, 0xb3, 0xfc, 0x38, 0x00, 0x06, 0xef, + 0x28, 0x26, 0x28, 0x06, 0x94, 0x00, 0x50, 0x21, 0x84, 0x30, 0x0b, 0x00, + 0xd1, 0x45, 0xa5, 0x30, 0x30, 0x00, 0x70, 0x34, 0x30, 0x00, 0x56, 0x14, + 0x0d, 0x00, 0x31, 0x26, 0x76, 0x18, 0x10, 0x00, 0x96, 0x18, 0x11, 0x00, + 0x70, 0x1c, 0x3a, 0x00, 0x20, 0x6d, 0x56, 0x18, 0x0d, 0x00, 0x32, 0x25, + 0x34, 0x05, 0x26, 0x25, 0x34, 0x05, 0x24, 0x25, 0x2f, 0x2d, 0xa1, 0x25, + 0x56, 0x18, 0x12, 0x00, 0x76, 0x18, 0x13, 0x00, 0x73, 0xfc, 0x38, 0x00, + 0x43, 0x60, 0x17, 0x00, 0xc2, 0x4f, 0x43, 0x60, 0x14, 0x10, 0x5e, 0x00, + 0x90, 0x13, 0x36, 0x8d, 0xb5, 0x32, 0x0a, 0x00, 0xde, 0x00, 0x00, 0x10, + 0xc6, 0x03, 0x50, 0x11, 0x22, 0x25, 0x26, 0x05, 0x82, 0x60, 0x3c, 0x00, + 0x82, 0x60, 0x39, 0x10, 0x6b, 0x8e, 0x52, 0x14, 0x34, 0x4d, 0x02, 0x94, + 0x67, 0xff, 0x4a, 0x48, 0xb6, 0x14, 0x0f, 0x00, 0xc2, 0x45, 0xdd, 0xf8, + 0x24, 0x00, 0x02, 0x94, 0x5d, 0xff, 0xc9, 0x48, 0x4b, 0x48, 0xb3, 0xfc, + 0x38, 0x00, 0x01, 0xee, 0x62, 0x30, 0xe8, 0x4c, 0x3a, 0x69, 0xa5, 0x02, + 0x50, 0x29, 0x20, 0x6d, 0x3a, 0xe9, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xbf, 0x22, 0xe2, 0x45, 0xc2, 0x4f, 0x73, 0xfc, 0x38, 0x00, 0x43, 0x60, + 0x17, 0x00, 0x43, 0x60, 0x14, 0x10, 0x5e, 0x00, 0x90, 0x13, 0x4e, 0xad, + 0xb5, 0x32, 0x0a, 0x00, 0x3d, 0x23, 0x30, 0x50, 0x16, 0x47, 0x01, 0xed, + 0x46, 0x94, 0x92, 0x00, 0x02, 0xed, 0x46, 0xb4, 0xf7, 0xff, 0x00, 0x0c, + 0xc4, 0xff, 0x74, 0x00, 0x5e, 0x14, 0x52, 0x00, 0x71, 0x8d, 0x5e, 0x30, + 0xd3, 0x02, 0xb1, 0x41, 0x08, 0x80, 0xb2, 0x41, 0x01, 0x80, 0x7e, 0x32, + 0xd9, 0x02, 0xfe, 0x32, 0x59, 0x00, 0xa0, 0x0e, 0x31, 0x32, 0x88, 0x03, + 0x52, 0x32, 0xbd, 0xa4, 0x48, 0xc8, 0x71, 0x60, 0x27, 0x00, 0x55, 0x00, + 0x00, 0x10, 0xa2, 0x02, 0x50, 0x11, 0x71, 0x60, 0x24, 0x10, 0x22, 0x25, + 0x5e, 0x00, 0x50, 0x11, 0xb0, 0x6d, 0x71, 0x60, 0x27, 0x80, 0x71, 0x60, + 0x24, 0x90, 0x71, 0x60, 0x17, 0x00, 0xa8, 0x48, 0x06, 0xef, 0x71, 0x60, + 0x14, 0x10, 0xa2, 0x4e, 0xbe, 0x6d, 0x71, 0x60, 0x17, 0x80, 0x71, 0x60, + 0x14, 0x90, 0x16, 0x15, 0x0d, 0x00, 0x82, 0x34, 0x56, 0x00, 0x62, 0x14, + 0x58, 0x00, 0x48, 0x00, 0x00, 0x20, 0x41, 0x26, 0xb0, 0x25, 0xdc, 0x44, + 0x02, 0x01, 0x50, 0x11, 0x54, 0x00, 0x50, 0x11, 0x31, 0x26, 0xa0, 0x89, + 0x21, 0x8a, 0x96, 0x14, 0x0d, 0x00, 0x77, 0x34, 0x01, 0x00, 0x48, 0x25, + 0x44, 0x05, 0x54, 0x00, 0x50, 0x11, 0x31, 0x26, 0xa2, 0x89, 0x23, 0x8a, + 0x76, 0x14, 0x0d, 0x00, 0x97, 0x14, 0x00, 0x00, 0xf7, 0x32, 0x0a, 0x00, + 0x38, 0x25, 0x34, 0x05, 0x54, 0x00, 0x50, 0x11, 0x24, 0x8a, 0x56, 0x14, + 0x0d, 0x00, 0x28, 0x26, 0x28, 0x06, 0x94, 0x00, 0x50, 0x21, 0xf2, 0x45, + 0x8a, 0x4c, 0x56, 0x14, 0x0d, 0x00, 0x06, 0xef, 0xb3, 0x0c, 0x28, 0x26, + 0x28, 0x06, 0x94, 0x00, 0x50, 0x21, 0xd2, 0x45, 0x84, 0x30, 0x0b, 0x00, + 0x70, 0x34, 0x30, 0x00, 0x56, 0x14, 0x0d, 0x00, 0x31, 0x26, 0x76, 0x18, + 0x10, 0x00, 0x96, 0x18, 0x11, 0x00, 0x70, 0x1c, 0x3a, 0x00, 0x20, 0x6d, + 0x56, 0x18, 0x0d, 0x00, 0x32, 0x25, 0x34, 0x05, 0x26, 0x25, 0x34, 0x05, + 0x24, 0x25, 0x2f, 0x2d, 0xa1, 0x25, 0x56, 0x18, 0x12, 0x00, 0x76, 0x18, + 0x13, 0x00, 0x5e, 0x14, 0x52, 0x00, 0x55, 0x00, 0x50, 0x13, 0xa2, 0x40, + 0x8a, 0xff, 0x3d, 0x23, 0x30, 0x50, 0x16, 0x47, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x14, 0x34, 0x4d, 0x0e, 0x8d, 0x24, 0xfe, 0x74, 0x00, 0xa5, 0x14, + 0x0f, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x91, 0x1f, 0xe2, 0x45, + 0x11, 0x6a, 0x02, 0xb4, 0x6f, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x88, 0x03, 0x62, 0x60, 0x27, 0x00, 0xe8, 0x48, + 0xb2, 0x41, 0x01, 0x80, 0x62, 0x60, 0x24, 0x10, 0xb1, 0x30, 0x4f, 0x00, + 0x52, 0x32, 0xbd, 0xa4, 0xb0, 0x6d, 0x62, 0x60, 0x27, 0x80, 0x62, 0x60, + 0x24, 0x90, 0x62, 0x60, 0x17, 0x00, 0x06, 0xef, 0x62, 0x60, 0x14, 0x10, + 0xbe, 0x6d, 0x62, 0x60, 0x17, 0x80, 0x62, 0x60, 0x14, 0x90, 0x96, 0x14, + 0x0d, 0x00, 0x9b, 0x29, 0x48, 0x25, 0x44, 0x05, 0x54, 0x00, 0x50, 0x11, + 0x31, 0x26, 0xa0, 0x89, 0x21, 0x8a, 0x96, 0x14, 0x0d, 0x00, 0x9a, 0x29, + 0x48, 0x25, 0xf7, 0x05, 0xbf, 0x2d, 0x44, 0x05, 0x54, 0x00, 0x50, 0x11, + 0x31, 0x26, 0xa2, 0x89, 0x23, 0x8a, 0x76, 0x14, 0x0d, 0x00, 0x91, 0x14, + 0x4c, 0x00, 0x38, 0x25, 0x34, 0x05, 0x54, 0x00, 0x50, 0x11, 0x24, 0x8a, + 0x56, 0x14, 0x0d, 0x00, 0x28, 0x26, 0x28, 0x06, 0x94, 0x00, 0x50, 0x21, + 0xf2, 0x45, 0x8a, 0x4c, 0x56, 0x14, 0x0d, 0x00, 0xb1, 0x30, 0x55, 0x00, + 0x06, 0xef, 0x28, 0x26, 0x28, 0x06, 0x94, 0x00, 0x50, 0x21, 0xd2, 0x45, + 0x84, 0x30, 0x0b, 0x00, 0x70, 0x34, 0x30, 0x00, 0x56, 0x14, 0x0d, 0x00, + 0x31, 0x26, 0x76, 0x18, 0x10, 0x00, 0x96, 0x18, 0x11, 0x00, 0x70, 0x1c, + 0x3a, 0x00, 0x20, 0x6d, 0x56, 0x18, 0x0d, 0x00, 0x32, 0x25, 0x34, 0x05, + 0x26, 0x25, 0x34, 0x05, 0x24, 0x25, 0x2f, 0x2d, 0xa1, 0x25, 0x56, 0x18, + 0x12, 0x00, 0x76, 0x18, 0x13, 0x00, 0x3d, 0x23, 0x30, 0x50, 0x16, 0x47, + 0x42, 0x30, 0xe8, 0x4c, 0xaa, 0x69, 0x89, 0x6e, 0x01, 0xee, 0xb0, 0x6d, + 0xaa, 0xe9, 0x1b, 0x29, 0x91, 0x69, 0x5d, 0x38, 0x14, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0xbf, 0x22, 0xc2, 0x45, 0x7d, 0xf8, 0x10, 0x00, + 0xd5, 0xce, 0x00, 0x0c, 0x64, 0x60, 0x0f, 0x00, 0x8f, 0xee, 0x64, 0x60, + 0x0c, 0x10, 0xa3, 0x94, 0x05, 0x00, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, + 0x29, 0xfd, 0xb9, 0x45, 0xf5, 0x4f, 0xa3, 0x41, 0x09, 0x80, 0x63, 0xfc, + 0xac, 0x9b, 0xe5, 0xcb, 0x44, 0x0c, 0x63, 0xfc, 0x38, 0x02, 0x7f, 0xee, + 0xbf, 0x69, 0xa3, 0xfc, 0x0c, 0x0b, 0x54, 0xea, 0xa3, 0xfc, 0x0c, 0x0b, + 0x53, 0xea, 0x82, 0x14, 0x14, 0x00, 0x17, 0xae, 0x81, 0xee, 0x83, 0xfc, + 0x0c, 0x0b, 0x04, 0xf8, 0x1c, 0x01, 0x82, 0x60, 0x18, 0x00, 0xa3, 0xfc, + 0x0c, 0x0b, 0x64, 0x0c, 0x62, 0x60, 0x15, 0x10, 0xd3, 0xe9, 0x82, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe7, 0x24, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0x40, 0x0c, 0x06, 0x47, 0xa4, 0x94, 0x10, 0x00, 0x82, 0xee, + 0xa4, 0x94, 0x23, 0x00, 0x90, 0xee, 0x83, 0xee, 0xa4, 0x94, 0x22, 0x00, + 0xc0, 0xee, 0x84, 0xee, 0xa4, 0xb4, 0xe9, 0xff, 0xa0, 0x30, 0x80, 0x00, + 0x05, 0xcc, 0x83, 0xfc, 0x0c, 0x0b, 0x83, 0xfc, 0x0c, 0x0b, 0x88, 0xee, + 0xa4, 0xf8, 0x1c, 0x01, 0x82, 0x60, 0x18, 0x00, 0xa3, 0xfc, 0x0c, 0x0b, + 0x64, 0x0c, 0x62, 0x60, 0x15, 0x10, 0x82, 0x0c, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xe7, 0x24, 0xe2, 0x45, 0xd4, 0xe9, 0xe5, 0x4b, 0x40, 0x0c, + 0x06, 0x47, 0xec, 0xcf, 0x83, 0xfc, 0x0c, 0x0b, 0xe9, 0xcf, 0x83, 0xfc, + 0x0c, 0x0b, 0x00, 0x0c, 0x44, 0xb0, 0xb1, 0x00, 0xe2, 0x40, 0x1f, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x60, 0x49, 0x82, 0x00, 0x18, 0x21, + 0xa4, 0x45, 0x9f, 0x45, 0x36, 0xed, 0x9f, 0x45, 0x01, 0xed, 0x9f, 0x45, + 0x02, 0xed, 0x9f, 0x45, 0x05, 0xed, 0x9f, 0x45, 0x06, 0xed, 0x9f, 0x45, + 0x09, 0xed, 0x9f, 0x45, 0x0b, 0xed, 0x9f, 0x45, 0x0c, 0xed, 0x9f, 0x45, + 0x12, 0xed, 0x9f, 0x45, 0x18, 0xed, 0x9f, 0x45, 0x24, 0xed, 0x9f, 0x45, + 0x30, 0xed, 0x9f, 0x45, 0x40, 0x0c, 0x00, 0x0c, 0xed, 0x4f, 0x66, 0x45, + 0x2e, 0x4a, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xe1, 0xd1, 0x44, 0xfe, + 0x70, 0x00, 0x24, 0xca, 0xe2, 0x45, 0x05, 0x0e, 0x71, 0xfc, 0x0c, 0x0b, + 0x7f, 0xed, 0xb4, 0x69, 0x43, 0x94, 0x07, 0x00, 0x00, 0x0c, 0x50, 0x14, + 0x58, 0x00, 0x02, 0xb4, 0x4c, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xb2, 0x34, + 0x00, 0x00, 0xa5, 0xd0, 0x0c, 0x00, 0xa3, 0xae, 0x60, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0xa3, 0x41, 0x09, 0x80, 0x63, 0x30, 0x0d, 0x27, 0xc3, 0x45, + 0x82, 0xfc, 0x38, 0x4d, 0x90, 0x14, 0x54, 0x00, 0xe3, 0x45, 0xc2, 0x0c, + 0xc2, 0x00, 0x90, 0x13, 0x12, 0x8d, 0x65, 0x0c, 0xe2, 0x25, 0xbd, 0x2d, + 0x50, 0x30, 0x54, 0x00, 0xb0, 0x30, 0x58, 0x00, 0x05, 0xee, 0x8b, 0xef, + 0x86, 0x94, 0x33, 0x00, 0x00, 0x0c, 0xa0, 0x89, 0x20, 0x6d, 0xa2, 0xb4, + 0xf9, 0xff, 0x00, 0x0c, 0x84, 0xed, 0xa4, 0x41, 0x09, 0x80, 0x44, 0x14, + 0x54, 0x4d, 0xb0, 0x05, 0x14, 0x8d, 0x03, 0x18, 0x64, 0x00, 0x50, 0x30, + 0x54, 0x00, 0xc0, 0x30, 0x80, 0x00, 0x10, 0x32, 0x58, 0x00, 0xa4, 0x30, + 0x54, 0x4d, 0xa0, 0x09, 0x83, 0xd0, 0xf0, 0x00, 0xc4, 0x94, 0x07, 0x00, + 0x00, 0x0c, 0x20, 0x6d, 0x02, 0xb6, 0xf7, 0xff, 0x00, 0x0c, 0x26, 0x45, + 0x0a, 0x47, 0xb7, 0x2d, 0xba, 0x05, 0xb1, 0x09, 0xf6, 0xcf, 0x62, 0x18, + 0x10, 0x00, 0x42, 0x14, 0xa6, 0x9a, 0x02, 0xb4, 0xb2, 0xff, 0x01, 0xed, + 0x50, 0x18, 0x5c, 0x00, 0xae, 0xcf, 0x50, 0x18, 0x60, 0x00, 0xce, 0xcf, + 0xa0, 0x8b, 0x00, 0x0c, 0xc1, 0x69, 0x3b, 0x69, 0x22, 0x2d, 0xa2, 0x40, + 0x41, 0x00, 0xa3, 0xfc, 0x70, 0x00, 0x16, 0xed, 0xc5, 0x14, 0x18, 0x00, + 0x46, 0x94, 0x3a, 0x00, 0x00, 0x0c, 0x44, 0x69, 0xe2, 0x40, 0x36, 0x00, + 0x42, 0xfc, 0x78, 0x00, 0x42, 0x00, 0xec, 0x01, 0xe2, 0x40, 0x30, 0x00, + 0xf1, 0x4f, 0x55, 0x45, 0xd0, 0x28, 0x51, 0xd0, 0x00, 0x40, 0x17, 0xad, + 0x04, 0x0e, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, 0x6d, 0x66, 0xe2, 0x45, + 0x83, 0x0c, 0xe2, 0x40, 0x0d, 0x00, 0x05, 0x69, 0x0b, 0x8d, 0x51, 0xd0, + 0xfc, 0x00, 0x42, 0x30, 0x60, 0xff, 0x42, 0xd0, 0xdc, 0xff, 0xe2, 0x40, + 0x50, 0x00, 0x14, 0xcc, 0x40, 0x30, 0xf3, 0xff, 0x81, 0x69, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x8d, 0x66, 0xe2, 0x45, 0x83, 0x0c, 0x3a, 0xad, + 0xa2, 0x41, 0x03, 0x80, 0x31, 0xd2, 0xfc, 0x00, 0x40, 0x30, 0xd0, 0x00, + 0x51, 0x94, 0x06, 0x00, 0x00, 0x0c, 0x40, 0x0c, 0x15, 0x45, 0x08, 0x47, + 0x9f, 0x45, 0x40, 0x0c, 0x05, 0x69, 0x7a, 0xad, 0x40, 0x0c, 0x81, 0x69, + 0x43, 0xfc, 0x48, 0x00, 0x42, 0xb0, 0x19, 0x00, 0x73, 0xad, 0x40, 0x0c, + 0xa3, 0xfc, 0x70, 0x00, 0x50, 0x2a, 0x64, 0xd0, 0xfc, 0x00, 0x43, 0x30, + 0x60, 0xff, 0x42, 0xd0, 0xdc, 0xff, 0xe2, 0x40, 0xd2, 0xff, 0x23, 0xb6, + 0xe5, 0xff, 0x40, 0x0c, 0x84, 0xd0, 0x00, 0x40, 0x61, 0xae, 0x40, 0x30, + 0xf3, 0xff, 0x65, 0x14, 0x18, 0x00, 0x43, 0xb0, 0x16, 0x00, 0x25, 0xad, + 0xa2, 0x41, 0x30, 0x00, 0x40, 0x30, 0x7f, 0x00, 0x43, 0x94, 0xd3, 0xff, + 0x40, 0x30, 0xf3, 0xff, 0xd1, 0xcf, 0x00, 0x0c, 0x42, 0x30, 0xad, 0x66, + 0xe2, 0x45, 0x01, 0x6a, 0x42, 0x40, 0xc2, 0xff, 0x51, 0xd0, 0xfc, 0x00, + 0xae, 0xcf, 0x42, 0x30, 0x60, 0xff, 0x01, 0x69, 0x83, 0x69, 0xa2, 0xfc, + 0x70, 0x00, 0xc2, 0xfc, 0x48, 0x00, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0xb5, 0xd5, 0xc2, 0x45, 0x83, 0xfc, 0x2c, 0x01, 0xb7, 0xcf, 0x40, 0x30, + 0xf3, 0xff, 0x42, 0x50, 0x90, 0x88, 0x43, 0x00, 0x50, 0x10, 0x42, 0x00, + 0x2c, 0x00, 0x02, 0xb4, 0xac, 0xff, 0x40, 0x30, 0xf3, 0xff, 0xaa, 0xcf, + 0x00, 0x0c, 0x00, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x9d, 0x38, + 0x24, 0x00, 0xeb, 0xcb, 0x1d, 0xef, 0x96, 0xee, 0x42, 0x30, 0xf5, 0x22, + 0x04, 0xc8, 0x05, 0xc8, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0xe2, 0x45, + 0x09, 0x6e, 0xeb, 0x4b, 0x0c, 0x47, 0x00, 0x0c, 0x44, 0x20, 0x04, 0x10, + 0xa5, 0x41, 0x09, 0x80, 0xc3, 0xfc, 0xe8, 0x06, 0x42, 0xfc, 0x70, 0x00, + 0x88, 0xed, 0xc5, 0xf8, 0x14, 0x4d, 0x20, 0x29, 0xa2, 0xd0, 0x0c, 0x00, + 0x65, 0x94, 0x07, 0x00, 0x42, 0xd0, 0x00, 0x40, 0xb9, 0x41, 0x03, 0x80, + 0x39, 0x33, 0x85, 0x7a, 0xb9, 0x45, 0x7c, 0xad, 0xb9, 0x41, 0x03, 0x80, + 0x45, 0x69, 0x78, 0x8d, 0x04, 0xed, 0xc4, 0x69, 0x63, 0xfc, 0x74, 0x00, + 0x43, 0xb4, 0xf4, 0xff, 0x39, 0x33, 0x85, 0x7a, 0xa3, 0x41, 0x09, 0x80, + 0x43, 0xfc, 0xdc, 0x4c, 0x20, 0x6d, 0x43, 0xf8, 0xdc, 0x4c, 0x9f, 0x45, + 0x01, 0xed, 0x00, 0x0c, 0xe5, 0x4f, 0x3d, 0x23, 0x10, 0xd0, 0x44, 0x60, + 0x2b, 0x00, 0xc5, 0x0e, 0x56, 0x32, 0x20, 0x01, 0x44, 0x60, 0x28, 0x10, + 0x24, 0x0e, 0x92, 0x0c, 0xa2, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x9b, 0x1f, 0xe2, 0x45, 0xc6, 0x0f, 0x02, 0x94, 0x43, 0x00, 0xe2, 0x0e, + 0x51, 0x14, 0x13, 0x05, 0x71, 0x14, 0x12, 0x05, 0x20, 0x25, 0xd3, 0x44, + 0x0b, 0xad, 0xb9, 0x41, 0x03, 0x80, 0xde, 0x0c, 0xb6, 0x0c, 0x91, 0x0c, + 0x39, 0x33, 0x21, 0xc8, 0x3d, 0x23, 0x10, 0x50, 0x99, 0x45, 0x1d, 0x4c, + 0x96, 0x32, 0x78, 0x00, 0xb3, 0x41, 0x05, 0x80, 0x73, 0x32, 0x59, 0x5e, + 0xf3, 0x45, 0x94, 0x0c, 0xa2, 0x0e, 0xf3, 0x45, 0x82, 0x0c, 0xb4, 0x96, + 0x10, 0x00, 0xb5, 0x0c, 0xb5, 0x41, 0x10, 0x80, 0x02, 0x0e, 0xb5, 0x32, + 0x0b, 0x13, 0xa5, 0x30, 0x48, 0x00, 0xf5, 0x45, 0x92, 0x0c, 0xf3, 0x45, + 0x90, 0x0c, 0xb0, 0x0c, 0xb4, 0xb4, 0xf7, 0xff, 0x02, 0x0e, 0xa2, 0x41, + 0x09, 0x80, 0xd7, 0x0c, 0xb1, 0x0c, 0x42, 0x30, 0x75, 0xe7, 0xe2, 0x45, + 0x9e, 0x0c, 0xb9, 0x41, 0x03, 0x80, 0xde, 0x0c, 0xb6, 0x0c, 0x91, 0x0c, + 0x39, 0x33, 0x21, 0xc8, 0x3d, 0x23, 0x10, 0x50, 0x99, 0x45, 0x1d, 0x4c, + 0x40, 0x30, 0xea, 0xff, 0x3d, 0x23, 0x10, 0x50, 0x0e, 0x47, 0x00, 0x0c, + 0xe1, 0x4f, 0x81, 0xed, 0x46, 0xb0, 0x1e, 0x00, 0xbd, 0x22, 0x28, 0xd0, + 0x64, 0xc8, 0x05, 0xc8, 0x06, 0xc8, 0x08, 0xad, 0x07, 0xc8, 0x44, 0xfc, + 0x98, 0x04, 0xe2, 0x40, 0x03, 0x00, 0xa8, 0x69, 0x84, 0x8d, 0x45, 0x0e, + 0xbd, 0x22, 0x28, 0x50, 0x10, 0x47, 0xa0, 0x6a, 0xa2, 0x41, 0x01, 0x80, + 0x24, 0x0e, 0xa5, 0x30, 0x30, 0x00, 0x11, 0x6e, 0x06, 0x0e, 0x42, 0x30, + 0xbd, 0xa4, 0xe2, 0x45, 0x06, 0xef, 0x1d, 0x15, 0x20, 0x00, 0xb2, 0x14, + 0x11, 0x00, 0x72, 0x14, 0x10, 0x00, 0x9d, 0x14, 0x21, 0x00, 0xf2, 0x14, + 0x12, 0x00, 0x5d, 0x14, 0x22, 0x00, 0xdd, 0x14, 0x23, 0x00, 0x32, 0x15, + 0x13, 0x00, 0x65, 0x44, 0x03, 0x01, 0x10, 0x1b, 0xbd, 0x14, 0x24, 0x00, + 0x12, 0x15, 0x14, 0x00, 0xdc, 0x44, 0x57, 0x44, 0x9d, 0x14, 0x25, 0x00, + 0xf2, 0x14, 0x15, 0x00, 0xd3, 0x44, 0x26, 0x01, 0x10, 0x33, 0xd6, 0x44, + 0x05, 0x01, 0x10, 0x2b, 0xd5, 0x44, 0xe4, 0x00, 0x10, 0x1b, 0xd3, 0x44, + 0x2d, 0x2d, 0xa2, 0x40, 0xc7, 0xff, 0x51, 0xfc, 0x98, 0x04, 0x72, 0x34, + 0x18, 0x00, 0x26, 0x2a, 0x83, 0xb4, 0xc0, 0xff, 0x00, 0x0c, 0x83, 0xee, + 0x72, 0x36, 0x1a, 0x00, 0xa3, 0x94, 0x23, 0x00, 0x92, 0x36, 0x1c, 0x00, + 0xa7, 0x2a, 0x65, 0xb6, 0xb5, 0xff, 0x00, 0x0c, 0x14, 0xb4, 0x46, 0x00, + 0xc4, 0xb0, 0x07, 0x00, 0xe6, 0x40, 0x63, 0x00, 0x64, 0xb0, 0x02, 0x00, + 0xe3, 0x40, 0x1e, 0x00, 0xe4, 0x40, 0x1c, 0x00, 0x01, 0xed, 0x44, 0xb4, + 0x61, 0x00, 0x5c, 0xfc, 0xdc, 0x81, 0x04, 0xed, 0x45, 0x94, 0x60, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x4a, 0x84, 0x42, 0x30, 0x57, 0x15, 0xe2, 0x45, + 0x91, 0x0c, 0x98, 0xcf, 0x00, 0x0c, 0xa7, 0x29, 0x73, 0x00, 0x90, 0x1b, + 0x03, 0xb4, 0x92, 0xff, 0x73, 0xb0, 0x03, 0x00, 0xe3, 0x40, 0x8e, 0xff, + 0xb4, 0x40, 0x6a, 0x00, 0x91, 0xfc, 0x30, 0x01, 0x06, 0xc8, 0x64, 0xfc, + 0xf4, 0x00, 0x63, 0xfc, 0xf0, 0x00, 0x86, 0x8d, 0x09, 0x6f, 0xc3, 0x45, + 0xb1, 0x30, 0x00, 0x06, 0x51, 0xfc, 0x98, 0x04, 0x26, 0x2a, 0x83, 0xed, + 0x64, 0xb4, 0x44, 0x00, 0x82, 0xed, 0x73, 0x94, 0x6e, 0x00, 0x00, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x4a, 0x84, 0x42, 0x30, 0xbd, 0x12, 0xc2, 0x45, + 0x91, 0xfc, 0x2c, 0x01, 0x6d, 0xcf, 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, + 0x4a, 0x84, 0x42, 0x30, 0xbd, 0x12, 0xc2, 0x45, 0x91, 0xfc, 0x2c, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0x82, 0x86, 0x42, 0x30, 0x59, 0x16, 0xe2, 0x45, + 0x00, 0x0c, 0x91, 0xfc, 0x30, 0x01, 0x01, 0xed, 0x46, 0xc8, 0x44, 0xfc, + 0xf4, 0x00, 0x9d, 0x3a, 0x1c, 0x00, 0x42, 0xfc, 0xf0, 0x00, 0xe2, 0x40, + 0x51, 0xff, 0x09, 0x6f, 0xc2, 0x45, 0xb1, 0x30, 0x00, 0x06, 0x4c, 0xcf, + 0x00, 0x0c, 0x80, 0x30, 0x80, 0x00, 0x83, 0x94, 0xbb, 0xff, 0x00, 0x0c, + 0x5c, 0xfc, 0xdc, 0x81, 0x20, 0x6d, 0x42, 0xcf, 0x5c, 0xf8, 0xdc, 0x81, + 0x91, 0xfc, 0x30, 0x01, 0x06, 0xc8, 0x44, 0xfc, 0xf4, 0x00, 0x62, 0xfc, + 0xf0, 0x00, 0x03, 0xb4, 0xb4, 0xff, 0x09, 0x6f, 0xa2, 0x41, 0x10, 0x80, + 0x91, 0x6e, 0x42, 0x30, 0xa9, 0x17, 0xe2, 0x45, 0x91, 0x0c, 0xa2, 0x40, + 0xb7, 0xff, 0x91, 0xfc, 0x30, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x1d, 0x1f, 0xc2, 0x45, 0x84, 0x30, 0x54, 0x04, 0x23, 0xcf, 0x00, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xbd, 0x12, 0x4a, 0x84, 0xc2, 0x45, + 0x91, 0xfc, 0x2c, 0x01, 0x4c, 0xed, 0x54, 0x94, 0x17, 0xff, 0x00, 0x0c, + 0x01, 0xed, 0x53, 0xb4, 0xb1, 0xff, 0xa2, 0x41, 0x10, 0x80, 0x54, 0x30, + 0x82, 0xff, 0x42, 0xb0, 0x02, 0x00, 0xe2, 0x40, 0xa7, 0xff, 0x0a, 0xcf, + 0x00, 0x0c, 0xa7, 0x29, 0x63, 0x96, 0xd0, 0xff, 0x81, 0xed, 0x8e, 0xcf, + 0xa9, 0xe9, 0x00, 0x0c, 0xa9, 0x4e, 0x3d, 0x23, 0x88, 0xd2, 0xa4, 0xfe, + 0x30, 0x01, 0xe4, 0xfe, 0x9c, 0x04, 0x04, 0x0e, 0x95, 0x34, 0x0c, 0x00, + 0xa2, 0x41, 0x09, 0x80, 0x66, 0x0e, 0x42, 0x30, 0x71, 0x29, 0x85, 0x0e, + 0x47, 0x0e, 0xc2, 0x45, 0x1d, 0xf8, 0x78, 0x02, 0x33, 0x36, 0x1c, 0x00, + 0x53, 0x34, 0x18, 0x00, 0x31, 0xd2, 0xff, 0x07, 0x5d, 0xf8, 0x80, 0x02, + 0x1e, 0x6d, 0x42, 0xb0, 0xd7, 0x07, 0x02, 0x94, 0x18, 0x01, 0x01, 0xed, + 0x10, 0xf8, 0xac, 0x04, 0x57, 0xfc, 0x00, 0x00, 0x60, 0x0c, 0xb2, 0x30, + 0xe2, 0xff, 0x42, 0x30, 0x30, 0x00, 0x48, 0xc8, 0xd3, 0x33, 0x10, 0x00, + 0x40, 0x0c, 0xb2, 0x41, 0x10, 0x80, 0xfd, 0x30, 0x50, 0x01, 0xc0, 0x0c, + 0x93, 0x30, 0x1e, 0x00, 0x52, 0x32, 0x7d, 0x1c, 0x65, 0xc8, 0x06, 0xc8, + 0xc7, 0xcb, 0xd2, 0x45, 0x5d, 0xf8, 0x10, 0x00, 0x5d, 0xfc, 0x68, 0x01, + 0x02, 0x94, 0xef, 0x01, 0xbd, 0xfc, 0x60, 0x01, 0x05, 0x94, 0xf8, 0x01, + 0x30, 0x3a, 0xa6, 0x04, 0x5d, 0x14, 0x4c, 0x02, 0x42, 0xb0, 0x05, 0x00, + 0x03, 0xad, 0x80, 0x0c, 0x54, 0x0a, 0x4f, 0x26, 0x90, 0x18, 0x84, 0x05, + 0x57, 0xfc, 0x3c, 0x00, 0x04, 0x8d, 0x5d, 0xfc, 0x88, 0x01, 0xe2, 0x40, + 0x03, 0x01, 0x50, 0xfc, 0xc4, 0x04, 0x28, 0x2e, 0x04, 0x94, 0xdf, 0x00, + 0xbd, 0xfc, 0x8c, 0x01, 0x42, 0xd0, 0x00, 0x08, 0x02, 0x94, 0xe3, 0x00, + 0xc0, 0x0e, 0x90, 0xfc, 0x30, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x0b, 0x1f, 0xc2, 0x45, 0x84, 0x30, 0x54, 0x04, 0xa2, 0x41, 0x10, 0x80, + 0xb4, 0x30, 0x30, 0x00, 0x42, 0x30, 0x15, 0x24, 0xe2, 0x45, 0x90, 0x0c, + 0x02, 0x94, 0xe5, 0x01, 0x42, 0x0e, 0x50, 0xfc, 0x5c, 0x07, 0x02, 0x94, + 0xf2, 0x01, 0x90, 0xfc, 0x30, 0x01, 0x20, 0x69, 0xcd, 0x69, 0x20, 0x69, + 0x42, 0x30, 0x32, 0x00, 0x24, 0x25, 0x26, 0x05, 0x21, 0x6b, 0x06, 0x94, + 0x9f, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x50, 0xfc, 0xc4, 0x04, 0x42, 0x00, + 0x2c, 0x04, 0x0a, 0xad, 0x5d, 0xfc, 0xa0, 0x01, 0x02, 0x94, 0x92, 0x00, + 0x5d, 0xfc, 0xa4, 0x01, 0x02, 0x94, 0x90, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x5d, 0x30, 0x78, 0x02, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x65, 0x25, 0xd8, 0x84, 0xc2, 0x45, 0x9d, 0x30, 0x50, 0x01, 0x54, 0xfc, + 0x18, 0x00, 0x25, 0x8d, 0x01, 0xed, 0x50, 0x18, 0x08, 0x07, 0x54, 0xfc, + 0x18, 0x00, 0x62, 0x14, 0x30, 0x00, 0x70, 0x18, 0x09, 0x07, 0x62, 0x14, + 0x31, 0x00, 0x70, 0x18, 0x0a, 0x07, 0x62, 0x14, 0x32, 0x00, 0x70, 0x18, + 0x0b, 0x07, 0x62, 0x14, 0x33, 0x00, 0x70, 0x18, 0x0c, 0x07, 0x62, 0x14, + 0x34, 0x00, 0x70, 0x18, 0x0d, 0x07, 0x42, 0x14, 0x35, 0x00, 0x50, 0x18, + 0x0e, 0x07, 0x54, 0x14, 0x38, 0x00, 0x50, 0x18, 0x10, 0x07, 0x54, 0x14, + 0x37, 0x00, 0x50, 0x18, 0x0f, 0x07, 0x5d, 0xfc, 0x10, 0x02, 0xe2, 0x40, + 0x09, 0x00, 0x20, 0x09, 0x62, 0x00, 0x3c, 0x2b, 0x03, 0x40, 0x04, 0x00, + 0x29, 0x25, 0x20, 0x6d, 0x52, 0x18, 0xa3, 0x06, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x6f, 0x21, 0xe2, 0x45, 0x92, 0x0c, 0x50, 0xfc, 0xc4, 0x04, + 0x2c, 0x2d, 0x02, 0xb4, 0x64, 0x01, 0xa2, 0x41, 0x02, 0x80, 0x12, 0x18, + 0xae, 0x06, 0x5d, 0xfc, 0x88, 0x01, 0x02, 0x94, 0x88, 0x01, 0x40, 0x0c, + 0x55, 0x34, 0x60, 0x00, 0x42, 0xb0, 0x04, 0x00, 0x42, 0xb0, 0x01, 0x00, + 0xc2, 0x0f, 0x52, 0x18, 0xa0, 0x06, 0xa2, 0x41, 0x01, 0x80, 0x15, 0x6e, + 0xc0, 0x30, 0xc8, 0x00, 0x42, 0x30, 0x51, 0xa8, 0xe2, 0x45, 0xa0, 0x0c, + 0xf2, 0xfc, 0x3c, 0x06, 0x90, 0xfc, 0x2c, 0x01, 0xa2, 0x41, 0x10, 0x80, + 0xb2, 0x30, 0x30, 0x06, 0xc4, 0xcb, 0x15, 0x6f, 0x42, 0x30, 0x75, 0x12, + 0xe7, 0xb0, 0x01, 0x00, 0xc2, 0x45, 0xbe, 0x41, 0x10, 0x80, 0xde, 0x33, + 0x2d, 0x24, 0x83, 0xee, 0xfe, 0x45, 0x92, 0x0c, 0xe2, 0x40, 0x9d, 0x00, + 0xb1, 0x41, 0x10, 0x80, 0x31, 0x32, 0xef, 0x10, 0xf1, 0x45, 0x92, 0x0c, + 0x02, 0xb4, 0x03, 0x01, 0x5c, 0xfc, 0xd4, 0x81, 0xf1, 0x45, 0x92, 0x0c, + 0x90, 0xfc, 0x30, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x1d, 0x1f, + 0xc2, 0x45, 0x84, 0x30, 0x54, 0x04, 0x00, 0x0e, 0xa3, 0x41, 0x10, 0x80, + 0x63, 0x30, 0x3f, 0x1e, 0xe3, 0x45, 0x96, 0x0c, 0x50, 0x0c, 0x3d, 0x23, + 0x88, 0x52, 0x9f, 0x45, 0x59, 0x4d, 0x20, 0x0e, 0xe9, 0xce, 0x50, 0xf8, + 0xac, 0x04, 0x9e, 0x8e, 0xbd, 0xfc, 0x90, 0x01, 0x9b, 0x8e, 0x42, 0xd0, + 0x00, 0x08, 0x02, 0xb4, 0xd9, 0x00, 0x5d, 0xfc, 0x88, 0x01, 0x5d, 0xfc, + 0x94, 0x01, 0x12, 0x8d, 0x5d, 0xfc, 0x98, 0x01, 0x0f, 0x8d, 0xc0, 0x0e, + 0x04, 0xb4, 0x15, 0xff, 0x5d, 0xfc, 0x88, 0x01, 0x07, 0x8d, 0x5d, 0xfc, + 0x8c, 0x01, 0x04, 0x8d, 0xbd, 0xfc, 0x90, 0x01, 0xa5, 0x40, 0x0b, 0xff, + 0xd3, 0xcf, 0x00, 0x0e, 0xf4, 0xfc, 0x08, 0x00, 0x07, 0x94, 0xd1, 0x00, + 0xa2, 0x41, 0x10, 0x80, 0x74, 0x6a, 0xa0, 0xee, 0x4c, 0x6e, 0x42, 0x30, + 0x4b, 0x1e, 0xc2, 0x45, 0xfd, 0xf8, 0x84, 0x02, 0xfd, 0xfc, 0x84, 0x02, + 0xc2, 0x0e, 0x82, 0x0c, 0x74, 0x6b, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0xbd, 0xa4, 0xa7, 0x0c, 0xe2, 0x45, 0x6c, 0x6f, 0x16, 0x94, 0xb9, 0x00, + 0x60, 0x0c, 0x57, 0xfc, 0x00, 0x00, 0xb6, 0xfc, 0x10, 0x00, 0x42, 0x30, + 0x30, 0x00, 0x48, 0xc8, 0x40, 0x0c, 0x95, 0x6f, 0xc0, 0x0c, 0x96, 0x30, + 0x18, 0x00, 0x65, 0xc8, 0x06, 0xc8, 0xc7, 0xcb, 0xd2, 0x45, 0x5d, 0xf8, + 0x10, 0x00, 0x57, 0xfc, 0x3c, 0x00, 0x09, 0x8d, 0x5d, 0xfc, 0x8c, 0x01, + 0x5d, 0xfc, 0x88, 0x01, 0x02, 0x94, 0x18, 0x01, 0x58, 0x48, 0x5d, 0xfc, + 0x8c, 0x01, 0x02, 0x94, 0xe6, 0x00, 0x79, 0x48, 0x50, 0xfc, 0xc4, 0x04, + 0x28, 0x2e, 0xbd, 0xfc, 0x90, 0x01, 0x05, 0x94, 0xf8, 0x00, 0x7a, 0x48, + 0x7d, 0xfc, 0x94, 0x01, 0x03, 0x94, 0xea, 0x00, 0x7b, 0x48, 0x7d, 0xfc, + 0x98, 0x01, 0x03, 0xb4, 0xa3, 0xff, 0x7c, 0x48, 0x03, 0x94, 0xa0, 0xff, + 0x42, 0xd0, 0x00, 0x08, 0xa2, 0x40, 0x9c, 0xff, 0x9b, 0xcf, 0x7d, 0xf8, + 0x98, 0x01, 0x50, 0xfc, 0xc4, 0x04, 0x24, 0x2d, 0x02, 0x94, 0x7d, 0x00, + 0x84, 0xee, 0x90, 0xfc, 0x30, 0x01, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x1d, 0x1f, 0xc2, 0x45, 0x84, 0x30, 0x54, 0x04, 0x50, 0xfc, 0xc4, 0x04, + 0xff, 0xed, 0x70, 0xf8, 0xf0, 0x04, 0x42, 0xd0, 0x00, 0x40, 0x02, 0xb4, + 0x5a, 0x00, 0x70, 0xf8, 0xf4, 0x04, 0x5d, 0xfc, 0xac, 0x01, 0xfd, 0x14, + 0x54, 0x02, 0xdd, 0xfc, 0x88, 0x01, 0x44, 0xc8, 0xa2, 0x41, 0x10, 0x80, + 0xb0, 0x0c, 0x42, 0x30, 0x15, 0x1b, 0xe2, 0x45, 0x95, 0x0c, 0x02, 0x94, + 0xc1, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x9d, 0xfc, 0x78, 0x02, 0x7d, 0xfc, + 0x1c, 0x02, 0xc4, 0x50, 0x00, 0x20, 0x03, 0x94, 0xa2, 0x00, 0xdd, 0xf8, + 0x78, 0x02, 0x31, 0x09, 0xb0, 0x0a, 0xa6, 0x41, 0x00, 0x01, 0x20, 0x25, + 0xd5, 0x44, 0x50, 0x38, 0xfe, 0x06, 0x32, 0x09, 0xc6, 0x30, 0x00, 0x20, + 0xf4, 0x44, 0x21, 0x2d, 0x50, 0x18, 0x01, 0x07, 0xdd, 0xf8, 0x78, 0x02, + 0x5d, 0xfc, 0x80, 0x02, 0xf8, 0x86, 0x30, 0x3a, 0x12, 0x06, 0x50, 0x38, + 0x2a, 0x06, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x67, 0x1a, 0xe2, 0x45, + 0x00, 0x0c, 0x50, 0x14, 0xf8, 0x04, 0x02, 0xb4, 0x6a, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0xa2, 0x41, 0x10, 0x80, 0xe8, 0x86, 0x42, 0x30, 0xeb, 0x1a, + 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xd9, 0x1a, + 0xe2, 0x45, 0x90, 0x0c, 0x11, 0xcf, 0x01, 0xec, 0x02, 0xb4, 0x38, 0xff, + 0xc0, 0x0e, 0x0c, 0xcf, 0x00, 0x0e, 0x20, 0x6d, 0xfd, 0xce, 0x5c, 0xf8, + 0xd4, 0x81, 0xa2, 0x41, 0x10, 0x80, 0x00, 0x84, 0x42, 0x30, 0x7f, 0x1a, + 0xe2, 0x45, 0x90, 0x0c, 0xb4, 0xcf, 0x9d, 0xfc, 0x78, 0x02, 0x00, 0x0e, + 0x50, 0x0c, 0x3d, 0x23, 0x88, 0x52, 0x9f, 0x45, 0x59, 0x4d, 0xfe, 0x45, + 0x92, 0x0c, 0xe2, 0x40, 0x80, 0xff, 0xde, 0xce, 0xb1, 0x41, 0x10, 0x80, + 0x80, 0x0c, 0x90, 0x18, 0x84, 0x05, 0x57, 0xfc, 0x3c, 0x00, 0x02, 0x94, + 0x14, 0xfe, 0x5d, 0xfc, 0x88, 0x01, 0x0f, 0xce, 0x00, 0x0c, 0x42, 0x30, + 0xd5, 0xf1, 0xe2, 0x45, 0x00, 0x0c, 0x72, 0xfc, 0x78, 0x00, 0x82, 0x0c, + 0xa2, 0x41, 0x02, 0x80, 0x63, 0x50, 0x80, 0x00, 0x42, 0x30, 0xe9, 0xf1, + 0xc2, 0x45, 0x72, 0xf8, 0x78, 0x00, 0x01, 0xed, 0x8e, 0xce, 0x52, 0x18, + 0xae, 0x06, 0x5c, 0xfc, 0xd4, 0x81, 0x90, 0xfc, 0x30, 0x01, 0x00, 0x0e, + 0x20, 0x6d, 0x5c, 0xf8, 0xd4, 0x81, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x1d, 0x1f, 0xc2, 0x45, 0x84, 0x30, 0x54, 0x04, 0xc3, 0xce, 0xa3, 0x41, + 0x10, 0x80, 0x5c, 0xfc, 0xd4, 0x81, 0x20, 0x6d, 0xb3, 0xce, 0x5c, 0xf8, + 0xd4, 0x81, 0x7f, 0xce, 0xc0, 0x0f, 0xb0, 0x0c, 0x42, 0x30, 0x13, 0x1a, + 0xe2, 0x45, 0x95, 0x0c, 0x94, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0xe3, 0x40, + 0x19, 0xff, 0x50, 0xfc, 0xc4, 0x04, 0x28, 0x2e, 0x04, 0xb4, 0x19, 0xff, + 0xbd, 0xfc, 0x90, 0x01, 0x14, 0xcf, 0x7d, 0xf8, 0x8c, 0x01, 0x10, 0x38, + 0xfe, 0x06, 0x6e, 0xcf, 0x10, 0x18, 0x01, 0x07, 0x03, 0x94, 0x15, 0xff, + 0xa2, 0xd0, 0x00, 0x08, 0xa5, 0x40, 0x11, 0xff, 0x10, 0xcf, 0x7d, 0xf8, + 0x94, 0x01, 0xe3, 0x40, 0x07, 0xff, 0xa4, 0x40, 0x05, 0xff, 0x04, 0xcf, + 0x7d, 0xf8, 0x90, 0x01, 0x42, 0x30, 0x7f, 0x1a, 0x88, 0x86, 0xe2, 0x45, + 0x01, 0xef, 0x50, 0xfc, 0xc4, 0x04, 0x42, 0x50, 0x00, 0x40, 0x37, 0xcf, + 0x50, 0xf8, 0xc4, 0x04, 0xe2, 0x40, 0xe7, 0xfe, 0xe6, 0xce, 0x5d, 0xf8, + 0x88, 0x01, 0x00, 0x0c, 0xf5, 0x4f, 0x44, 0x45, 0x52, 0x25, 0xc5, 0x69, + 0xd4, 0x06, 0xd4, 0x26, 0xd6, 0x06, 0x51, 0x68, 0xa2, 0x41, 0x10, 0x80, + 0x05, 0x96, 0x0e, 0x00, 0x42, 0x30, 0xa7, 0x25, 0xe2, 0x45, 0x00, 0x0c, + 0x07, 0x8c, 0x40, 0x0c, 0x0b, 0x69, 0x42, 0x00, 0x40, 0x98, 0x42, 0x70, + 0x01, 0x00, 0x21, 0x2d, 0x04, 0x45, 0x06, 0x47, 0xe2, 0x45, 0x00, 0x0c, + 0x40, 0x0c, 0x04, 0x45, 0x06, 0x47, 0x00, 0x0c, 0xd9, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0x3d, 0x23, 0x28, 0xd0, 0x42, 0x30, 0xa7, 0x25, 0x25, 0x0e, + 0xc4, 0x0e, 0x47, 0xc8, 0xe2, 0x45, 0xe6, 0x0e, 0x71, 0x36, 0xa4, 0x00, + 0x51, 0x34, 0xaa, 0x00, 0xb5, 0x41, 0x09, 0x80, 0xb5, 0x32, 0x35, 0x32, + 0x53, 0x00, 0x3c, 0xbb, 0x02, 0x00, 0x3c, 0x70, 0x91, 0x0c, 0x13, 0x46, + 0x73, 0xd2, 0xff, 0xff, 0xf5, 0x45, 0xb3, 0x0c, 0xa2, 0x40, 0xd5, 0x00, + 0x51, 0x34, 0xa6, 0x00, 0x02, 0x94, 0xd1, 0x00, 0x73, 0x30, 0x01, 0x00, + 0x51, 0x34, 0xaa, 0x00, 0x43, 0x00, 0x3c, 0xab, 0x02, 0x00, 0x3c, 0x70, + 0x12, 0x46, 0x53, 0x96, 0x90, 0x00, 0x65, 0xc8, 0x01, 0xed, 0x44, 0xc8, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xe7, 0x18, 0x46, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0xb4, 0x41, 0x10, 0x80, 0x48, 0xc8, 0xa2, 0x41, 0x09, 0x80, + 0x94, 0x32, 0x45, 0x1e, 0x0e, 0xcc, 0x49, 0xc8, 0x42, 0x4e, 0x20, 0x6d, + 0x44, 0xc8, 0x51, 0x34, 0xaa, 0x00, 0x52, 0x00, 0x3c, 0xab, 0x02, 0x00, + 0x3c, 0x70, 0x12, 0x46, 0x53, 0x96, 0x69, 0x00, 0x00, 0x0c, 0xd2, 0x86, + 0xf5, 0x45, 0x00, 0x0c, 0x6f, 0x8d, 0x44, 0x48, 0xe2, 0x40, 0x11, 0x00, + 0x16, 0x69, 0x42, 0x02, 0x18, 0x19, 0x48, 0x48, 0x82, 0xfc, 0x54, 0x04, + 0x64, 0xed, 0x45, 0x05, 0x34, 0x05, 0x02, 0x40, 0x06, 0x00, 0x49, 0x48, + 0x42, 0xfc, 0x50, 0x4d, 0x02, 0x94, 0x84, 0x00, 0x47, 0x48, 0x91, 0x34, + 0xaa, 0x00, 0x45, 0x48, 0x82, 0x00, 0x3c, 0xab, 0x04, 0x00, 0x3c, 0x70, + 0x10, 0x46, 0x50, 0x96, 0x2e, 0x00, 0x46, 0x48, 0x02, 0x25, 0x95, 0x69, + 0x04, 0x05, 0x24, 0x25, 0x43, 0x00, 0x50, 0xf1, 0x5e, 0xfc, 0x00, 0x00, + 0x5e, 0x94, 0x19, 0x00, 0x00, 0x0c, 0xe2, 0x40, 0x16, 0x00, 0xbe, 0x34, + 0x08, 0x00, 0x82, 0x0c, 0xde, 0x6e, 0xbe, 0x38, 0x08, 0x00, 0x20, 0x6b, + 0xa1, 0x6a, 0x20, 0xe8, 0x21, 0xe8, 0xe1, 0xea, 0xf4, 0x45, 0x50, 0xeb, + 0x5e, 0xfc, 0x00, 0x00, 0x5e, 0x94, 0x03, 0x00, 0x00, 0x0c, 0xa2, 0x40, + 0xec, 0xff, 0x91, 0x34, 0xaa, 0x00, 0x00, 0x6c, 0x90, 0x00, 0x3c, 0xab, + 0x04, 0x00, 0x3c, 0x70, 0x10, 0x46, 0x50, 0xb6, 0xd6, 0xff, 0x02, 0x25, + 0x46, 0x48, 0x52, 0x84, 0xf7, 0x0c, 0xe2, 0x45, 0x96, 0x0c, 0x51, 0x34, + 0xa4, 0x00, 0x64, 0x48, 0x42, 0x4e, 0x04, 0xc8, 0x43, 0x00, 0x50, 0xf1, + 0x51, 0x34, 0xaa, 0x00, 0xde, 0xd3, 0xff, 0x0f, 0x52, 0x00, 0x3c, 0xab, + 0x02, 0x00, 0x3c, 0x70, 0x12, 0x46, 0x53, 0xb6, 0x9a, 0xff, 0xd1, 0x3b, + 0xa4, 0x00, 0x51, 0x34, 0xa6, 0x00, 0x02, 0x94, 0x5a, 0x00, 0xb9, 0x41, + 0x10, 0x80, 0x51, 0x34, 0xaa, 0x00, 0x71, 0x34, 0xa4, 0x00, 0x43, 0x00, + 0x3c, 0xbb, 0x02, 0x00, 0x3c, 0x70, 0x03, 0x46, 0x43, 0xd2, 0xff, 0xff, + 0x12, 0x32, 0xff, 0xff, 0x50, 0x00, 0x3c, 0xab, 0x02, 0x00, 0x3c, 0x70, + 0x02, 0x46, 0x52, 0xb4, 0x12, 0x00, 0x47, 0x48, 0x17, 0xcc, 0x00, 0x0c, + 0x51, 0x34, 0xaa, 0x00, 0x43, 0x00, 0x3c, 0xab, 0x02, 0x00, 0x3c, 0x70, + 0x12, 0x46, 0x50, 0x00, 0x3c, 0xab, 0x02, 0x00, 0x3c, 0x70, 0x02, 0x46, + 0x42, 0x96, 0x08, 0x00, 0x47, 0x48, 0xd2, 0x86, 0xf5, 0x45, 0x00, 0x0c, + 0x6d, 0x8d, 0x72, 0x30, 0x01, 0x00, 0x47, 0x48, 0xe2, 0x45, 0x00, 0x0c, + 0x51, 0xfc, 0xb4, 0x00, 0x22, 0x2d, 0x2d, 0x8d, 0xb9, 0x41, 0x10, 0x80, + 0x3d, 0x23, 0x28, 0x50, 0x14, 0x47, 0xb0, 0x41, 0x10, 0x80, 0x0f, 0xcc, + 0x10, 0x32, 0xe7, 0x18, 0xf0, 0x45, 0x00, 0x0c, 0x71, 0x36, 0xaa, 0x00, + 0x51, 0x34, 0xa4, 0x00, 0x62, 0x02, 0x3c, 0xbb, 0x13, 0x00, 0x3c, 0x70, + 0x13, 0x46, 0x73, 0xd2, 0xff, 0xff, 0xe2, 0x86, 0xf5, 0x45, 0x00, 0x0c, + 0xd3, 0x0c, 0xf7, 0x0c, 0xb1, 0x0c, 0x6c, 0xad, 0x96, 0x0c, 0x51, 0x34, + 0xa6, 0x00, 0x02, 0xb4, 0xaa, 0xff, 0xb9, 0x41, 0x10, 0x80, 0x91, 0x30, + 0x60, 0x00, 0x39, 0x33, 0xc5, 0x13, 0x3d, 0x23, 0x28, 0x50, 0x99, 0x45, + 0x29, 0x4c, 0x96, 0x6a, 0x91, 0x30, 0x60, 0x00, 0x45, 0x02, 0x18, 0x29, + 0x39, 0x33, 0xff, 0x1e, 0x3d, 0x23, 0x28, 0x50, 0xa5, 0x30, 0x65, 0x00, + 0x99, 0x45, 0x29, 0x4c, 0xe1, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0x82, 0xfc, + 0x58, 0xbf, 0x3d, 0x23, 0x18, 0xd0, 0xb2, 0x41, 0x05, 0x80, 0x52, 0x32, + 0x59, 0x5e, 0x84, 0x30, 0x20, 0x02, 0x02, 0x0e, 0xd2, 0x45, 0x5d, 0xf8, + 0x14, 0x00, 0x62, 0x0c, 0x50, 0xfc, 0x58, 0xbf, 0x42, 0x30, 0x20, 0x02, + 0x43, 0x94, 0x50, 0x00, 0x64, 0xc8, 0xb1, 0x41, 0x10, 0x80, 0x31, 0x32, + 0xf3, 0x18, 0xbe, 0x41, 0x09, 0x80, 0xb4, 0x41, 0x09, 0x80, 0x44, 0x48, + 0x01, 0xec, 0x24, 0x69, 0x62, 0xfe, 0x50, 0x02, 0x73, 0x32, 0x70, 0x04, + 0xf2, 0x45, 0x93, 0x0c, 0x53, 0x94, 0x2f, 0x00, 0xe2, 0x0e, 0xc0, 0x0e, + 0xa0, 0x32, 0x10, 0x00, 0x76, 0x30, 0x2c, 0x01, 0xb4, 0x25, 0x77, 0x00, + 0x50, 0x19, 0xb2, 0x69, 0xe3, 0x40, 0x19, 0x00, 0xe3, 0x34, 0xaa, 0x00, + 0xe7, 0x40, 0x11, 0x00, 0xb5, 0x69, 0x30, 0x6a, 0x83, 0xb4, 0x2c, 0x00, + 0xb6, 0x6d, 0x06, 0xcc, 0x80, 0x0c, 0xc3, 0xfc, 0xf4, 0xff, 0xa6, 0xb4, + 0x25, 0x00, 0x00, 0x0c, 0x40, 0x6e, 0xa3, 0x0c, 0xe4, 0xb4, 0xf7, 0xff, + 0xb6, 0x6d, 0x7e, 0xfc, 0x50, 0x4d, 0xa3, 0x40, 0x22, 0x00, 0xc2, 0x4e, + 0xb6, 0xb6, 0xde, 0xff, 0x76, 0x30, 0x2c, 0x01, 0xf2, 0x45, 0x97, 0x0c, + 0x53, 0xb4, 0xd3, 0xff, 0xe2, 0x0e, 0xd2, 0x45, 0x9d, 0xfc, 0x10, 0x00, + 0x62, 0x0c, 0x45, 0x48, 0x64, 0xc8, 0x42, 0xfc, 0x58, 0xbf, 0x42, 0x30, + 0x20, 0x02, 0x43, 0xb4, 0xbb, 0xff, 0x44, 0x48, 0x40, 0x0c, 0x3d, 0x23, + 0x18, 0x50, 0x10, 0x47, 0x74, 0xfc, 0x4c, 0x4d, 0x1e, 0xfa, 0x50, 0x4d, + 0xb0, 0x6d, 0x74, 0xf8, 0x4c, 0x4d, 0xb6, 0x0c, 0xf1, 0x45, 0x97, 0x0c, + 0xda, 0xcf, 0x1e, 0xf8, 0x50, 0x4d, 0x00, 0x0c, 0xed, 0x4f, 0x57, 0x45, + 0x44, 0xfc, 0x30, 0x01, 0x04, 0x0e, 0x2d, 0x69, 0x1c, 0x8d, 0x25, 0x0e, + 0x10, 0x69, 0x01, 0xee, 0xe0, 0x0c, 0xa2, 0x6a, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xf7, 0x11, 0x54, 0x6b, 0xdc, 0x6e, 0x04, 0xc8, 0xc2, 0x45, + 0x1d, 0xf8, 0x14, 0x00, 0xa2, 0x09, 0xb9, 0x41, 0x02, 0x80, 0x98, 0x86, + 0xa2, 0x41, 0x09, 0x80, 0x39, 0x33, 0xed, 0x72, 0x62, 0xf8, 0x38, 0x4d, + 0x17, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x5c, 0xfc, 0xe4, 0x81, 0x20, 0x6d, + 0xe1, 0xcf, 0x5c, 0xf8, 0xe4, 0x81, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, + 0x10, 0x80, 0x64, 0x45, 0x42, 0x30, 0x8f, 0x1c, 0x24, 0x0e, 0x85, 0x0c, + 0x05, 0x0e, 0xc2, 0x45, 0x45, 0xfe, 0x70, 0x00, 0x71, 0xfc, 0x4c, 0x0b, + 0x02, 0xee, 0xb0, 0x6a, 0x85, 0x94, 0x3f, 0x00, 0x01, 0xee, 0x62, 0x60, + 0x21, 0x00, 0x62, 0x60, 0x1e, 0x10, 0x03, 0x40, 0x07, 0x00, 0x01, 0xed, + 0x71, 0x14, 0xb2, 0x0c, 0x43, 0x94, 0x04, 0x00, 0x40, 0x30, 0x88, 0x00, + 0x24, 0x45, 0x08, 0x47, 0x92, 0x34, 0x00, 0x00, 0x64, 0xd0, 0x8c, 0x00, + 0x43, 0xb4, 0xf8, 0xff, 0x60, 0x50, 0xff, 0xff, 0x52, 0x34, 0x10, 0x00, + 0xd2, 0x34, 0x12, 0x00, 0xb2, 0x34, 0x14, 0x00, 0x96, 0x44, 0x95, 0x44, + 0x62, 0x94, 0xec, 0xff, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3d, 0x17, + 0xe2, 0x45, 0x00, 0x0c, 0x22, 0x0e, 0xa2, 0x41, 0x10, 0x80, 0x90, 0x0c, + 0x42, 0x30, 0xaf, 0x23, 0xe2, 0x45, 0x84, 0xee, 0x82, 0x0c, 0xa2, 0x6e, + 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0x15, 0xa8, 0xe2, 0x45, 0xd1, 0x0c, + 0x62, 0x0c, 0x20, 0x29, 0x80, 0x30, 0x00, 0x80, 0xd4, 0x44, 0xd0, 0xcf, + 0x30, 0xa9, 0x63, 0x14, 0x1c, 0x00, 0x83, 0xb4, 0xbe, 0xff, 0x00, 0x0c, + 0x91, 0xfc, 0x74, 0x0b, 0xa4, 0x14, 0x94, 0x00, 0x65, 0x94, 0x15, 0x00, + 0x00, 0x0c, 0x71, 0x14, 0xb2, 0x0c, 0x85, 0xad, 0xa3, 0x41, 0x08, 0x80, + 0xbd, 0xcf, 0x11, 0x18, 0xb2, 0x0c, 0x63, 0xfc, 0x54, 0x04, 0x91, 0xfc, + 0xbc, 0x0c, 0xc7, 0x05, 0x63, 0xb0, 0x65, 0x00, 0xa3, 0x40, 0xa5, 0xff, + 0xb1, 0xcf, 0x11, 0x18, 0xb2, 0x0c, 0x72, 0x34, 0x00, 0x00, 0xa0, 0x30, + 0x88, 0x00, 0xc3, 0xd0, 0x8c, 0x00, 0xa6, 0x94, 0x0b, 0x00, 0x63, 0x50, + 0x00, 0x10, 0x84, 0x14, 0x96, 0x00, 0x81, 0xed, 0x64, 0x94, 0x93, 0xff, + 0x00, 0x0c, 0x9e, 0xcf, 0x11, 0x18, 0xb2, 0x0c, 0x72, 0x38, 0x00, 0x00, + 0xf4, 0xcf, 0x91, 0xfc, 0x74, 0x0b, 0x00, 0x0c, 0xc5, 0x69, 0x01, 0xed, + 0x63, 0x14, 0x1c, 0x06, 0x43, 0x94, 0x02, 0x00, 0x00, 0x0c, 0xbf, 0x45, + 0x50, 0x29, 0x60, 0x30, 0x88, 0x00, 0xc2, 0xd0, 0x8c, 0x00, 0x66, 0xb4, + 0xf8, 0xff, 0x00, 0x0c, 0xf1, 0x4f, 0x55, 0x45, 0x02, 0xd2, 0x00, 0x03, + 0x10, 0x72, 0x00, 0x03, 0x45, 0x30, 0x1e, 0x00, 0xdc, 0x6e, 0x05, 0x02, + 0x18, 0x10, 0x02, 0x0e, 0xa0, 0x08, 0x44, 0x69, 0x97, 0x2c, 0xe2, 0x14, + 0x96, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x02, 0x84, 0x42, 0x30, 0x73, 0x1d, + 0xe2, 0x45, 0x40, 0x6a, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x1f, 0x1d, + 0xe2, 0x45, 0x91, 0x0c, 0x80, 0x29, 0x20, 0x25, 0x63, 0x50, 0x10, 0x00, + 0xd3, 0x44, 0x00, 0xa9, 0x15, 0x45, 0x08, 0x47, 0xd1, 0x4f, 0x3d, 0x23, + 0x38, 0xd0, 0xe4, 0xfe, 0x5c, 0x07, 0xc4, 0xfe, 0x30, 0x01, 0xa4, 0xfe, + 0x9c, 0x04, 0x17, 0x94, 0xcd, 0x00, 0x0c, 0xc8, 0x57, 0xfe, 0x00, 0x00, + 0x76, 0xfc, 0x34, 0x00, 0xa4, 0xfc, 0x5c, 0x07, 0x52, 0xfc, 0x00, 0x00, + 0x20, 0x0e, 0x42, 0x30, 0x32, 0x00, 0x24, 0x25, 0x26, 0x05, 0x8c, 0x8e, + 0xc2, 0xff, 0x04, 0x00, 0x51, 0x69, 0x82, 0xed, 0x22, 0x72, 0x07, 0x00, + 0x31, 0xb2, 0x01, 0x00, 0x42, 0x70, 0x06, 0x00, 0x43, 0x00, 0x58, 0x88, + 0xf5, 0x14, 0x39, 0x00, 0x07, 0xb4, 0xa0, 0x00, 0x84, 0x0e, 0xbe, 0xfc, + 0x10, 0x00, 0x40, 0x0c, 0x00, 0x0e, 0x85, 0x40, 0xbc, 0x00, 0x01, 0xef, + 0xd0, 0x00, 0x10, 0x18, 0x00, 0x6c, 0xb0, 0xb4, 0xfb, 0xff, 0xd3, 0x44, + 0xb0, 0x0c, 0x4c, 0xc8, 0x75, 0xfc, 0xc4, 0x00, 0x56, 0xfc, 0x48, 0x00, + 0xd5, 0x14, 0x38, 0x00, 0x9e, 0xfc, 0x0c, 0x00, 0x34, 0x05, 0x75, 0xfc, + 0xc0, 0x00, 0x42, 0x30, 0xb2, 0x00, 0x64, 0x05, 0x42, 0x26, 0x44, 0x05, + 0x60, 0x00, 0x90, 0x1b, 0x2a, 0x06, 0xb8, 0x25, 0xa2, 0x41, 0x04, 0x80, + 0xff, 0xef, 0xc0, 0x0c, 0xa0, 0x30, 0xd0, 0x00, 0x42, 0x30, 0x11, 0xb0, + 0xe2, 0x45, 0x38, 0x06, 0x02, 0x94, 0x69, 0x00, 0x62, 0x0e, 0xb6, 0xfc, + 0x48, 0x00, 0x73, 0xfc, 0x64, 0x00, 0x93, 0xfc, 0x70, 0x00, 0x54, 0x30, + 0x70, 0x03, 0xd6, 0x05, 0x73, 0xf8, 0x64, 0x00, 0x6c, 0x48, 0x58, 0x06, + 0x93, 0xf8, 0x70, 0x00, 0x5d, 0x20, 0x20, 0xd0, 0x02, 0x0e, 0xa2, 0x41, + 0x09, 0x80, 0xf7, 0x0c, 0xc0, 0x0c, 0xb5, 0x0c, 0x94, 0x0c, 0x42, 0x30, + 0x45, 0x0d, 0x6a, 0xc8, 0xc4, 0xcb, 0x65, 0xca, 0x07, 0xc8, 0xc2, 0x45, + 0x1d, 0xfa, 0x18, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0xc1, 0x0c, + 0xf3, 0x0c, 0xde, 0x0c, 0xb5, 0x0c, 0x94, 0x0c, 0x04, 0xca, 0x05, 0xc8, + 0xc2, 0x45, 0x5d, 0xfa, 0x18, 0x00, 0x54, 0xfc, 0x34, 0x01, 0x2a, 0x2d, + 0x39, 0x8d, 0x5c, 0xfc, 0xe0, 0x81, 0x74, 0xfc, 0x00, 0x06, 0x02, 0xed, + 0x43, 0x94, 0x05, 0x00, 0x5c, 0xfc, 0xd8, 0x81, 0x20, 0x6d, 0x5c, 0xf8, + 0xd8, 0x81, 0x56, 0xfc, 0xf4, 0x00, 0x42, 0xfc, 0x08, 0x01, 0x05, 0x8d, + 0xc0, 0x0c, 0xb4, 0x30, 0x00, 0x06, 0xe2, 0x45, 0x96, 0x0c, 0x73, 0xfc, + 0x14, 0x00, 0xa2, 0x41, 0x01, 0x00, 0xd3, 0x44, 0x53, 0xf8, 0x14, 0x00, + 0x56, 0xfc, 0x40, 0x00, 0x42, 0x00, 0x2c, 0x04, 0x06, 0x8d, 0xa2, 0x41, + 0x11, 0x00, 0x20, 0x6d, 0xda, 0x44, 0x73, 0xf8, 0x14, 0x00, 0x54, 0xfc, + 0x5c, 0x07, 0x28, 0x8d, 0x07, 0xef, 0x20, 0x69, 0xee, 0x86, 0xa0, 0x6b, + 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0x8d, 0x8a, 0xc2, 0x45, 0x1d, 0xf8, + 0x10, 0x00, 0x3d, 0x23, 0x38, 0x50, 0x18, 0x47, 0x20, 0x6d, 0xdb, 0xcf, + 0x5c, 0xf8, 0xe0, 0x81, 0x19, 0x6d, 0xd5, 0xfc, 0x04, 0x00, 0x44, 0xc8, + 0xa2, 0x41, 0x10, 0x80, 0xbe, 0x0c, 0x42, 0x30, 0x03, 0x18, 0xe2, 0x45, + 0x97, 0x0c, 0x02, 0x0e, 0x63, 0xcf, 0xa2, 0x0c, 0x5c, 0xfc, 0xd4, 0x81, + 0x3d, 0x23, 0x38, 0x50, 0x20, 0x6d, 0x5c, 0xf8, 0xd4, 0x81, 0x18, 0x47, + 0x5c, 0xfc, 0xd4, 0x81, 0x20, 0x6d, 0x5c, 0xf8, 0xd4, 0x81, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x45, 0x1e, 0xe2, 0x45, 0x93, 0x0c, 0xd7, 0xcf, + 0x00, 0x0c, 0x4c, 0xcf, 0xa0, 0x0c, 0x00, 0x0c, 0xe5, 0x4f, 0x79, 0x45, + 0x44, 0x14, 0x79, 0x00, 0x14, 0x8d, 0x04, 0x0e, 0x84, 0xfc, 0x74, 0x00, + 0x06, 0x8e, 0x01, 0xed, 0xc0, 0x69, 0x43, 0x94, 0x7f, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x10, 0xf8, 0x74, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xd1, 0x1c, 0xe2, 0x45, 0x90, 0x0c, 0x39, 0x45, 0x0e, 0x47, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x14, 0x1d, 0x4d, 0x81, 0xed, 0x44, 0xfe, 0x6c, 0x00, + 0x62, 0x94, 0x20, 0x00, 0x24, 0xfe, 0x70, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x01, 0xef, 0x42, 0x30, 0xe9, 0x1c, 0xe2, 0x45, 0xa0, 0x0c, 0xe5, 0x8c, + 0x88, 0xed, 0x10, 0x29, 0x42, 0xd0, 0x0c, 0x00, 0x62, 0x94, 0xdf, 0xff, + 0x40, 0x02, 0x0c, 0xd8, 0xa2, 0x41, 0x00, 0x80, 0x52, 0xb4, 0xd9, 0xff, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x31, 0x14, 0xc2, 0x45, 0x90, 0xfc, + 0x6c, 0x00, 0xd3, 0xcf, 0xa2, 0x41, 0x10, 0x80, 0x64, 0xfe, 0x74, 0x00, + 0x73, 0xfc, 0x00, 0x00, 0x43, 0x94, 0x4b, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0xac, 0xad, 0x42, 0x30, 0x88, 0x03, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x88, 0x03, 0x73, 0xfc, 0x38, 0x00, 0x82, 0x60, 0x23, 0x00, 0xa3, 0x60, + 0x17, 0x00, 0x82, 0x60, 0x20, 0x10, 0xc4, 0x0c, 0x85, 0x0c, 0x83, 0x60, + 0x14, 0x10, 0xa3, 0x30, 0x39, 0x00, 0x4c, 0x06, 0x82, 0x60, 0x23, 0x80, + 0x82, 0x60, 0x20, 0x90, 0x83, 0x60, 0x17, 0x00, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xbf, 0x22, 0x83, 0x60, 0x14, 0x10, 0xe2, 0x45, 0x4d, 0x2e, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3f, 0x1e, 0xc2, 0x45, 0x93, 0xfc, + 0x38, 0x00, 0xb5, 0xcf, 0x00, 0x0c, 0x62, 0x60, 0x23, 0x00, 0xd3, 0x14, + 0x52, 0x00, 0xb3, 0x30, 0x53, 0x00, 0x62, 0x60, 0x20, 0x10, 0xe6, 0x05, + 0x62, 0x60, 0x23, 0x80, 0x62, 0x60, 0x20, 0x90, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0xbf, 0x22, 0xe2, 0x45, 0x86, 0x0c, 0xa0, 0xcf, 0x00, 0x0c, + 0x42, 0x30, 0x31, 0x14, 0xe2, 0x45, 0x00, 0x0c, 0x80, 0xcf, 0x10, 0xf8, + 0x74, 0x00, 0x42, 0x30, 0x88, 0x03, 0x62, 0x60, 0x23, 0x00, 0xf3, 0xfc, + 0x04, 0x00, 0xd3, 0x34, 0x16, 0x00, 0x62, 0x60, 0x20, 0x10, 0x89, 0x6e, + 0x01, 0xee, 0xb0, 0x6d, 0x62, 0x60, 0x23, 0x80, 0x62, 0x60, 0x20, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xbf, 0x22, 0xe4, 0xc8, 0xc2, 0x45, + 0xdd, 0x38, 0x14, 0x00, 0x7e, 0xcf, 0x00, 0x0c, 0x44, 0x14, 0x42, 0x06, + 0x64, 0x14, 0x41, 0x06, 0xb9, 0x41, 0x03, 0x80, 0x20, 0x25, 0xd3, 0x44, + 0x39, 0x33, 0x21, 0xca, 0xa3, 0x41, 0x09, 0x80, 0x99, 0x45, 0x43, 0x38, + 0x72, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x8f, 0x1c, 0x64, 0x45, 0x05, 0x0e, 0x46, 0x0e, 0xe2, 0x45, 0x27, 0x0e, + 0x62, 0x60, 0x21, 0x00, 0x62, 0x60, 0x1e, 0x10, 0x03, 0x40, 0x07, 0x00, + 0x81, 0xed, 0x50, 0x14, 0xb2, 0x0c, 0x62, 0x94, 0x04, 0x00, 0x80, 0x30, + 0x88, 0x00, 0x24, 0x45, 0x08, 0x47, 0x90, 0x29, 0x63, 0xd0, 0x8c, 0x00, + 0x83, 0xb4, 0xf9, 0xff, 0x80, 0x50, 0xff, 0xff, 0x98, 0x29, 0x19, 0x2b, + 0x9a, 0x2a, 0x9e, 0x44, 0x9d, 0x44, 0x83, 0x94, 0xf0, 0xff, 0x00, 0x0c, + 0x52, 0x18, 0x6a, 0x00, 0xec, 0xcf, 0x52, 0x18, 0x71, 0x00, 0x00, 0x0c, + 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0xd8, 0x9b, 0xe2, 0x40, 0x66, 0x02, + 0xcd, 0x4f, 0x3d, 0x23, 0x40, 0xd0, 0xa1, 0x68, 0xa6, 0x02, 0x00, 0x18, + 0xd5, 0x00, 0x50, 0x81, 0x51, 0x30, 0xb8, 0x00, 0x04, 0x24, 0x60, 0x04, + 0x8c, 0xc8, 0x4e, 0xc8, 0x82, 0x0c, 0xa2, 0x41, 0x05, 0x80, 0x04, 0x24, + 0x42, 0x30, 0xf1, 0x4b, 0xc5, 0x0f, 0xff, 0xee, 0x46, 0x0e, 0xea, 0xc8, + 0xc2, 0x45, 0x5d, 0xf8, 0x3c, 0x00, 0x02, 0x05, 0x82, 0xfe, 0x4c, 0x03, + 0x10, 0x32, 0x4c, 0x03, 0x02, 0x04, 0x90, 0x96, 0x48, 0x02, 0xa2, 0x41, + 0x05, 0x80, 0x14, 0x94, 0x42, 0x02, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x30, + 0xd0, 0x00, 0x42, 0x30, 0x51, 0x1e, 0xc2, 0x45, 0x80, 0x30, 0x12, 0x01, + 0x02, 0x94, 0x41, 0x02, 0xc2, 0x0e, 0xe2, 0x32, 0x0c, 0x00, 0x40, 0x30, + 0x06, 0x01, 0x56, 0xf8, 0x04, 0x00, 0xf6, 0xfa, 0x08, 0x00, 0x74, 0xfe, + 0x70, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x3d, 0x17, 0x13, 0x35, + 0x00, 0x00, 0x88, 0x0c, 0xc2, 0x45, 0x1d, 0xf9, 0x2c, 0x00, 0x51, 0xfd, + 0x14, 0x00, 0x0b, 0x49, 0xe0, 0x0c, 0x20, 0x31, 0x01, 0x00, 0x02, 0xef, + 0x87, 0x30, 0xd2, 0x02, 0x27, 0x01, 0x10, 0x28, 0x44, 0x26, 0x45, 0x01, + 0x50, 0x2a, 0xb2, 0x8e, 0x42, 0x06, 0x64, 0xfd, 0x04, 0x00, 0x13, 0x17, + 0x0a, 0x00, 0xb3, 0x14, 0x0b, 0x00, 0xab, 0x15, 0x49, 0x01, 0xeb, 0x15, + 0x48, 0x01, 0x93, 0x15, 0x0c, 0x00, 0x8b, 0x14, 0x4a, 0x01, 0x2b, 0x17, + 0x4b, 0x01, 0xd3, 0x15, 0x0d, 0x00, 0xf8, 0x01, 0x10, 0x7b, 0xa5, 0x01, + 0x10, 0x2b, 0x0b, 0x17, 0x4c, 0x01, 0xb3, 0x15, 0x0e, 0x00, 0xaf, 0x00, + 0x90, 0x2a, 0x8c, 0x00, 0x10, 0x23, 0xeb, 0x15, 0x4d, 0x01, 0x93, 0x15, + 0x0f, 0x00, 0xe5, 0x44, 0x2e, 0x03, 0x10, 0x73, 0xc4, 0x01, 0x90, 0x22, + 0x0d, 0x03, 0x10, 0x5b, 0x64, 0x01, 0x90, 0x22, 0xec, 0x01, 0x10, 0x2b, + 0xe5, 0x44, 0x4d, 0x2e, 0xe4, 0x40, 0x05, 0x00, 0xf0, 0x6f, 0xc7, 0xb4, + 0xc5, 0xff, 0x87, 0x30, 0xd2, 0x02, 0x91, 0xfc, 0x0c, 0x0b, 0x40, 0x6a, + 0x87, 0x00, 0x50, 0x23, 0x04, 0x94, 0xce, 0x01, 0xff, 0xed, 0x47, 0xd1, + 0xff, 0x00, 0xeb, 0xc8, 0xa8, 0xd0, 0x0c, 0x00, 0x08, 0xee, 0x85, 0x94, + 0xf1, 0x00, 0x28, 0xd1, 0x8c, 0x00, 0xc0, 0x30, 0x88, 0x00, 0xc9, 0x94, + 0xeb, 0x00, 0x80, 0x0c, 0xf4, 0xfc, 0x48, 0x00, 0xc7, 0xb0, 0x18, 0x00, + 0xa6, 0x40, 0x29, 0x00, 0x74, 0xfd, 0x70, 0x00, 0xcb, 0x14, 0x04, 0x00, + 0x61, 0x2f, 0x23, 0xaf, 0x18, 0xef, 0xc7, 0x94, 0x20, 0x00, 0x00, 0x0c, + 0xeb, 0x34, 0x00, 0x00, 0x87, 0xd1, 0xfc, 0x00, 0xcc, 0x30, 0x60, 0xff, + 0xc6, 0xd0, 0xdc, 0xff, 0x06, 0x94, 0xc0, 0x00, 0xc0, 0x30, 0xd0, 0x00, + 0xcc, 0xb4, 0x11, 0x00, 0xe7, 0xd0, 0x00, 0x40, 0xa7, 0x40, 0xb8, 0x00, + 0xeb, 0x14, 0x18, 0x00, 0xc7, 0xb0, 0x16, 0x00, 0x06, 0xb4, 0xaa, 0x00, + 0xa6, 0x41, 0x30, 0x00, 0xc0, 0x30, 0x7f, 0x00, 0xc7, 0xb4, 0xac, 0x00, + 0x00, 0x0c, 0x05, 0x94, 0x3d, 0x01, 0xa8, 0xd0, 0x00, 0x40, 0x08, 0xd1, + 0xfc, 0x00, 0xa0, 0x30, 0x80, 0x00, 0xa8, 0x94, 0xaf, 0x00, 0x00, 0x0c, + 0xd0, 0xee, 0xa8, 0x94, 0xab, 0x00, 0x00, 0x0c, 0x84, 0xee, 0xb6, 0x60, + 0x17, 0x80, 0xb6, 0x60, 0x14, 0x90, 0x6c, 0x48, 0xa0, 0x30, 0x06, 0x01, + 0xb6, 0x60, 0x0f, 0x80, 0xb6, 0x60, 0x0c, 0x90, 0x56, 0x19, 0x20, 0x00, + 0x76, 0x18, 0x21, 0x00, 0xd6, 0x1b, 0x4a, 0x00, 0x56, 0x62, 0x25, 0x80, + 0x56, 0x62, 0x22, 0x90, 0x16, 0x60, 0x29, 0x80, 0x16, 0x60, 0x26, 0x90, + 0x16, 0x18, 0x76, 0x00, 0xb4, 0xfc, 0x70, 0x00, 0x82, 0x00, 0x50, 0xf1, + 0xa2, 0x41, 0x01, 0x80, 0xde, 0x0c, 0x96, 0x30, 0x7e, 0x00, 0x42, 0x30, + 0xbd, 0xa4, 0xc2, 0x45, 0x3d, 0xf9, 0x34, 0x00, 0x55, 0x02, 0x50, 0x21, + 0x44, 0x26, 0x6b, 0x48, 0x4c, 0x48, 0x44, 0x02, 0x50, 0x21, 0x44, 0x26, + 0xd6, 0x63, 0x7b, 0x80, 0x42, 0x06, 0xd6, 0x63, 0x78, 0x90, 0x44, 0x20, + 0x5c, 0x93, 0xd4, 0xff, 0x2c, 0x00, 0xea, 0x48, 0xd0, 0x0c, 0x5e, 0x30, + 0x6c, 0x01, 0x4b, 0xc8, 0xa2, 0x41, 0x10, 0x80, 0xb7, 0x0c, 0x94, 0x0c, + 0x42, 0x30, 0x61, 0x14, 0xc2, 0x45, 0x3d, 0xfa, 0x10, 0x00, 0xa2, 0x41, + 0x09, 0x80, 0x9e, 0x86, 0x42, 0x30, 0xed, 0x3a, 0xf3, 0x0c, 0xe2, 0x45, + 0xd7, 0x0c, 0x2d, 0x49, 0x40, 0x30, 0x88, 0x00, 0x49, 0x94, 0xab, 0x00, + 0x80, 0x0c, 0x55, 0x02, 0x50, 0x11, 0x24, 0x25, 0x42, 0x02, 0x50, 0x11, + 0x24, 0x25, 0x84, 0x30, 0x6f, 0x01, 0x22, 0x05, 0x46, 0x26, 0x02, 0xf8, + 0x98, 0x03, 0x42, 0x06, 0x41, 0x6a, 0x03, 0xed, 0x44, 0x94, 0xba, 0x00, + 0x00, 0x0c, 0x55, 0x02, 0x50, 0x11, 0x24, 0x25, 0x42, 0x02, 0x50, 0x11, + 0x24, 0x25, 0x22, 0x05, 0x82, 0xfc, 0x4c, 0x03, 0x90, 0x94, 0xcc, 0x00, + 0xc4, 0xff, 0x00, 0x00, 0xb5, 0x41, 0x10, 0x80, 0x08, 0xcc, 0xb5, 0x32, + 0x51, 0x21, 0x9e, 0x0c, 0xd0, 0x97, 0x3e, 0x00, 0x5e, 0xfc, 0x00, 0x00, + 0xc2, 0x0f, 0x4a, 0x48, 0xf7, 0x0c, 0x1e, 0x84, 0x49, 0xc8, 0x4b, 0x48, + 0x44, 0xca, 0x05, 0xca, 0xc6, 0xca, 0x67, 0xca, 0xd5, 0x45, 0x5d, 0xf8, + 0x20, 0x00, 0x42, 0x40, 0xec, 0xff, 0xe2, 0x0c, 0x47, 0x0c, 0x3d, 0x23, + 0x40, 0x50, 0x1a, 0x47, 0xc6, 0x50, 0x90, 0x88, 0xc7, 0x00, 0x50, 0x30, + 0xc6, 0x00, 0x2c, 0x00, 0xa6, 0x40, 0x55, 0xff, 0xa8, 0xd0, 0x00, 0x40, + 0x05, 0x94, 0x55, 0xff, 0x81, 0xee, 0xb6, 0x18, 0x77, 0x00, 0x08, 0xd1, + 0xfc, 0x00, 0xa0, 0x30, 0x80, 0x00, 0xa8, 0xb4, 0x53, 0xff, 0x44, 0x6e, + 0x55, 0xcf, 0x44, 0x6e, 0xc8, 0xd0, 0x00, 0x40, 0x06, 0x94, 0x12, 0xff, + 0x80, 0x0c, 0x94, 0xfc, 0x30, 0x00, 0xe4, 0x40, 0x87, 0x00, 0x4d, 0x0a, + 0x04, 0x94, 0x84, 0x00, 0x01, 0xef, 0x08, 0xcf, 0xd6, 0x18, 0x77, 0x00, + 0x4f, 0x48, 0xb2, 0x41, 0x09, 0x80, 0xff, 0xee, 0x92, 0x30, 0xc4, 0x9b, + 0xc2, 0x45, 0xfd, 0xf8, 0x28, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0x9c, 0xbd, 0xa2, 0x60, 0x53, 0x00, 0xa4, 0x41, 0x13, 0x80, 0x04, 0xfd, + 0x1c, 0x63, 0xa2, 0x60, 0x50, 0x10, 0x96, 0x0c, 0xc0, 0x0c, 0xd0, 0x6d, + 0x62, 0x60, 0x53, 0x80, 0x62, 0x60, 0x50, 0x90, 0xe8, 0x45, 0xa0, 0x0c, + 0xa3, 0x41, 0x09, 0x80, 0x43, 0xfc, 0xb0, 0x9b, 0xb0, 0x41, 0x05, 0x80, + 0x10, 0x32, 0xf9, 0x4b, 0x20, 0x6d, 0x92, 0x30, 0xc4, 0x9b, 0xd0, 0x45, + 0x43, 0xf8, 0xb0, 0x9b, 0x6c, 0x48, 0x04, 0xed, 0x43, 0x94, 0x83, 0x00, + 0x00, 0x0c, 0xea, 0x48, 0x8a, 0x8f, 0x01, 0xed, 0x47, 0x94, 0x88, 0x00, + 0x71, 0xfc, 0x10, 0x0b, 0x43, 0xfc, 0x80, 0x00, 0x20, 0x6d, 0x43, 0xf8, + 0x80, 0x00, 0xd0, 0x45, 0x9d, 0xfc, 0x38, 0x00, 0xe0, 0x0c, 0x47, 0x0c, + 0x3d, 0x23, 0x40, 0x50, 0x1a, 0x47, 0x93, 0x34, 0x00, 0x00, 0x53, 0x30, + 0x1e, 0x00, 0xb3, 0x30, 0x18, 0x00, 0x84, 0xd0, 0x00, 0x03, 0x84, 0x70, + 0x00, 0x03, 0x85, 0x00, 0x18, 0x10, 0x20, 0x0a, 0x55, 0x02, 0x50, 0x11, + 0x24, 0x25, 0x47, 0x2e, 0x42, 0x02, 0x50, 0x11, 0x24, 0x25, 0x84, 0x30, + 0x6f, 0x01, 0x22, 0x05, 0x46, 0x26, 0x02, 0xf8, 0x98, 0x03, 0x42, 0x06, + 0x41, 0x6a, 0x03, 0xed, 0x44, 0xb4, 0x4b, 0xff, 0x55, 0x02, 0x50, 0x11, + 0x53, 0x34, 0x00, 0x00, 0x80, 0x30, 0x88, 0x00, 0x42, 0xd0, 0x8c, 0x00, + 0x82, 0xb4, 0x41, 0xff, 0x55, 0x02, 0x50, 0x11, 0x01, 0xed, 0x3b, 0xcf, + 0x56, 0x18, 0x76, 0x00, 0xe5, 0x40, 0xc3, 0xfe, 0xb4, 0xfc, 0x30, 0x00, + 0xe5, 0x40, 0x02, 0x00, 0xdd, 0x0a, 0x54, 0x05, 0x81, 0xee, 0xbb, 0xce, + 0xb6, 0x18, 0x77, 0x00, 0x80, 0x0c, 0x84, 0xce, 0x16, 0x18, 0x77, 0x00, + 0x4f, 0x48, 0xb2, 0x41, 0x09, 0x80, 0xff, 0xee, 0xc2, 0x45, 0x92, 0x30, + 0xc4, 0x9b, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x9c, 0xbd, 0xa2, 0x60, + 0x53, 0x00, 0xa4, 0x41, 0x13, 0x80, 0xe4, 0xfc, 0x1c, 0x63, 0xa2, 0x60, + 0x50, 0x10, 0x96, 0x0c, 0xc0, 0x0c, 0xd0, 0x6d, 0x62, 0x60, 0x53, 0x80, + 0x62, 0x60, 0x50, 0x90, 0xe7, 0x45, 0xa0, 0x0c, 0xa3, 0x41, 0x09, 0x80, + 0x43, 0xfc, 0xb0, 0x9b, 0xb0, 0x41, 0x05, 0x80, 0x10, 0x32, 0xf9, 0x4b, + 0x20, 0x6d, 0x92, 0x30, 0xc4, 0x9b, 0xd0, 0x45, 0x43, 0xf8, 0xb0, 0x9b, + 0x6c, 0x48, 0x04, 0xed, 0x43, 0xb4, 0x8b, 0xff, 0x00, 0x0c, 0x71, 0xfc, + 0x10, 0x0b, 0x8e, 0x48, 0x43, 0xfc, 0x84, 0x00, 0x20, 0x6d, 0xd0, 0x45, + 0x43, 0xf8, 0x84, 0x00, 0x84, 0xcf, 0xe0, 0x0c, 0x43, 0xfc, 0x7c, 0x00, + 0x20, 0x6d, 0x7b, 0xcf, 0x43, 0xf8, 0x7c, 0x00, 0x40, 0x31, 0xff, 0x00, + 0x33, 0xce, 0x6b, 0xc8, 0xff, 0xef, 0x9f, 0x45, 0x47, 0x0c, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0xf9, 0x4b, 0xc2, 0x45, 0x9d, 0xfc, 0x38, 0x00, + 0x01, 0xcf, 0xe0, 0x30, 0xf6, 0xff, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, + 0xf9, 0x4b, 0xc2, 0x45, 0x9d, 0xfc, 0x38, 0x00, 0xf7, 0xce, 0xe0, 0x30, + 0xf4, 0xff, 0x00, 0x0c, 0xe5, 0x4f, 0xa3, 0x41, 0x09, 0x80, 0x3d, 0x23, + 0x10, 0xd0, 0xe3, 0x32, 0x9c, 0xbd, 0xc4, 0x16, 0x09, 0x00, 0xb7, 0x60, + 0x03, 0x00, 0xbe, 0x41, 0x09, 0x80, 0x76, 0x02, 0x00, 0x08, 0xb7, 0x60, + 0x00, 0x10, 0xd3, 0x02, 0x50, 0x11, 0x26, 0x25, 0x44, 0x0e, 0xc2, 0x02, + 0x50, 0x11, 0x9e, 0xfc, 0x58, 0xbf, 0xb1, 0x41, 0x09, 0x80, 0xd0, 0x6e, + 0x24, 0x25, 0x31, 0x32, 0x9c, 0x93, 0x22, 0x05, 0xb7, 0x60, 0x03, 0x80, + 0xb5, 0x41, 0x05, 0x80, 0x84, 0x30, 0x20, 0x02, 0xb5, 0x32, 0x59, 0x5e, + 0xb7, 0x60, 0x00, 0x90, 0x08, 0xcc, 0x82, 0xfe, 0x10, 0x00, 0x52, 0x14, + 0x08, 0x00, 0x85, 0x69, 0x43, 0x94, 0x0b, 0x00, 0x90, 0x0c, 0xf5, 0x45, + 0x00, 0x0c, 0x02, 0x0e, 0x5e, 0xfc, 0x58, 0xbf, 0x42, 0x30, 0x20, 0x02, + 0x50, 0xb4, 0xf1, 0xff, 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x92, 0x0c, + 0x42, 0x30, 0xfb, 0x1c, 0xc2, 0x45, 0xb0, 0xfe, 0x10, 0x00, 0x72, 0x14, + 0x28, 0x00, 0x01, 0xed, 0x43, 0x94, 0x82, 0x00, 0xb5, 0x32, 0x20, 0x01, + 0x57, 0x60, 0x0b, 0x00, 0x57, 0x60, 0x08, 0x10, 0x20, 0x6d, 0x57, 0x60, + 0x0b, 0x80, 0x57, 0x60, 0x08, 0x90, 0x57, 0x60, 0x0f, 0x00, 0x57, 0x60, + 0x0c, 0x10, 0x62, 0x00, 0x90, 0x1b, 0x85, 0x8d, 0x20, 0x6d, 0x57, 0x60, + 0x0f, 0x80, 0x57, 0x60, 0x0c, 0x90, 0x57, 0x60, 0x17, 0x00, 0x57, 0x60, + 0x14, 0x10, 0x20, 0x6d, 0x57, 0x60, 0x17, 0x80, 0x57, 0x60, 0x14, 0x90, + 0x77, 0x60, 0x13, 0x00, 0x77, 0x60, 0x10, 0x10, 0x43, 0x00, 0x90, 0x13, + 0x05, 0x8d, 0xb0, 0x6d, 0x77, 0x60, 0x13, 0x80, 0x77, 0x60, 0x10, 0x90, + 0xd3, 0x02, 0x50, 0x99, 0x73, 0x02, 0x00, 0x18, 0xd3, 0x02, 0x50, 0xb1, + 0xd6, 0x02, 0x00, 0x10, 0xa2, 0x41, 0x10, 0x80, 0xde, 0x86, 0x42, 0x30, + 0xb3, 0x1c, 0xc2, 0x45, 0xd1, 0x02, 0x50, 0x99, 0x53, 0xfa, 0x18, 0x00, + 0x13, 0xf8, 0x1c, 0x00, 0x13, 0xf8, 0x20, 0x00, 0x74, 0xfc, 0x6c, 0x00, + 0x54, 0xfc, 0x70, 0x00, 0x94, 0x0c, 0x35, 0x05, 0x42, 0x30, 0x0e, 0x00, + 0x54, 0x38, 0x60, 0x00, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x1d, 0xa3, + 0xe2, 0x45, 0x84, 0x6a, 0x54, 0x38, 0x5c, 0x00, 0xd2, 0x60, 0x21, 0x00, + 0xa2, 0x41, 0x05, 0x80, 0xb4, 0x0c, 0xd2, 0x60, 0x1e, 0x10, 0x95, 0x0c, + 0x42, 0x30, 0x91, 0x28, 0xe2, 0x45, 0x6f, 0x2f, 0x76, 0x30, 0x24, 0x00, + 0xd6, 0x32, 0x34, 0x00, 0x54, 0x38, 0x50, 0x00, 0x32, 0x05, 0x13, 0xf8, + 0x14, 0x00, 0xd1, 0x02, 0x50, 0x89, 0xff, 0xed, 0xa0, 0x89, 0x20, 0x6d, + 0x22, 0xb6, 0xfc, 0xff, 0x00, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x07, 0x1d, 0x54, 0xf8, 0x44, 0x00, 0x84, 0x6a, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x69, 0x1b, 0xe2, 0x45, 0x94, 0x0c, 0x40, 0x0c, 0x3d, 0x23, + 0x10, 0x50, 0x0e, 0x47, 0x57, 0x60, 0x07, 0x00, 0x57, 0x60, 0x04, 0x10, + 0x20, 0x6d, 0x57, 0x60, 0x07, 0x80, 0x81, 0xcf, 0x57, 0x60, 0x04, 0x90, + 0xbf, 0x45, 0x00, 0x0c, 0xdd, 0x4f, 0x3d, 0x23, 0x20, 0xd0, 0x1d, 0x36, + 0x5c, 0x00, 0x64, 0x30, 0x14, 0x05, 0x24, 0x0e, 0x50, 0x00, 0x80, 0x28, + 0x43, 0x00, 0x18, 0x11, 0x45, 0x0e, 0x66, 0x0e, 0x50, 0x00, 0x50, 0x10, + 0x21, 0x2d, 0x87, 0x0e, 0xbd, 0x36, 0x58, 0x00, 0xdd, 0x36, 0x60, 0x00, + 0xf9, 0x4a, 0xda, 0x4b, 0x11, 0x8d, 0x7b, 0x48, 0x08, 0x05, 0x42, 0x14, + 0xf8, 0x04, 0xa2, 0x94, 0x0b, 0x00, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0xef, + 0x08, 0x84, 0x42, 0x30, 0x1d, 0x10, 0x04, 0xc8, 0xc2, 0x45, 0x7d, 0xf8, + 0x18, 0x00, 0x66, 0x48, 0xb9, 0x41, 0x01, 0x80, 0x7c, 0x85, 0xd2, 0x86, + 0x39, 0x33, 0x6d, 0xf7, 0xb6, 0xca, 0x17, 0xca, 0xdd, 0x22, 0x60, 0x90, + 0xda, 0xcb, 0x7b, 0xc8, 0x3d, 0x23, 0x20, 0x50, 0x99, 0x45, 0x25, 0x4c, + 0xe9, 0x4f, 0x68, 0x45, 0x44, 0x68, 0x50, 0xfc, 0x40, 0x00, 0x42, 0x00, + 0x2c, 0x02, 0x1e, 0x8d, 0x40, 0x0c, 0x50, 0xfc, 0x40, 0x00, 0x42, 0x00, + 0xac, 0x02, 0x18, 0xad, 0x40, 0x0c, 0x02, 0x69, 0x82, 0x40, 0x14, 0x00, + 0x40, 0x0c, 0x50, 0xfc, 0x08, 0x06, 0x10, 0xad, 0x40, 0x0c, 0x50, 0xfc, + 0xfc, 0x06, 0x0c, 0x8d, 0x40, 0x0c, 0x50, 0x14, 0x15, 0x04, 0x07, 0xad, + 0x02, 0xed, 0xc5, 0x68, 0x71, 0xfc, 0x00, 0x06, 0x43, 0x94, 0x04, 0x00, + 0x00, 0x0c, 0x40, 0x0c, 0x28, 0x45, 0x0c, 0x47, 0xc0, 0x69, 0x35, 0x69, + 0x42, 0xd0, 0x00, 0x20, 0x79, 0xad, 0x40, 0x0c, 0x51, 0xfc, 0xc4, 0x04, + 0x20, 0x2d, 0xe2, 0x40, 0x09, 0x00, 0x51, 0xfc, 0xe8, 0x04, 0x21, 0x2d, + 0xe2, 0x40, 0x04, 0x00, 0x43, 0x34, 0x50, 0x00, 0x6b, 0x8d, 0x40, 0x0c, + 0x00, 0x69, 0x22, 0x2d, 0x33, 0xad, 0x43, 0xfe, 0x70, 0x00, 0x51, 0xfc, + 0x94, 0x04, 0x61, 0x8d, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xdf, 0x23, + 0xa0, 0x0c, 0xe2, 0x45, 0x09, 0x6e, 0x52, 0x34, 0x00, 0x00, 0x60, 0x30, + 0xd0, 0x00, 0x42, 0xd0, 0xfc, 0x00, 0x62, 0xb4, 0x0b, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x72, 0x34, 0x18, 0x00, 0x40, 0x30, 0x03, 0x01, 0x43, 0x94, + 0x31, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, + 0x82, 0x6a, 0xaa, 0x06, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xff, 0x1e, + 0xc2, 0x45, 0x90, 0x30, 0x08, 0x07, 0xa2, 0x41, 0x10, 0x80, 0xa0, 0x0c, + 0x42, 0x30, 0xe5, 0x23, 0xe2, 0x45, 0x09, 0x6e, 0xb5, 0xcf, 0x40, 0x0c, + 0xa2, 0x41, 0x10, 0x80, 0x88, 0x87, 0xa0, 0x50, 0xff, 0xff, 0x42, 0x30, + 0x4b, 0x1b, 0xe2, 0x45, 0x01, 0xef, 0x51, 0xfc, 0xc4, 0x04, 0xb0, 0x30, + 0x04, 0x07, 0x40, 0x00, 0x0c, 0x42, 0x51, 0xf8, 0xc4, 0x04, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x63, 0x18, 0xe2, 0x45, 0x90, 0x0c, 0xb9, 0xcf, + 0x51, 0xfc, 0x94, 0x04, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0xfc, 0x54, 0x04, + 0xa2, 0x41, 0x10, 0x80, 0x90, 0x30, 0x08, 0x07, 0x42, 0x30, 0xff, 0x1e, + 0xc2, 0x45, 0xa5, 0x30, 0x0a, 0x00, 0xd1, 0xcf, 0xa2, 0x41, 0x10, 0x80, + 0xed, 0x4f, 0xbd, 0x22, 0x10, 0xd0, 0x41, 0x69, 0x84, 0xfe, 0x0c, 0x00, + 0x04, 0x0e, 0x22, 0xfe, 0x70, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0xa7, 0x25, 0x44, 0xfe, 0x08, 0x00, 0xc2, 0x45, 0x74, 0xfe, 0x2c, 0x01, + 0x90, 0x29, 0x08, 0xee, 0xa3, 0xd0, 0x0c, 0x00, 0x85, 0x94, 0x04, 0x00, + 0x40, 0x0c, 0xbd, 0x22, 0x10, 0x50, 0x0a, 0x47, 0x43, 0xd0, 0x4c, 0x00, + 0xa2, 0x94, 0x06, 0x00, 0x40, 0x30, 0x00, 0x03, 0x02, 0xed, 0xbd, 0x22, + 0x10, 0x50, 0x0a, 0x47, 0x63, 0xd0, 0x00, 0x03, 0x43, 0x94, 0x5f, 0x00, + 0x03, 0xed, 0x01, 0x69, 0x62, 0xfa, 0x10, 0x00, 0x52, 0xfc, 0xfc, 0x06, + 0x02, 0x94, 0x4f, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x52, 0xfc, 0x08, 0x00, + 0x82, 0x40, 0x49, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x01, 0x69, 0x62, 0xfc, + 0x70, 0x00, 0x30, 0x29, 0x42, 0xd0, 0x00, 0x01, 0xe2, 0x40, 0x45, 0x00, + 0x43, 0x14, 0x10, 0x00, 0x21, 0x2d, 0x3b, 0xad, 0xa2, 0x41, 0x10, 0x80, + 0x52, 0xfc, 0x08, 0x06, 0x36, 0xad, 0xa2, 0x41, 0x10, 0x80, 0x54, 0xfc, + 0x38, 0x01, 0x42, 0x00, 0x6c, 0x00, 0x2f, 0xad, 0xa2, 0x41, 0x10, 0x80, + 0xb3, 0x41, 0x09, 0x80, 0x53, 0xfc, 0x20, 0x4d, 0x20, 0x6d, 0x53, 0xf8, + 0x20, 0x4d, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x15, 0x18, 0xe2, 0x45, + 0x94, 0x0c, 0x11, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0x52, 0xfc, 0x00, 0x00, + 0x22, 0x2d, 0x0b, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0x10, 0x29, 0x88, 0xed, + 0x82, 0xd0, 0x0c, 0x00, 0x64, 0x94, 0x47, 0x00, 0x00, 0x0c, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0xfc, 0x54, 0x04, 0xb2, 0xfc, 0x08, 0x00, 0xaa, 0x06, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xff, 0x1e, 0xc2, 0x45, 0x92, 0x30, + 0x08, 0x07, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x4d, 0x16, 0xe2, 0x45, + 0x90, 0x0c, 0x93, 0xcf, 0x03, 0xed, 0xbc, 0xcf, 0x34, 0x09, 0x74, 0xfc, + 0x00, 0x06, 0x43, 0xb4, 0x9e, 0xff, 0x00, 0x0c, 0x50, 0xfe, 0x10, 0x00, + 0x12, 0x94, 0x90, 0xff, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0xd5, 0xf1, + 0xc2, 0x45, 0xb3, 0x41, 0x08, 0x00, 0x32, 0xfe, 0x78, 0x00, 0x82, 0x0c, + 0x71, 0x02, 0x90, 0x1a, 0xa2, 0x41, 0x02, 0x80, 0x71, 0x02, 0x50, 0x8a, + 0x42, 0x30, 0xe9, 0xf1, 0xc2, 0x45, 0x72, 0xf8, 0x78, 0x00, 0x11, 0xb4, + 0x79, 0xff, 0x20, 0xef, 0x03, 0x69, 0x84, 0x6a, 0x82, 0xfc, 0x2c, 0x01, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0xc3, 0x12, 0xc2, 0x45, 0xa5, 0x30, + 0x30, 0x06, 0x6d, 0xcf, 0x02, 0xed, 0x42, 0xd0, 0x00, 0x20, 0x02, 0x94, + 0xb8, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x53, 0xfc, 0x20, 0x4d, 0x42, 0xb0, + 0x04, 0x00, 0xa2, 0x40, 0xae, 0xff, 0xa2, 0x41, 0x10, 0x80, 0xb2, 0x30, + 0x04, 0x07, 0x42, 0x30, 0x63, 0x18, 0xe2, 0x45, 0x92, 0x0c, 0xa7, 0xcf, + 0xa2, 0x41, 0x08, 0x80, 0xe5, 0x4f, 0x3d, 0x23, 0x10, 0xd0, 0xc4, 0x0f, + 0xc2, 0x69, 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, 0x5c, 0xfc, + 0x7c, 0x82, 0x20, 0x6e, 0x9c, 0xf8, 0x7c, 0x82, 0x43, 0xf8, 0x48, 0x04, + 0x50, 0x69, 0x45, 0x94, 0x34, 0x00, 0x00, 0x0c, 0xe2, 0x40, 0x31, 0x00, + 0xb2, 0x41, 0x10, 0x80, 0xb1, 0x41, 0x03, 0x80, 0xb3, 0x41, 0x10, 0x80, + 0xb4, 0x41, 0x10, 0x80, 0xb5, 0x41, 0x10, 0x80, 0x05, 0x0e, 0x52, 0x32, + 0xb3, 0x19, 0x31, 0x32, 0x49, 0x72, 0x73, 0x32, 0xa1, 0x19, 0x94, 0x32, + 0x9b, 0x19, 0xb6, 0x41, 0x10, 0x80, 0xb5, 0x32, 0x89, 0x19, 0xb7, 0x41, + 0x05, 0x80, 0x84, 0x29, 0x9e, 0x0c, 0xbe, 0x6d, 0x84, 0xa9, 0xa0, 0x6a, + 0xa1, 0x69, 0x20, 0xe8, 0x21, 0xe8, 0xd1, 0xe9, 0xb0, 0xea, 0xd1, 0x45, + 0x5e, 0xf8, 0x04, 0x00, 0xe2, 0x40, 0x24, 0x00, 0xa2, 0x0c, 0xf2, 0x45, + 0x9e, 0x0c, 0x00, 0x69, 0x50, 0x94, 0x03, 0x00, 0x00, 0x0c, 0xa2, 0x40, + 0xe8, 0xff, 0x7e, 0xfc, 0x08, 0x00, 0x5c, 0xfc, 0x84, 0x82, 0x63, 0xfc, + 0x48, 0x04, 0x7c, 0xf8, 0x7c, 0x82, 0xa2, 0x40, 0x0e, 0x00, 0x5c, 0xfc, + 0x7c, 0x82, 0xa2, 0x40, 0x0a, 0x00, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, + 0xa0, 0x00, 0xa2, 0x40, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, + 0x00, 0x18, 0x3d, 0x23, 0x10, 0x50, 0x0e, 0x47, 0xf3, 0x45, 0x9e, 0x0c, + 0x5a, 0xad, 0xa2, 0x0c, 0xf4, 0x45, 0x9e, 0x0c, 0x56, 0xad, 0xa2, 0x0c, + 0x56, 0x30, 0x83, 0x19, 0xe2, 0x45, 0x9e, 0x0c, 0x50, 0xad, 0xa2, 0x0c, + 0xf5, 0x45, 0x9e, 0x0c, 0x4c, 0xad, 0xa2, 0x0c, 0x57, 0x30, 0x09, 0x2c, + 0xe2, 0x45, 0x9e, 0x0c, 0x46, 0xad, 0xa2, 0x0c, 0xa2, 0x41, 0x09, 0x80, + 0x42, 0x30, 0xad, 0x43, 0xe2, 0x45, 0x9e, 0x0c, 0x02, 0xb4, 0xbd, 0xff, + 0xa2, 0x0c, 0xa2, 0x41, 0x03, 0x80, 0xb0, 0x0c, 0x42, 0x30, 0x89, 0x7d, + 0xe2, 0x45, 0x9e, 0x0c, 0x02, 0xb4, 0xb3, 0xff, 0xa2, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0x95, 0x19, 0xe2, 0x45, 0x9e, 0x0c, 0x02, 0xb4, + 0xaa, 0xff, 0xa2, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x6b, 0x19, + 0xe2, 0x45, 0x9e, 0x0c, 0x02, 0xb4, 0xa1, 0xff, 0xa2, 0x0c, 0xa2, 0x41, + 0x10, 0x80, 0x42, 0x30, 0xa7, 0x19, 0xe2, 0x45, 0x9e, 0x0c, 0x02, 0xb4, + 0x98, 0xff, 0xa2, 0x0c, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x71, 0x19, + 0xe2, 0x45, 0x9e, 0x0c, 0xa2, 0x40, 0x8e, 0xff, 0xa2, 0x41, 0x10, 0x80, + 0x42, 0x30, 0x8f, 0x19, 0xe2, 0x45, 0x9e, 0x0c, 0x88, 0xcf, 0xa2, 0x0c, + 0xe9, 0x4f, 0x40, 0x30, 0x84, 0x00, 0x68, 0x45, 0x04, 0x0e, 0x45, 0x94, + 0xac, 0x00, 0x46, 0x0e, 0x45, 0x90, 0x85, 0x00, 0x2b, 0xad, 0x27, 0x0e, + 0x40, 0x30, 0x86, 0x00, 0x45, 0x94, 0xbb, 0x00, 0x45, 0x90, 0x86, 0x00, + 0x02, 0xb4, 0x7e, 0x00, 0x40, 0x30, 0x87, 0x00, 0x45, 0x94, 0x4c, 0x00, + 0x40, 0x30, 0x88, 0x00, 0x45, 0xb4, 0xb7, 0x00, 0xa3, 0x41, 0x09, 0x80, + 0x44, 0x14, 0x24, 0x00, 0x82, 0x0c, 0x43, 0x18, 0x70, 0x4c, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0xd1, 0xe8, 0xe2, 0x45, 0x00, 0x0c, 0xa0, 0x0c, + 0x90, 0x60, 0x0b, 0x00, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x43, 0x23, + 0xc2, 0x45, 0x90, 0x60, 0x08, 0x10, 0x01, 0xed, 0x28, 0x45, 0x0c, 0x47, + 0x3d, 0xed, 0x45, 0x94, 0x61, 0x00, 0x45, 0x90, 0x3e, 0x00, 0x34, 0xad, + 0x40, 0x30, 0x82, 0x00, 0x45, 0x94, 0x17, 0x00, 0x40, 0x30, 0x83, 0x00, + 0x45, 0xb4, 0x8f, 0x00, 0xa2, 0x41, 0x01, 0x80, 0xa4, 0x30, 0x24, 0x00, + 0x06, 0xef, 0x42, 0x30, 0xbd, 0xa4, 0xc2, 0x45, 0x9d, 0x30, 0x12, 0x00, + 0x50, 0x48, 0x90, 0x48, 0x42, 0xfc, 0x80, 0x00, 0x26, 0x69, 0xe2, 0x45, + 0x89, 0x6e, 0xd4, 0xcf, 0xa2, 0x0c, 0xa4, 0x60, 0x27, 0x00, 0xa2, 0x41, + 0x10, 0x80, 0x84, 0x30, 0x28, 0x00, 0x42, 0x30, 0xa1, 0x22, 0xc2, 0x45, + 0xb0, 0x60, 0x24, 0x10, 0xc7, 0xcf, 0xa2, 0x0c, 0x44, 0x14, 0x25, 0x00, + 0x64, 0x14, 0x24, 0x00, 0xa0, 0x0c, 0x20, 0x25, 0xd3, 0x44, 0xa3, 0x41, + 0x09, 0x80, 0xbc, 0xcf, 0x43, 0x38, 0x4a, 0x4d, 0x25, 0xed, 0x45, 0xb4, + 0x60, 0x00, 0xa2, 0x41, 0x09, 0x80, 0xc2, 0x14, 0x25, 0x4d, 0x06, 0xb4, + 0x5d, 0x00, 0xa2, 0x41, 0x01, 0x80, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, + 0xc4, 0xbe, 0x62, 0x60, 0x33, 0x00, 0xd0, 0x48, 0xd8, 0x86, 0x62, 0x60, + 0x30, 0x10, 0xb0, 0x6d, 0x62, 0x60, 0x33, 0x80, 0x62, 0x60, 0x30, 0x90, + 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, 0x41, 0x1f, 0xe2, 0x45, 0x00, 0x0c, + 0x99, 0xcf, 0xa2, 0x0c, 0xa2, 0x41, 0x09, 0x80, 0x42, 0x30, 0x9d, 0x13, + 0xe2, 0x45, 0xa7, 0x0c, 0x91, 0xcf, 0xa2, 0x0c, 0x70, 0x48, 0x44, 0x60, + 0x27, 0x00, 0xa6, 0x41, 0x09, 0x80, 0x63, 0xfc, 0x50, 0x02, 0x44, 0x60, + 0x24, 0x10, 0x81, 0xee, 0x63, 0x14, 0x94, 0x00, 0x03, 0xb4, 0x82, 0xff, + 0x46, 0x18, 0x25, 0x4d, 0xd0, 0x48, 0xa2, 0x41, 0x10, 0x80, 0x42, 0x30, + 0x43, 0x1d, 0xe2, 0x45, 0xb2, 0x0c, 0x78, 0xcf, 0xa2, 0x0c, 0x50, 0x48, + 0xe4, 0x60, 0x27, 0x00, 0xa0, 0x0c, 0x42, 0xfc, 0xd0, 0x00, 0xe4, 0x60, + 0x24, 0x10, 0xc2, 0x14, 0x3f, 0x00, 0x06, 0x94, 0x6b, 0xff, 0xe2, 0xf8, + 0xcc, 0x00, 0x52, 0xfc, 0x08, 0x00, 0xb0, 0x48, 0x42, 0xfc, 0xf8, 0x00, + 0xc2, 0x45, 0x92, 0x30, 0x20, 0x01, 0x60, 0xcf, 0xa2, 0x0c, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0x30, 0x29, 0x14, 0xe2, 0x45, 0xa7, 0x0c, 0x58, 0xcf, + 0xa2, 0x0c, 0x40, 0x0c, 0x28, 0x45, 0x0c, 0x47, 0x72, 0x6a, 0xb1, 0xfc, + 0x20, 0x01, 0x42, 0x30, 0xdd, 0x45, 0xc2, 0x45, 0xe7, 0xfc, 0xcc, 0x00, + 0x01, 0xed, 0x9b, 0xcf, 0x51, 0x18, 0x3f, 0x00, 0x40, 0xea, 0x9f, 0x45, + 0x41, 0xea, 0x00, 0x0c, 0x40, 0x69, 0x51, 0xea, 0x50, 0xe9, 0x40, 0x69, + 0xa1, 0xea, 0x9f, 0x45, 0xc0, 0xea, 0x00, 0x0c, 0x41, 0x69, 0x50, 0xea, + 0x51, 0xe9, 0x41, 0x69, 0xa0, 0xea, 0x9f, 0x45, 0xc1, 0xea, 0x00, 0x0c, + 0x40, 0x69, 0x54, 0x44, 0x9f, 0x45, 0x42, 0xb0, 0x01, 0x00, 0x00, 0x0c, + 0x40, 0x69, 0x62, 0x44, 0x9f, 0x45, 0x80, 0x00, 0x58, 0x10, 0x00, 0x0c, + 0x41, 0x69, 0x62, 0x44, 0x9f, 0x45, 0x80, 0x00, 0x58, 0x10, 0x00, 0x0c, + 0x9f, 0x45, 0x40, 0x69, 0x9f, 0x45, 0x41, 0x69, 0xc0, 0x69, 0x41, 0x69, + 0x31, 0xe9, 0xa0, 0xe9, 0x40, 0xea, 0x9f, 0x45, 0x41, 0xea, 0x00, 0x0c, + 0x40, 0x69, 0x82, 0x94, 0x08, 0x00, 0x00, 0x0c, 0x20, 0x6a, 0xa1, 0x69, + 0xc1, 0xe9, 0x30, 0xea, 0x21, 0xe9, 0x9f, 0x45, 0x20, 0xe9, 0x9f, 0x45, + 0x40, 0x0c, 0x00, 0x0c, 0x40, 0x69, 0x82, 0x94, 0x09, 0x00, 0x00, 0x0c, + 0x41, 0x69, 0xa1, 0x69, 0x20, 0x6a, 0xc1, 0xe9, 0x30, 0xea, 0x21, 0xe9, + 0x9f, 0x45, 0x20, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0x41, 0x69, 0x50, 0xea, + 0x51, 0xe9, 0xa0, 0xea, 0x9f, 0x45, 0xc1, 0xea, 0x40, 0x69, 0x51, 0xea, + 0x50, 0xe9, 0xa1, 0xea, 0x9f, 0x45, 0xc0, 0xea, 0x40, 0x69, 0x82, 0x94, + 0x0a, 0x00, 0x00, 0x0c, 0xc1, 0x69, 0x45, 0x20, 0x00, 0x90, 0xa1, 0xea, + 0x51, 0x69, 0xa0, 0xea, 0x40, 0xea, 0x9f, 0x45, 0x41, 0xea, 0xd0, 0xea, + 0x9f, 0x45, 0xd1, 0xea, 0x46, 0x34, 0x43, 0x45, 0x33, 0x36, 0x31, 0x32, + 0x33, 0x34, 0x35, 0x36, 0x00, 0x00, 0x00, 0x00, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x27, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x2b, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x2f, 0x27, 0x09, 0x80, 0x33, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x37, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x3b, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x3f, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x43, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x47, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x4b, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x4f, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x23, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x27, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x2b, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x2f, 0x27, 0x09, 0x80, 0x33, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x3b, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x3f, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x43, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, 0x53, 0x27, 0x09, 0x80, + 0x53, 0x27, 0x09, 0x80, 0x47, 0x27, 0x09, 0x80, 0x00, 0x01, 0x32, 0x21, + 0x24, 0x30, 0x2e, 0x46, 0x36, 0x37, 0x39, 0x3b, 0x3b, 0x2d, 0x48, 0x7f, + 0x59, 0x5e, 0x6b, 0xbf, 0xc7, 0x00, 0x00, 0x00, 0x83, 0x00, 0x00, 0x00, + 0x84, 0x00, 0x00, 0x00, 0x85, 0x00, 0x00, 0x00, 0x86, 0x00, 0x00, 0x00, + 0x87, 0x00, 0x00, 0x00, 0x88, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0xfc, 0xff, 0xff, 0xf7, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0xa0, 0x9d, + 0x13, 0x80, 0x47, 0x43, 0x43, 0x3a, 0x20, 0x28, 0x43, 0x6f, 0x64, 0x65, + 0x73, 0x63, 0x61, 0x70, 0x65, 0x20, 0x47, 0x4e, 0x55, 0x20, 0x54, 0x6f, + 0x6f, 0x6c, 0x73, 0x20, 0x32, 0x30, 0x31, 0x37, 0x2e, 0x31, 0x30, 0x2d, + 0x30, 0x35, 0x20, 0x66, 0x6f, 0x72, 0x20, 0x4d, 0x49, 0x50, 0x53, 0x20, + 0x4d, 0x54, 0x49, 0x20, 0x42, 0x61, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x74, + 0x61, 0x6c, 0x29, 0x20, 0x36, 0x2e, 0x33, 0x2e, 0x30, 0x00, 0x47, 0x43, + 0x43, 0x3a, 0x20, 0x28, 0x43, 0x6f, 0x64, 0x65, 0x73, 0x63, 0x61, 0x70, + 0x65, 0x20, 0x47, 0x4e, 0x55, 0x20, 0x54, 0x6f, 0x6f, 0x6c, 0x73, 0x20, + 0x32, 0x30, 0x32, 0x30, 0x2e, 0x30, 0x36, 0x2d, 0x30, 0x31, 0x20, 0x66, + 0x6f, 0x72, 0x20, 0x4d, 0x49, 0x50, 0x53, 0x20, 0x4d, 0x54, 0x49, 0x20, + 0x42, 0x61, 0x72, 0x65, 0x20, 0x4d, 0x65, 0x74, 0x61, 0x6c, 0x29, 0x20, + 0x39, 0x2e, 0x33, 0x2e, 0x30, 0x00, 0x41, 0x0f, 0x00, 0x00, 0x00, 0x67, + 0x6e, 0x75, 0x00, 0x01, 0x07, 0x00, 0x00, 0x00, 0x04, 0x03, 0xdd, 0x2e, + 0x02, 0x00, 0x04, 0x00, 0x00, 0x00, 0x00, 0x00, 0x04, 0x01, 0x40, 0x67, + 0x01, 0x00, 0x0c, 0xbf, 0xa4, 0x00, 0x00, 0xf0, 0x0e, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, 0x1f, 0x4c, + 0x02, 0x00, 0x02, 0x01, 0x06, 0x01, 0x65, 0x02, 0x00, 0x03, 0x4d, 0x16, + 0x00, 0x00, 0x13, 0x2b, 0x3a, 0x00, 0x00, 0x00, 0x02, 0x01, 0x08, 0x04, + 0x99, 0x01, 0x00, 0x04, 0x3a, 0x00, 0x00, 0x00, 0x02, 0x02, 0x05, 0x39, + 0xdc, 0x01, 0x00, 0x02, 0x02, 0x07, 0xe3, 0x98, 0x02, 0x00, 0x03, 0x28, + 0xc5, 0x00, 0x00, 0x13, 0x4d, 0x5f, 0x00, 0x00, 0x00, 0x02, 0x04, 0x05, + 0x6c, 0x4f, 0x02, 0x00, 0x03, 0x9d, 0x9f, 0x00, 0x00, 0x13, 0x4f, 0x71, + 0x00, 0x00, 0x00, 0x02, 0x04, 0x07, 0xac, 0x35, 0x02, 0x00, 0x05, 0x71, + 0x00, 0x00, 0x00, 0x04, 0x78, 0x00, 0x00, 0x00, 0x03, 0x05, 0x3a, 0x00, + 0x00, 0x13, 0x67, 0x8d, 0x00, 0x00, 0x00, 0x02, 0x08, 0x05, 0x70, 0x82, + 0x02, 0x00, 0x03, 0xf9, 0x1a, 0x00, 0x00, 0x13, 0x69, 0x9f, 0x00, 0x00, + 0x00, 0x02, 0x08, 0x07, 0x67, 0x7d, 0x01, 0x00, 0x03, 0x83, 0x98, 0x00, + 0x00, 0x13, 0xe8, 0x71, 0x00, 0x00, 0x00, 0x03, 0x4f, 0x16, 0x00, 0x00, + 0x14, 0x18, 0x2f, 0x00, 0x00, 0x00, 0x03, 0x2a, 0xc5, 0x00, 0x00, 0x14, + 0x2c, 0x54, 0x00, 0x00, 0x00, 0x05, 0xbc, 0x00, 0x00, 0x00, 0x03, 0x9f, + 0x9f, 0x00, 0x00, 0x14, 0x30, 0x66, 0x00, 0x00, 0x00, 0x05, 0xcc, 0x00, + 0x00, 0x00, 0x03, 0x07, 0x3a, 0x00, 0x00, 0x14, 0x38, 0x82, 0x00, 0x00, + 0x00, 0x03, 0xfb, 0x1a, 0x00, 0x00, 0x14, 0x3c, 0x94, 0x00, 0x00, 0x00, + 0x03, 0x85, 0x98, 0x00, 0x00, 0x14, 0x52, 0xa6, 0x00, 0x00, 0x00, 0x06, + 0x04, 0x05, 0x69, 0x6e, 0x74, 0x00, 0x04, 0xfd, 0x00, 0x00, 0x00, 0x03, + 0xf6, 0x63, 0x02, 0x00, 0x15, 0xd8, 0x71, 0x00, 0x00, 0x00, 0x02, 0x08, + 0x04, 0x8d, 0x84, 0x02, 0x00, 0x03, 0x35, 0x1a, 0x00, 0x00, 0x16, 0x07, + 0xfd, 0x00, 0x00, 0x00, 0x03, 0xfc, 0x6c, 0x00, 0x00, 0x17, 0x2c, 0x5f, + 0x00, 0x00, 0x00, 0x03, 0x24, 0xe9, 0x00, 0x00, 0x17, 0x72, 0x5f, 0x00, + 0x00, 0x00, 0x07, 0x16, 0xf7, 0x01, 0x00, 0x15, 0x65, 0x01, 0x21, 0x00, + 0x00, 0x00, 0x08, 0x04, 0x17, 0xa6, 0x67, 0x01, 0x00, 0x00, 0x09, 0x88, + 0x86, 0x00, 0x00, 0x17, 0xa8, 0x3c, 0x01, 0x00, 0x00, 0x09, 0x00, 0x4d, + 0x00, 0x00, 0x17, 0xa9, 0x67, 0x01, 0x00, 0x00, 0x00, 0x0a, 0x3a, 0x00, + 0x00, 0x00, 0x77, 0x01, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, 0x00, 0x03, + 0x00, 0x02, 0x04, 0x07, 0xe7, 0xfe, 0x00, 0x00, 0x0c, 0x08, 0x17, 0xa3, + 0x9f, 0x01, 0x00, 0x00, 0x0d, 0xf1, 0x61, 0x01, 0x00, 0x17, 0xa5, 0xfd, + 0x00, 0x00, 0x00, 0x00, 0x0d, 0xd9, 0x82, 0x00, 0x00, 0x17, 0xaa, 0x48, + 0x01, 0x00, 0x00, 0x04, 0x00, 0x03, 0x9f, 0xf0, 0x00, 0x00, 0x17, 0xab, + 0x7e, 0x01, 0x00, 0x00, 0x03, 0x83, 0x6c, 0x00, 0x00, 0x17, 0xaf, 0x1b, + 0x01, 0x00, 0x00, 0x0e, 0x04, 0x03, 0x81, 0xd2, 0x00, 0x00, 0x18, 0x16, + 0x71, 0x00, 0x00, 0x00, 0x0f, 0xcc, 0x6f, 0x00, 0x00, 0x18, 0x18, 0x2f, + 0x15, 0x02, 0x00, 0x00, 0x0d, 0xb2, 0x31, 0x00, 0x00, 0x18, 0x31, 0x15, + 0x02, 0x00, 0x00, 0x00, 0x10, 0x5f, 0x6b, 0x00, 0x18, 0x32, 0xfd, 0x00, + 0x00, 0x00, 0x04, 0x0d, 0xc4, 0x01, 0x00, 0x00, 0x18, 0x32, 0xfd, 0x00, + 0x00, 0x00, 0x08, 0x0d, 0x9c, 0x1a, 0x01, 0x00, 0x18, 0x32, 0xfd, 0x00, + 0x00, 0x00, 0x0c, 0x0d, 0xd1, 0x58, 0x00, 0x00, 0x18, 0x32, 0xfd, 0x00, + 0x00, 0x00, 0x10, 0x10, 0x5f, 0x78, 0x00, 0x18, 0x33, 0x1b, 0x02, 0x00, + 0x00, 0x14, 0x00, 0x11, 0x04, 0xc2, 0x01, 0x00, 0x00, 0x0a, 0xb7, 0x01, + 0x00, 0x00, 0x2b, 0x02, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, 0x00, 0x00, + 0x00, 0x0f, 0x7f, 0xe0, 0x00, 0x00, 0x24, 0x18, 0x37, 0xa4, 0x02, 0x00, + 0x00, 0x0d, 0xc7, 0x3d, 0x00, 0x00, 0x18, 0x39, 0xfd, 0x00, 0x00, 0x00, + 0x00, 0x0d, 0x8f, 0xca, 0x00, 0x00, 0x18, 0x3a, 0xfd, 0x00, 0x00, 0x00, + 0x04, 0x0d, 0x99, 0x53, 0x01, 0x00, 0x18, 0x3b, 0xfd, 0x00, 0x00, 0x00, + 0x08, 0x0d, 0x3d, 0xe9, 0x00, 0x00, 0x18, 0x3c, 0xfd, 0x00, 0x00, 0x00, + 0x0c, 0x0d, 0x0c, 0xd4, 0x00, 0x00, 0x18, 0x3d, 0xfd, 0x00, 0x00, 0x00, + 0x10, 0x0d, 0x3e, 0x52, 0x00, 0x00, 0x18, 0x3e, 0xfd, 0x00, 0x00, 0x00, + 0x14, 0x0d, 0x59, 0x54, 0x00, 0x00, 0x18, 0x3f, 0xfd, 0x00, 0x00, 0x00, + 0x18, 0x0d, 0xe6, 0x5f, 0x01, 0x00, 0x18, 0x40, 0xfd, 0x00, 0x00, 0x00, + 0x1c, 0x0d, 0x78, 0x15, 0x00, 0x00, 0x18, 0x41, 0xfd, 0x00, 0x00, 0x00, + 0x20, 0x00, 0x12, 0x4e, 0x24, 0x01, 0x00, 0x08, 0x01, 0x18, 0x4a, 0xe4, + 0x02, 0x00, 0x00, 0x0d, 0xa8, 0x0a, 0x00, 0x00, 0x18, 0x4b, 0xe4, 0x02, + 0x00, 0x00, 0x00, 0x0d, 0x45, 0x47, 0x00, 0x00, 0x18, 0x4c, 0xe4, 0x02, + 0x00, 0x00, 0x80, 0x13, 0x28, 0x19, 0x01, 0x00, 0x18, 0x4e, 0xb7, 0x01, + 0x00, 0x00, 0x00, 0x01, 0x13, 0x35, 0xcd, 0x00, 0x00, 0x18, 0x51, 0xb7, + 0x01, 0x00, 0x00, 0x04, 0x01, 0x00, 0x0a, 0xb5, 0x01, 0x00, 0x00, 0xf4, + 0x02, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x12, 0x86, + 0x2a, 0x00, 0x00, 0x90, 0x01, 0x18, 0x5d, 0x32, 0x03, 0x00, 0x00, 0x0d, + 0xb2, 0x31, 0x00, 0x00, 0x18, 0x5e, 0x32, 0x03, 0x00, 0x00, 0x00, 0x0d, + 0xda, 0x71, 0x00, 0x00, 0x18, 0x5f, 0xfd, 0x00, 0x00, 0x00, 0x04, 0x0d, + 0x67, 0xb4, 0x00, 0x00, 0x18, 0x61, 0x38, 0x03, 0x00, 0x00, 0x08, 0x0d, + 0x4e, 0x24, 0x01, 0x00, 0x18, 0x62, 0xa4, 0x02, 0x00, 0x00, 0x88, 0x00, + 0x11, 0x04, 0xf4, 0x02, 0x00, 0x00, 0x0a, 0x48, 0x03, 0x00, 0x00, 0x48, + 0x03, 0x00, 0x00, 0x0b, 0x77, 0x01, 0x00, 0x00, 0x1f, 0x00, 0x11, 0x04, + 0x4e, 0x03, 0x00, 0x00 +}; + +const unsigned char __aligned(4) nrf_wifi_lmac_patch_pri_bimg[] = { + 0xba, 0xda, 0xba, 0xab, 0x00, 0x00, 0x00, 0x10, 0x00, 0x00, 0x00, 0x00, + 0xc0, 0xcc, 0x00, 0x80, 0x02, 0x00, 0x00, 0x00, 0xff, 0xff, 0x00, 0x00, + 0x7d, 0xea, 0x00, 0x00, 0x02, 0xd4, 0xc6, 0x2f, 0x46, 0x19, 0x08, 0x80, + 0x01, 0x00, 0x33, 0xb9, 0x02, 0xd4, 0x54, 0x3b, 0xd0, 0x16, 0x08, 0x80, + 0x01, 0x00, 0xa1, 0x26, 0x02, 0xd4, 0xaa, 0x3d, 0x4e, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x34, 0x91, 0x02, 0xd4, 0x76, 0x28, 0x10, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x23, 0x4e, 0x02, 0xd4, 0x32, 0x3a, 0x6a, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x1d, 0xee, 0x02, 0xd4, 0xd8, 0x3c, 0x2a, 0x14, 0x08, 0x80, + 0x01, 0x00, 0xee, 0x80, 0x02, 0xd4, 0x16, 0x45, 0x84, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xdf, 0xf8, 0x02, 0xd4, 0xa2, 0x46, 0xac, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x76, 0x06, 0x02, 0xd4, 0x5e, 0x3e, 0x56, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x69, 0x79, 0x02, 0xd4, 0x54, 0x46, 0x60, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x37, 0x19, 0x02, 0xd4, 0x3c, 0x2c, 0xa6, 0x13, 0x08, 0x80, + 0x01, 0x00, 0xd6, 0x70, 0x02, 0xd4, 0x6a, 0x30, 0xc4, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x66, 0xa9, 0x02, 0xd4, 0x1a, 0x47, 0x72, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x53, 0x58, 0x02, 0xd4, 0xd6, 0x3c, 0x18, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x9b, 0x75, 0x02, 0xd4, 0x20, 0x2d, 0xee, 0x16, 0x08, 0x80, + 0x01, 0x00, 0xb1, 0xa0, 0x02, 0xd4, 0xda, 0x31, 0x58, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x1d, 0x6f, 0x02, 0xd4, 0x1e, 0x38, 0xba, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x41, 0x27, 0x02, 0xd4, 0x74, 0x2d, 0x16, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x46, 0xf8, 0x02, 0xd4, 0x6e, 0x40, 0xb8, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x90, 0xa1, 0x02, 0xd4, 0xe4, 0x47, 0x8e, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x44, 0x76, 0x02, 0xd4, 0x86, 0x44, 0x0c, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xe9, 0x59, 0x02, 0xd4, 0xc8, 0x48, 0x66, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x59, 0xba, 0x02, 0xd4, 0x4a, 0x44, 0xe2, 0x13, 0x08, 0x80, + 0x01, 0x00, 0x17, 0x0c, 0x02, 0xd4, 0xa4, 0x44, 0x2c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x29, 0x11, 0x02, 0xd4, 0xe4, 0x2b, 0x1c, 0x19, 0x08, 0x80, + 0x01, 0x00, 0xad, 0x7a, 0x02, 0xd4, 0x18, 0x33, 0xf2, 0x12, 0x08, 0x80, + 0x01, 0x00, 0x25, 0x65, 0x02, 0xd4, 0x44, 0x42, 0xc4, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x18, 0x65, 0x02, 0xd4, 0xa8, 0x3c, 0xb6, 0x15, 0x08, 0x80, + 0x01, 0x00, 0xf4, 0x5f, 0x02, 0xd4, 0x38, 0x44, 0x1a, 0x12, 0x08, 0x80, + 0x01, 0x00, 0x12, 0x05, 0x02, 0xd4, 0x66, 0x34, 0xbe, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x89, 0xba, 0x02, 0xd4, 0x14, 0x28, 0x34, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x94, 0x7f, 0x02, 0xd4, 0x9a, 0x42, 0xbe, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x72, 0x0e, 0x02, 0xd4, 0xa0, 0x2d, 0x00, 0x17, 0x08, 0x80, + 0x01, 0x00, 0xfa, 0xfc, 0x02, 0xd4, 0x5c, 0x37, 0x3c, 0x14, 0x08, 0x80, + 0x01, 0x00, 0x48, 0xae, 0x02, 0xd4, 0xbc, 0x36, 0x66, 0x14, 0x08, 0x80, + 0x01, 0x00, 0x86, 0x90, 0x02, 0xd4, 0x3a, 0x38, 0x3e, 0x15, 0x08, 0x80, + 0x01, 0x00, 0xc3, 0x08, 0x02, 0xd4, 0xf2, 0x42, 0x3c, 0x17, 0x08, 0x80, + 0x01, 0x00, 0xa4, 0xa5, 0x02, 0xd4, 0x90, 0x27, 0x28, 0x10, 0x08, 0x80, + 0x01, 0x00, 0xf6, 0x16, 0x02, 0xd4, 0xc8, 0x43, 0x96, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x35, 0x8c, 0x02, 0xd4, 0xbe, 0x2c, 0x82, 0x19, 0x08, 0x80, + 0x01, 0x00, 0xf6, 0x77, 0x02, 0xd4, 0x58, 0x2d, 0x5c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x59, 0x90, 0x02, 0xd4, 0xbe, 0x2a, 0x7a, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x06, 0xc1, 0x02, 0xd4, 0x74, 0x3c, 0x8a, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x30, 0x39, 0x02, 0xd4, 0x7e, 0x40, 0xd0, 0x13, 0x08, 0x80, + 0x01, 0x00, 0xac, 0x20, 0x02, 0xd4, 0x60, 0x45, 0x4e, 0x11, 0x08, 0x80, + 0x01, 0x00, 0x2a, 0xf0, 0x02, 0xd4, 0x86, 0x3d, 0xe0, 0x12, 0x08, 0x80, + 0x01, 0x00, 0x4d, 0x98, 0x02, 0xd4, 0x2e, 0x2c, 0xd6, 0x16, 0x08, 0x80, + 0x01, 0x00, 0x0f, 0xa4, 0x02, 0xd4, 0x02, 0x49, 0x54, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xd9, 0x3c, 0x02, 0xd4, 0x9a, 0x2c, 0x78, 0x1a, 0x08, 0x80, + 0x01, 0x00, 0x9f, 0xfa, 0x02, 0xd4, 0xea, 0x2f, 0xa2, 0x14, 0x08, 0x80, + 0x01, 0x00, 0x0f, 0x7f, 0x02, 0xd4, 0xca, 0x2a, 0x8c, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x3a, 0x62, 0x02, 0xd4, 0xc0, 0x47, 0xb2, 0x10, 0x08, 0x80, + 0x01, 0x00, 0x2e, 0x26, 0x02, 0xd4, 0x02, 0x3e, 0x04, 0x19, 0x08, 0x80, + 0x01, 0x00, 0x45, 0xd3, 0x02, 0xd4, 0x00, 0x45, 0xf0, 0x17, 0x08, 0x80, + 0x01, 0x00, 0x18, 0xcb, 0x02, 0xd4, 0xe8, 0x2d, 0x7a, 0x18, 0x08, 0x80, + 0x01, 0x00, 0x97, 0xb2, 0x02, 0xd4, 0xac, 0x41, 0xd4, 0x15, 0x08, 0x80, + 0x01, 0x00, 0xaa, 0xea, 0x02, 0xd4, 0x88, 0x39, 0xc6, 0x14, 0x08, 0x80, + 0x01, 0x00, 0xf6, 0xb2, 0x02, 0xd4, 0xc8, 0x3a, 0x72, 0x14, 0x08, 0x80, + 0x01, 0x00, 0xa9, 0x61, 0x02, 0xd4, 0x56, 0x31, 0xbe, 0x19, 0x08, 0x80, + 0x01, 0x00, 0x0b, 0xe0, 0x02, 0xd4, 0xc6, 0x29, 0xda, 0x15, 0x08, 0x80, + 0x01, 0x00, 0x7a, 0x56, 0x02, 0xd4, 0x4c, 0x49, 0x6c, 0x11, 0x08, 0x80, + 0x01, 0x00, 0xd6, 0x76, 0x00, 0x00, 0x00, 0x00, 0xff, 0xff, 0xff, 0xff, + 0x03, 0x00, 0xba, 0x3e +}; + +const unsigned char __aligned(4) nrf_wifi_lmac_patch_sec_bin[] = { + 0x06, 0x0d, 0x44, 0x0c, 0x07, 0xb4, 0xf1, 0x00, 0x65, 0x0c, 0xc5, 0x00, + 0x90, 0x3b, 0x07, 0x94, 0x57, 0x00, 0x46, 0x01, 0x3c, 0x5b, 0x0a, 0x94, + 0x0b, 0x00, 0xaa, 0x00, 0x10, 0x28, 0x40, 0x01, 0xd0, 0x19, 0x83, 0x00, + 0x50, 0x18, 0xca, 0x00, 0x10, 0x40, 0x8a, 0x00, 0x10, 0x10, 0xdd, 0x44, + 0xc8, 0x00, 0x40, 0x80, 0x28, 0xd1, 0xff, 0xff, 0x06, 0x00, 0x3c, 0x70, + 0xc3, 0x00, 0x3c, 0xbb, 0x45, 0x46, 0x04, 0x46, 0x06, 0x00, 0x3c, 0x70, + 0xc3, 0x00, 0x3c, 0xbb, 0x62, 0x00, 0x40, 0x80, 0x84, 0x00, 0x00, 0x80, + 0xdc, 0x44, 0xa9, 0x00, 0x10, 0x2a, 0xa3, 0x00, 0x90, 0x23, 0xe4, 0x40, + 0x0a, 0x00, 0x03, 0x01, 0x50, 0x19, 0x03, 0x01, 0x90, 0x23, 0x05, 0xae, + 0xa3, 0x00, 0x90, 0x23, 0x04, 0x01, 0x10, 0x3a, 0xbe, 0x05, 0xd7, 0x05, + 0x06, 0x00, 0x3c, 0x70, 0xc3, 0x00, 0x3c, 0xbb, 0x44, 0x46, 0x05, 0x46, + 0x06, 0x00, 0x3c, 0x70, 0xc3, 0x00, 0x3c, 0xbb, 0x89, 0x00, 0x10, 0x22, + 0x65, 0x00, 0x00, 0x80, 0x2f, 0x2d, 0xd3, 0x44, 0x82, 0x00, 0x90, 0x1b, + 0xe3, 0x40, 0x0b, 0x00, 0x02, 0x01, 0x50, 0x11, 0x02, 0x01, 0x90, 0x1b, + 0xa3, 0x40, 0x05, 0x00, 0x82, 0x00, 0x90, 0x1b, 0x03, 0x01, 0x10, 0x2a, + 0x2a, 0x05, 0x45, 0x05, 0x60, 0x0c, 0x4a, 0x00, 0x50, 0x10, 0xbf, 0x45, + 0x0a, 0xaf, 0x48, 0x01, 0x3c, 0x5b, 0x81, 0xed, 0x06, 0x00, 0x3c, 0x70, + 0xc3, 0x00, 0x3c, 0xbb, 0x48, 0x46, 0x48, 0x01, 0x3c, 0x5b, 0x0a, 0x94, + 0x55, 0x00, 0x05, 0x01, 0xd0, 0x19, 0x20, 0xed, 0x0a, 0x01, 0x10, 0x40, + 0x42, 0x01, 0xd0, 0x11, 0x68, 0x01, 0x40, 0x80, 0xa2, 0x00, 0x50, 0x30, + 0xaa, 0x00, 0x10, 0x18, 0x0b, 0x00, 0x3c, 0x70, 0x66, 0x01, 0x3c, 0xbb, + 0x82, 0x00, 0x50, 0x10, 0x62, 0x00, 0x90, 0x4a, 0x8a, 0x00, 0x10, 0x10, + 0x68, 0xd0, 0xff, 0xff, 0x47, 0x46, 0x04, 0x46, 0x0b, 0x00, 0x3c, 0x70, + 0x66, 0x01, 0x3c, 0xbb, 0xc9, 0x00, 0x40, 0x80, 0x84, 0x00, 0x00, 0x80, + 0xf4, 0x44, 0xe3, 0x00, 0x10, 0x3a, 0xe6, 0x00, 0x90, 0x23, 0xe4, 0x40, + 0x0a, 0x00, 0x06, 0x01, 0x50, 0x31, 0x06, 0x01, 0x90, 0x23, 0x05, 0xae, + 0xe6, 0x00, 0x90, 0x23, 0x04, 0x01, 0x10, 0x2a, 0x6a, 0x07, 0xfd, 0x07, + 0x0b, 0x00, 0x3c, 0x70, 0x67, 0x01, 0x3c, 0xbb, 0x45, 0x46, 0x06, 0x46, + 0x0b, 0x00, 0x3c, 0x70, 0x67, 0x01, 0x3c, 0xbb, 0xc6, 0x00, 0x00, 0x80, + 0xa3, 0x00, 0x10, 0x2a, 0x69, 0xd0, 0xff, 0xff, 0xde, 0x44, 0xa3, 0x00, + 0x90, 0x23, 0xe4, 0x40, 0x0a, 0x00, 0x03, 0x01, 0x50, 0x19, 0x03, 0x01, + 0x90, 0x23, 0x05, 0xae, 0xa3, 0x00, 0x90, 0x23, 0x04, 0x01, 0x10, 0x32, + 0xbc, 0x05, 0xd7, 0x05, 0x88, 0x00, 0x40, 0x80, 0xc8, 0xd0, 0xff, 0xff, + 0x04, 0x00, 0x3c, 0x70, 0x83, 0x00, 0x3c, 0xbb, 0x47, 0x46, 0x05, 0x46, + 0x04, 0x00, 0x3c, 0x70, 0x83, 0x00, 0x3c, 0xbb, 0x62, 0x00, 0x40, 0x80, + 0xa5, 0x00, 0x00, 0x80, 0xdd, 0x44, 0xe6, 0x00, 0x10, 0x3a, 0xe3, 0x00, + 0x90, 0x2b, 0xe5, 0x40, 0x0c, 0x00, 0x03, 0x01, 0x50, 0x19, 0x03, 0x01, + 0x90, 0x2b, 0xa5, 0x40, 0x06, 0x00, 0xe3, 0x00, 0x90, 0x2b, 0x05, 0x01, + 0x10, 0x4a, 0x69, 0x00, 0x50, 0x19, 0xf7, 0x05, 0x04, 0x00, 0x3c, 0x70, + 0x83, 0x00, 0x3c, 0xbb, 0x47, 0x46, 0x05, 0x46, 0x04, 0x00, 0x3c, 0x70, + 0x83, 0x00, 0x3c, 0xbb, 0x55, 0xcf, 0xe6, 0x00, 0x10, 0x22, 0xe5, 0x00, + 0x90, 0x43, 0x08, 0x94, 0x05, 0x00, 0xa7, 0x01, 0x3c, 0x5b, 0x44, 0x0c, + 0x62, 0xcf, 0x65, 0x0c, 0x0d, 0xb4, 0x10, 0x00, 0x00, 0x31, 0x20, 0x00, + 0xa7, 0x00, 0x90, 0x43, 0x08, 0xb4, 0x04, 0x00, 0xc4, 0x00, 0x90, 0x43, + 0xa8, 0x40, 0x55, 0xff, 0x69, 0x05, 0xfb, 0x07, 0x44, 0x00, 0x90, 0x1b, + 0x50, 0xcf, 0xbf, 0x05, 0xed, 0x00, 0x10, 0x38, 0xa8, 0x01, 0xd0, 0x41, + 0x8d, 0x00, 0x10, 0x10, 0xc8, 0x00, 0x50, 0x18, 0xa8, 0x00, 0x50, 0x50, + 0xfb, 0x44, 0x88, 0x00, 0x50, 0x48, 0x87, 0x00, 0x40, 0x80, 0xad, 0x00, + 0x10, 0x28, 0x04, 0x00, 0x3c, 0x70, 0x8a, 0x00, 0x3c, 0xbb, 0xa9, 0x00, + 0x90, 0x2a, 0xc7, 0xd1, 0xff, 0xff, 0x65, 0x01, 0x40, 0x80, 0xcd, 0x00, + 0x10, 0x30, 0x49, 0x46, 0x0c, 0x46, 0x04, 0x00, 0x3c, 0x70, 0x8a, 0x00, + 0x3c, 0xbb, 0x8c, 0x01, 0x00, 0x80, 0x6c, 0x01, 0x90, 0x5a, 0x2e, 0x01, + 0x10, 0x1a, 0x6b, 0x00, 0x90, 0x53, 0x0a, 0x94, 0x10, 0x00, 0x89, 0x0d, + 0xeb, 0x00, 0x50, 0x59, 0xeb, 0x00, 0x90, 0x53, 0x0a, 0xb4, 0x09, 0x00, + 0x9e, 0x4d, 0x6b, 0x00, 0x90, 0x53, 0xea, 0x40, 0x04, 0x00, 0x89, 0x31, + 0xfe, 0xff, 0xeb, 0x00, 0x50, 0x59, 0x6b, 0x00, 0xd0, 0x59, 0x25, 0xd1, + 0xff, 0xff, 0x04, 0x00, 0x3c, 0x70, 0x8b, 0x00, 0x3c, 0xbb, 0x4f, 0x46, + 0x0a, 0x46, 0x04, 0x00, 0x3c, 0x70, 0x8b, 0x00, 0x3c, 0xbb, 0x4a, 0x01, + 0x00, 0x80, 0x2a, 0x01, 0x90, 0x4a, 0xee, 0x01, 0x10, 0x22, 0x89, 0x00, + 0x90, 0x2b, 0x90, 0x8e, 0x6f, 0x0c, 0xe9, 0x00, 0x50, 0x49, 0xe9, 0x00, + 0x90, 0x2b, 0x8a, 0xae, 0xbe, 0x6d, 0x89, 0x00, 0x90, 0x2b, 0x88, 0x8e, + 0x4c, 0x01, 0x00, 0x80, 0x6f, 0x30, 0xfe, 0xff, 0xe9, 0x00, 0x50, 0x49, + 0x4c, 0x01, 0x00, 0x80, 0x89, 0x00, 0xd0, 0x49, 0x6a, 0x00, 0x90, 0x1a, + 0xc3, 0x00, 0x3c, 0x9b, 0x0b, 0x46, 0x4a, 0x46, 0x44, 0x46, 0x69, 0x01, + 0x90, 0x2b, 0x87, 0xae, 0x6b, 0x0c, 0x69, 0xb5, 0x0c, 0x00, 0x42, 0x01, + 0x90, 0x2b, 0xe5, 0x40, 0x08, 0x00, 0xca, 0x00, 0xd0, 0x31, 0xeb, 0x00, + 0xd0, 0x39, 0xca, 0x00, 0x90, 0x1b, 0xbf, 0x05, 0x86, 0x0c, 0x45, 0x07, + 0x69, 0x00, 0xd0, 0x49, 0xc2, 0x00, 0x90, 0x1b, 0x69, 0x00, 0xd0, 0x19, + 0xcd, 0x00, 0x50, 0x30, 0x68, 0x00, 0x10, 0x10, 0x6d, 0x00, 0x50, 0x18, + 0xc0, 0xce, 0xd6, 0x44, 0x85, 0x01, 0x2c, 0x55, 0x05, 0x01, 0x2c, 0x98, + 0x64, 0x0c, 0x0c, 0x94, 0x45, 0x00, 0xa5, 0x00, 0x40, 0xf8, 0x40, 0x30, + 0xff, 0x07, 0x4c, 0x94, 0x68, 0x00, 0x88, 0x00, 0x90, 0x12, 0xa3, 0x41, + 0x80, 0x00, 0x44, 0x00, 0x40, 0xe8, 0x08, 0x01, 0x00, 0x18, 0xd3, 0x44, + 0x2c, 0x31, 0x01, 0xfc, 0xc6, 0x25, 0x02, 0x01, 0x90, 0x12, 0xa0, 0x0d, + 0x07, 0x01, 0x2c, 0x55, 0x67, 0x01, 0x2c, 0x98, 0x08, 0x94, 0x65, 0x00, + 0xe7, 0x00, 0x40, 0xf8, 0x80, 0x30, 0xff, 0x07, 0x88, 0x94, 0x8a, 0x00, + 0xcb, 0x00, 0x90, 0x22, 0x86, 0x00, 0x40, 0xe8, 0xaa, 0x41, 0x80, 0x00, + 0x6b, 0x01, 0x00, 0x18, 0x44, 0x01, 0x90, 0x22, 0x64, 0x01, 0x90, 0x5a, + 0x08, 0x31, 0x01, 0xfc, 0x66, 0x26, 0x40, 0x0d, 0x09, 0x01, 0xd0, 0x61, + 0x0d, 0x01, 0x00, 0x10, 0x48, 0x01, 0x90, 0x42, 0x1e, 0x4d, 0x28, 0xb1, + 0x0f, 0x00, 0x09, 0x94, 0x81, 0x00, 0xe5, 0x00, 0x10, 0x33, 0xa9, 0x41, + 0x05, 0x80, 0x29, 0x31, 0x24, 0x94, 0x09, 0x01, 0x18, 0x41, 0xa8, 0x45, + 0x88, 0x00, 0x90, 0x12, 0x2e, 0x8d, 0x60, 0x0c, 0x44, 0x00, 0x3c, 0x5b, + 0x28, 0x01, 0x3c, 0x5b, 0x42, 0x30, 0x20, 0x00, 0x02, 0x01, 0x58, 0x48, + 0x49, 0x31, 0xf5, 0xff, 0x4a, 0x90, 0x1d, 0x00, 0xe2, 0x40, 0x12, 0x00, + 0x1d, 0xed, 0x69, 0x30, 0xf8, 0xff, 0x42, 0x01, 0xd0, 0x11, 0x03, 0x01, + 0x10, 0x40, 0x82, 0x00, 0x50, 0x10, 0x83, 0x00, 0x10, 0x18, 0x02, 0x01, + 0x90, 0x12, 0x80, 0x31, 0x0d, 0xfc, 0xad, 0xcf, 0x2c, 0x01, 0xd0, 0x49, + 0x49, 0x30, 0xd8, 0xff, 0xf8, 0xcf, 0x82, 0x00, 0x10, 0x10, 0xe2, 0x40, + 0x0a, 0x00, 0x48, 0x0c, 0x20, 0x31, 0xff, 0x07, 0xa1, 0xcf, 0xa0, 0x31, + 0x03, 0x00, 0x20, 0x0d, 0x9d, 0xcf, 0xa0, 0x31, 0x01, 0x00, 0x60, 0x0c, + 0x20, 0x31, 0xff, 0x07, 0x97, 0xcf, 0xa0, 0x31, 0x02, 0x00, 0xcb, 0x00, + 0x90, 0x22, 0x30, 0x8e, 0x00, 0x0d, 0x86, 0x00, 0x3c, 0x5b, 0x0b, 0x01, + 0x3c, 0x5b, 0x84, 0x30, 0x20, 0x00, 0x64, 0x01, 0x58, 0x40, 0xc8, 0x31, + 0xf5, 0xff, 0x8e, 0x90, 0x1d, 0x00, 0x14, 0x8e, 0x88, 0x0d, 0x88, 0x30, + 0xf8, 0xff, 0x00, 0x31, 0x1d, 0x00, 0x64, 0x01, 0x10, 0x58, 0xc8, 0x01, + 0xd0, 0x41, 0xc4, 0x00, 0x10, 0x20, 0xc8, 0x00, 0x50, 0x40, 0x68, 0x01, + 0x90, 0x5a, 0x00, 0x31, 0x0d, 0xfc, 0x8d, 0xcf, 0x88, 0x01, 0xd0, 0x41, + 0x68, 0x31, 0xd8, 0xff, 0x80, 0x0c, 0xf7, 0xcf, 0xcb, 0x00, 0x10, 0x58, + 0xe4, 0x40, 0x0a, 0x00, 0x86, 0x0c, 0x00, 0x31, 0xff, 0x07, 0x80, 0xcf, + 0x40, 0x31, 0x03, 0x00, 0x60, 0x0d, 0x7c, 0xcf, 0x40, 0x31, 0x01, 0x00, + 0x60, 0x0d, 0x00, 0x31, 0xff, 0x07, 0x76, 0xcf, 0x40, 0x31, 0x02, 0x00, + 0x4b, 0x00, 0x90, 0x2b, 0x88, 0xae, 0x02, 0x01, 0x00, 0xf8, 0x62, 0xb5, + 0x48, 0x01, 0x83, 0x00, 0x90, 0x2b, 0xa5, 0x40, 0x44, 0x01, 0xb3, 0x26, + 0x23, 0x25, 0xe3, 0x00, 0x00, 0xf8, 0xa8, 0x00, 0x90, 0x1a, 0x44, 0x01, + 0x40, 0xc0, 0x6b, 0x01, 0x00, 0x40, 0x23, 0x01, 0x40, 0x80, 0x6a, 0x01, + 0x90, 0x5a, 0xab, 0x01, 0x40, 0x80, 0x44, 0x01, 0x00, 0x40, 0x0d, 0x00, + 0x3c, 0x70, 0xa2, 0x01, 0x3c, 0xbb, 0x8b, 0xd0, 0xff, 0xff, 0x42, 0x46, + 0x08, 0x46, 0x44, 0x00, 0x10, 0x2a, 0x08, 0x01, 0x00, 0x80, 0x09, 0x01, + 0x90, 0x42, 0xa8, 0x00, 0x90, 0x73, 0x0e, 0x94, 0x10, 0x00, 0x22, 0x0d, + 0x68, 0x01, 0x50, 0x41, 0x68, 0x01, 0x90, 0x73, 0x0e, 0xb4, 0x09, 0x00, + 0x3e, 0x4d, 0xa8, 0x00, 0x90, 0x73, 0xee, 0x40, 0x04, 0x00, 0x22, 0x31, + 0xfe, 0xff, 0x68, 0x01, 0x50, 0x41, 0xa8, 0x00, 0xd0, 0x41, 0xbf, 0x2d, + 0x0d, 0x00, 0x3c, 0x70, 0xa8, 0x01, 0x3c, 0xbb, 0x48, 0x46, 0x02, 0x46, + 0x04, 0x01, 0x10, 0x2a, 0x42, 0x00, 0x00, 0x80, 0xda, 0x44, 0xa3, 0x00, + 0x90, 0x73, 0x0e, 0x94, 0x10, 0x00, 0x48, 0x0c, 0x63, 0x01, 0x50, 0x19, + 0x63, 0x01, 0x90, 0x73, 0x0e, 0xb4, 0x09, 0x00, 0x2e, 0x6d, 0xa3, 0x00, + 0x90, 0x73, 0xee, 0x40, 0x04, 0x00, 0x48, 0x30, 0xfe, 0xff, 0x63, 0x01, + 0x50, 0x19, 0x29, 0x01, 0x00, 0x80, 0xd7, 0x05, 0x49, 0x00, 0x90, 0x4a, + 0x49, 0x01, 0x3c, 0x9b, 0x0f, 0x46, 0x4e, 0x46, 0xe3, 0x01, 0x90, 0x13, + 0x08, 0xad, 0x0f, 0x0d, 0xe3, 0xb5, 0x2b, 0x00, 0x49, 0x0c, 0xc7, 0x01, + 0x90, 0x2b, 0xe5, 0x40, 0x26, 0x00, 0x47, 0x01, 0x50, 0x39, 0x47, 0x01, + 0x90, 0x2b, 0x65, 0x01, 0x50, 0xc1, 0x03, 0x03, 0x50, 0x19, 0x6b, 0x00, + 0x90, 0xc3, 0x18, 0xb4, 0x07, 0x00, 0x49, 0x30, 0xff, 0xff, 0x6b, 0xb4, + 0x16, 0x00, 0x00, 0x0c, 0xa5, 0x40, 0x13, 0x00, 0xe3, 0x01, 0x90, 0x2b, + 0xa5, 0x40, 0x06, 0x00, 0x68, 0xb4, 0x0d, 0x00, 0xc7, 0x01, 0x90, 0x2b, + 0xe5, 0x40, 0x09, 0x00, 0x47, 0x01, 0x50, 0x39, 0x49, 0x30, 0xfe, 0xff, + 0x47, 0x01, 0x90, 0x2b, 0x65, 0x01, 0x50, 0x29, 0xd6, 0x05, 0xc7, 0x01, + 0xd0, 0x49, 0xe3, 0x01, 0xd0, 0x29, 0x27, 0x01, 0x90, 0x43, 0x05, 0x01, + 0xd0, 0x29, 0xab, 0x94, 0x7d, 0x00, 0xff, 0xed, 0x0d, 0x00, 0x3c, 0x70, + 0xa5, 0x01, 0x3c, 0xbb, 0x09, 0x01, 0x40, 0x80, 0x45, 0x46, 0x07, 0x46, + 0xa4, 0x00, 0x10, 0x72, 0xe7, 0x00, 0x00, 0x80, 0xe8, 0x00, 0x90, 0x3a, + 0xc7, 0x01, 0x90, 0x1b, 0x8f, 0x8d, 0xe5, 0x0d, 0x67, 0x01, 0x50, 0x39, + 0x67, 0x01, 0x90, 0x1b, 0x89, 0xad, 0xfe, 0x4d, 0xc7, 0x01, 0x90, 0x1b, + 0xe3, 0x40, 0x04, 0x00, 0xe5, 0x31, 0xfe, 0xff, 0x67, 0x01, 0x50, 0x39, + 0xc7, 0x01, 0xd0, 0x39, 0x69, 0xd0, 0xff, 0xff, 0x0d, 0x00, 0x3c, 0x70, + 0xa7, 0x01, 0x3c, 0xbb, 0x47, 0x46, 0x08, 0x46, 0xe4, 0x00, 0x10, 0x22, + 0x08, 0x01, 0x00, 0x80, 0x03, 0x01, 0x90, 0x1a, 0x83, 0x00, 0x90, 0x2b, + 0x90, 0x8e, 0x07, 0x0d, 0x63, 0x01, 0x50, 0x19, 0x63, 0x01, 0x90, 0x2b, + 0x8a, 0xae, 0x1e, 0x4d, 0x83, 0x00, 0x90, 0x2b, 0x88, 0x8e, 0xaf, 0x00, + 0x00, 0x80, 0x07, 0x31, 0xfe, 0xff, 0x63, 0x01, 0x50, 0x19, 0xaf, 0x00, + 0x00, 0x80, 0x47, 0x06, 0x05, 0x01, 0x90, 0x2a, 0xaa, 0x00, 0x3c, 0x9b, + 0x0f, 0x46, 0x4e, 0x46, 0x49, 0x46, 0xe4, 0x01, 0x90, 0x1b, 0x88, 0xad, + 0x0f, 0x0d, 0xe4, 0xb5, 0x27, 0x00, 0x65, 0x0c, 0x0e, 0x94, 0x28, 0x00, + 0xec, 0x30, 0xff, 0x03, 0x8b, 0x00, 0x50, 0x21, 0x64, 0x01, 0x90, 0x3b, + 0x96, 0xaf, 0xde, 0x6d, 0xe4, 0x01, 0x90, 0x3b, 0xa7, 0x40, 0x06, 0x00, + 0x88, 0xb4, 0x16, 0x00, 0xca, 0x01, 0x90, 0x3b, 0xe7, 0x40, 0x0e, 0x00, + 0x65, 0x30, 0xfe, 0xff, 0xaa, 0x00, 0x00, 0x08, 0x45, 0x01, 0x90, 0x53, + 0x6a, 0x01, 0x50, 0x59, 0x45, 0x0d, 0x64, 0x01, 0x50, 0x21, 0x04, 0xb5, + 0x05, 0x00, 0x00, 0x0c, 0x49, 0x95, 0x06, 0x00, 0xec, 0x30, 0xff, 0x03, + 0x63, 0x50, 0x01, 0x00, 0xec, 0x30, 0xff, 0x03, 0x87, 0x40, 0x4a, 0x00, + 0x35, 0x2e, 0x0d, 0x8e, 0x82, 0x00, 0x2c, 0x06, 0x84, 0xee, 0x37, 0x2e, + 0xa4, 0x94, 0x05, 0x00, 0x32, 0x6e, 0x64, 0x00, 0x90, 0x1b, 0x34, 0x05, + 0x64, 0x0c, 0x82, 0x00, 0x2c, 0x06, 0x08, 0x8e, 0x87, 0x90, 0xff, 0x07, + 0x40, 0x00, 0x0c, 0xc6, 0xec, 0x30, 0x00, 0x04, 0x87, 0x90, 0xff, 0x07, + 0x04, 0x94, 0x80, 0x00, 0x82, 0x00, 0x00, 0xe8, 0xb7, 0x25, 0x27, 0x25, + 0xdc, 0x44, 0x80, 0x0c, 0x82, 0x00, 0x0c, 0x98, 0x43, 0x0c, 0x87, 0x00, + 0x0c, 0xf5, 0x86, 0x00, 0xcc, 0xff, 0x9f, 0x45, 0x64, 0x0c, 0x9e, 0x4d, + 0xc0, 0xce, 0xe0, 0x0c, 0xa4, 0x41, 0x08, 0x00, 0x62, 0x01, 0x90, 0x5a, + 0x8b, 0x00, 0x50, 0x5a, 0x0b, 0x94, 0x5d, 0x00, 0xc5, 0x0c, 0x59, 0xcc, + 0x4e, 0x6d, 0xc7, 0x0c, 0x4b, 0x0c, 0x64, 0x0c, 0xaa, 0x0d, 0x02, 0xee, + 0x8d, 0x94, 0x5c, 0x00, 0x03, 0xee, 0x8d, 0x94, 0x50, 0x00, 0x01, 0xee, + 0x8d, 0xb4, 0xb8, 0xff, 0x00, 0x0c, 0x40, 0x0c, 0x31, 0xcc, 0x60, 0x0c, + 0xf2, 0xcf, 0xc5, 0x0c, 0x81, 0xee, 0xfb, 0x06, 0x85, 0x90, 0x39, 0x00, + 0x76, 0x8e, 0x85, 0x90, 0x20, 0x00, 0x28, 0x8e, 0x80, 0x30, 0xe1, 0xff, + 0xa0, 0xef, 0x65, 0x00, 0x50, 0x40, 0xdf, 0x07, 0x47, 0x00, 0x10, 0x20, + 0x67, 0x00, 0x10, 0x18, 0x04, 0x01, 0x90, 0x22, 0x60, 0x00, 0x90, 0x1b, + 0x45, 0x00, 0x50, 0x10, 0xdc, 0x44, 0x35, 0x2e, 0x0d, 0x8e, 0x82, 0x00, + 0xec, 0x05, 0x84, 0xee, 0x37, 0x2e, 0xa4, 0x94, 0x05, 0x00, 0x32, 0x6e, + 0x64, 0x00, 0x90, 0x1b, 0x34, 0x05, 0x64, 0x0c, 0x82, 0x00, 0xec, 0x05, + 0x2a, 0xae, 0x82, 0x00, 0x00, 0xe8, 0xb7, 0x25, 0x27, 0x25, 0xdc, 0x44, + 0xa6, 0xcf, 0xe0, 0x0c, 0x79, 0x06, 0xa0, 0x00, 0xd0, 0x39, 0x44, 0x00, + 0x50, 0x20, 0x47, 0x00, 0x10, 0x38, 0x45, 0x70, 0x20, 0x00, 0x40, 0x00, + 0x58, 0x38, 0x40, 0x0c, 0xdf, 0x44, 0x60, 0x00, 0x90, 0x1b, 0xd9, 0xcf, + 0xdc, 0x44, 0xa2, 0x41, 0x07, 0x00, 0x42, 0x50, 0xff, 0xff, 0xff, 0xed, + 0xc0, 0x0c, 0x42, 0x00, 0x2c, 0x90, 0x62, 0x00, 0x90, 0x22, 0xe4, 0x40, + 0x0a, 0x00, 0x87, 0xcf, 0xe0, 0x30, 0xff, 0x07, 0x40, 0x0c, 0xfb, 0xcf, + 0x60, 0x0c, 0x40, 0x0c, 0x60, 0x0c, 0x7f, 0xcf, 0x81, 0xef, 0xa2, 0x41, + 0x07, 0x00, 0xff, 0xed, 0x42, 0x50, 0xff, 0xff, 0xe0, 0x30, 0xff, 0x07, + 0x76, 0xcf, 0xc0, 0x0c, 0x45, 0x01, 0x2c, 0x55, 0x45, 0x00, 0x2c, 0x98, + 0x0a, 0x94, 0x45, 0x00, 0xa5, 0x00, 0x40, 0xf8, 0x60, 0x30, 0xff, 0x07, + 0x6a, 0x94, 0x6b, 0x00, 0x82, 0x00, 0x90, 0x4a, 0x64, 0x00, 0x40, 0xe8, + 0xa8, 0x41, 0x80, 0x00, 0x26, 0x25, 0x03, 0x01, 0x90, 0x1a, 0x24, 0x01, + 0x00, 0x18, 0x4a, 0x31, 0x01, 0xfc, 0xd3, 0x44, 0x60, 0x0d, 0x07, 0x01, + 0x2c, 0x55, 0x67, 0x00, 0x2c, 0x98, 0x08, 0x94, 0x68, 0x00, 0xe7, 0x00, + 0x40, 0xf8, 0x80, 0x30, 0xff, 0x07, 0x88, 0x94, 0x8b, 0x00, 0xc3, 0x00, + 0x90, 0x22, 0x86, 0x00, 0x40, 0xe8, 0xac, 0x41, 0x80, 0x00, 0xb6, 0x25, + 0x84, 0x01, 0x90, 0x22, 0xdc, 0x44, 0x66, 0x26, 0xc8, 0x30, 0x01, 0xfc, + 0x80, 0x0d, 0xca, 0x00, 0x50, 0x51, 0xcb, 0x00, 0x00, 0x10, 0xe5, 0x00, + 0x10, 0x43, 0x86, 0x01, 0x90, 0x32, 0x6e, 0x6f, 0xa6, 0xb1, 0x0f, 0x00, + 0x0d, 0x94, 0x83, 0x00, 0xca, 0x31, 0x01, 0x00, 0xaa, 0x41, 0x05, 0x80, + 0x4a, 0x31, 0x60, 0x94, 0xca, 0x00, 0x18, 0x31, 0xa6, 0x45, 0x82, 0x00, + 0x90, 0x4a, 0x09, 0x94, 0x30, 0x00, 0x40, 0x0d, 0x64, 0x00, 0x3c, 0x5b, + 0x42, 0x01, 0x3c, 0x5b, 0x63, 0x30, 0x20, 0x00, 0x0a, 0x0d, 0x43, 0x00, + 0x58, 0x40, 0x28, 0x31, 0xf5, 0xff, 0x69, 0x90, 0x1d, 0x00, 0x93, 0x8d, + 0x68, 0x30, 0xf8, 0xff, 0x40, 0x31, 0x1d, 0x00, 0x2a, 0x01, 0xd0, 0x51, + 0x43, 0x00, 0x10, 0x10, 0x8a, 0x00, 0x50, 0x50, 0x83, 0x00, 0x10, 0x48, + 0x4a, 0x00, 0x90, 0x12, 0x40, 0x31, 0x0d, 0xfc, 0xab, 0xcf, 0x0a, 0x01, + 0xd0, 0x51, 0x48, 0x30, 0xd8, 0xff, 0x20, 0x0d, 0xf7, 0xcf, 0x82, 0x00, + 0x10, 0x10, 0xe9, 0x40, 0x0a, 0x00, 0x24, 0x0d, 0x40, 0x31, 0xff, 0x07, + 0x9e, 0xcf, 0x60, 0x31, 0x03, 0x00, 0x40, 0x0c, 0x9a, 0xcf, 0x60, 0x31, + 0x01, 0x00, 0x40, 0x0c, 0x40, 0x31, 0xff, 0x07, 0x94, 0xcf, 0x60, 0x31, + 0x02, 0x00, 0xc3, 0x00, 0x90, 0x22, 0x2e, 0x8e, 0x03, 0x01, 0x3c, 0x5b, + 0x86, 0x00, 0x3c, 0x5b, 0x84, 0x30, 0x20, 0x00, 0x64, 0x00, 0x58, 0x40, + 0xa8, 0x31, 0xf5, 0xff, 0x8d, 0x90, 0x1d, 0x00, 0x13, 0x8e, 0x80, 0x31, + 0x1d, 0x00, 0x88, 0x30, 0xf8, 0xff, 0xac, 0x01, 0xd0, 0x61, 0x64, 0x00, + 0x10, 0x18, 0xcc, 0x00, 0x50, 0x60, 0xc4, 0x00, 0x10, 0x20, 0x6c, 0x00, + 0x90, 0x1a, 0xc0, 0x30, 0x0d, 0xfc, 0x8a, 0xcf, 0x06, 0x01, 0xd0, 0x31, + 0x68, 0x30, 0xd8, 0xff, 0x80, 0x0c, 0xf7, 0xcf, 0xc3, 0x00, 0x10, 0x18, + 0xe4, 0x40, 0x0b, 0x00, 0x86, 0x0c, 0x80, 0x31, 0x03, 0x00, 0x7d, 0xcf, + 0xc0, 0x30, 0xff, 0x07, 0x60, 0x0c, 0xc0, 0x0c, 0x78, 0xcf, 0x80, 0x31, + 0x01, 0x00, 0x60, 0x0c, 0xc0, 0x30, 0xff, 0x07, 0x72, 0xcf, 0x80, 0x31, + 0x02, 0x00, 0xb0, 0x4f, 0x89, 0x00, 0x3c, 0x9b, 0x5d, 0x20, 0x00, 0xd0, + 0x0d, 0x46, 0x4c, 0x46, 0x69, 0x00, 0x3c, 0x9b, 0x58, 0x46, 0x19, 0x46, + 0x44, 0x00, 0x3c, 0x9b, 0x44, 0x46, 0x05, 0x46, 0x43, 0x00, 0x3c, 0x9b, + 0x0d, 0x03, 0x50, 0x39, 0x07, 0x03, 0x90, 0x13, 0x50, 0x46, 0x11, 0x46, + 0xce, 0x07, 0x87, 0x00, 0x90, 0x5b, 0x19, 0x02, 0x50, 0x31, 0xc2, 0x00, + 0x50, 0x69, 0x26, 0x03, 0x90, 0x33, 0xad, 0x00, 0x50, 0x21, 0x4d, 0x00, + 0x90, 0x13, 0x8b, 0x00, 0x50, 0x49, 0xd6, 0x44, 0x69, 0x01, 0x90, 0x5b, + 0x14, 0x05, 0xa4, 0x00, 0x90, 0x23, 0x64, 0x01, 0x90, 0x22, 0x44, 0x05, + 0x69, 0x00, 0x40, 0xb8, 0x42, 0x00, 0x00, 0x48, 0x29, 0x01, 0x00, 0x48, + 0xd3, 0x44, 0x67, 0x00, 0x00, 0x48, 0xe7, 0x00, 0x40, 0xb8, 0x83, 0x01, + 0x90, 0x1a, 0x60, 0x00, 0x90, 0x1b, 0xdf, 0x44, 0x23, 0x01, 0x90, 0x4a, + 0x62, 0x00, 0x2c, 0x06, 0x03, 0x94, 0x80, 0x00, 0x89, 0x00, 0x40, 0x08, + 0x69, 0xd0, 0x01, 0x00, 0x22, 0x01, 0x00, 0xf8, 0xdc, 0x44, 0x23, 0x25, + 0x23, 0x01, 0x90, 0x4a, 0xce, 0x30, 0xff, 0x03, 0x86, 0x40, 0x74, 0x00, + 0x69, 0xd0, 0x07, 0x00, 0x8f, 0x8d, 0x62, 0x00, 0x2c, 0x06, 0x04, 0xee, + 0x69, 0xd0, 0x0f, 0x00, 0x83, 0x94, 0x06, 0x00, 0x89, 0x30, 0x04, 0x00, + 0x24, 0x01, 0x90, 0x1b, 0x34, 0x05, 0x24, 0x0d, 0x62, 0x00, 0x2c, 0x06, + 0x88, 0x8d, 0x66, 0x90, 0xff, 0x07, 0x40, 0x00, 0x0c, 0xc6, 0xce, 0x30, + 0x00, 0x04, 0x66, 0x90, 0xff, 0x07, 0x03, 0x94, 0xaa, 0x00, 0x69, 0x00, + 0x40, 0x18, 0x22, 0x01, 0x00, 0xe8, 0x27, 0x25, 0x69, 0x00, 0x90, 0x4a, + 0x60, 0x0c, 0x5d, 0x20, 0x00, 0x50, 0x62, 0x00, 0x0c, 0x98, 0x49, 0x0c, + 0x66, 0x00, 0x0c, 0xf5, 0x68, 0x00, 0xcc, 0xff, 0x02, 0x47, 0xa4, 0x41, + 0x08, 0x00, 0xda, 0x44, 0x9c, 0x44, 0x03, 0x94, 0x89, 0x00, 0x05, 0x0d, + 0x84, 0xcc, 0x4e, 0x6d, 0x05, 0x0d, 0x82, 0xed, 0x6b, 0x94, 0xed, 0x00, + 0x00, 0x0c, 0x83, 0xed, 0x6b, 0x94, 0x7e, 0x00, 0x81, 0xed, 0x6b, 0x94, + 0xe9, 0x00, 0x00, 0x0c, 0xce, 0x30, 0xff, 0x03, 0x86, 0x40, 0x9d, 0x00, + 0x69, 0xd0, 0x07, 0x00, 0x8f, 0x8d, 0x62, 0x00, 0x2c, 0x06, 0x04, 0xee, + 0x69, 0xd0, 0x0f, 0x00, 0x83, 0x94, 0x06, 0x00, 0x89, 0x30, 0x04, 0x00, + 0x24, 0x01, 0x90, 0x1b, 0x34, 0x05, 0x24, 0x0d, 0x62, 0x00, 0x2c, 0x06, + 0x88, 0x8d, 0x66, 0x90, 0xff, 0x07, 0x40, 0x00, 0x0c, 0xc6, 0xce, 0x30, + 0x00, 0x04, 0x66, 0x90, 0xff, 0x07, 0xe3, 0x40, 0xc4, 0x00, 0x69, 0x00, + 0x40, 0x18, 0x22, 0x01, 0x00, 0xe8, 0x27, 0x25, 0x71, 0xcc, 0x69, 0x00, + 0x90, 0x4a, 0x07, 0x0d, 0x43, 0x0c, 0x24, 0x0d, 0xc8, 0xcf, 0x6c, 0x0d, + 0x89, 0xcf, 0xca, 0x0d, 0x81, 0xee, 0xeb, 0x06, 0x65, 0x90, 0x39, 0x00, + 0x03, 0x94, 0x52, 0x00, 0x65, 0x90, 0x20, 0x00, 0xa8, 0x8d, 0x80, 0x30, + 0xe1, 0xff, 0xa0, 0xed, 0x25, 0x01, 0x50, 0x30, 0xd7, 0x05, 0x43, 0x00, + 0x10, 0x20, 0x23, 0x01, 0x10, 0x18, 0xe6, 0x44, 0x60, 0x00, 0x90, 0x1b, + 0x45, 0x00, 0x50, 0x10, 0xdc, 0x44, 0x35, 0x2e, 0x0d, 0x8e, 0x82, 0x00, + 0xec, 0x05, 0x84, 0xee, 0x37, 0x2e, 0xa4, 0x94, 0x05, 0x00, 0x32, 0x6e, + 0x64, 0x00, 0x90, 0x1b, 0x34, 0x05, 0x64, 0x0c, 0x82, 0x00, 0xec, 0x05, + 0x32, 0xae, 0xb7, 0x25, 0x22, 0x01, 0x00, 0xe8, 0x27, 0x25, 0x69, 0x00, + 0x90, 0x4a, 0x80, 0xcf, 0xc0, 0x0c, 0xa0, 0x00, 0xd0, 0x19, 0x69, 0x06, + 0x43, 0x00, 0x10, 0x18, 0x44, 0x00, 0x50, 0x20, 0x45, 0x70, 0x20, 0x00, + 0x40, 0x00, 0x58, 0x18, 0x40, 0x0c, 0x23, 0x01, 0x90, 0x1a, 0x60, 0x00, + 0x90, 0x1b, 0xd7, 0xcf, 0xdc, 0x44, 0xa2, 0x41, 0x07, 0x00, 0x42, 0x50, + 0xff, 0xff, 0x20, 0x31, 0xff, 0xff, 0x00, 0x0d, 0x42, 0x00, 0x2c, 0x90, + 0x22, 0x01, 0x90, 0x1a, 0xe3, 0x40, 0x0f, 0x00, 0x17, 0xcc, 0xc0, 0x30, + 0xff, 0x07, 0x40, 0x0c, 0x20, 0x0d, 0x5a, 0xcf, 0xc0, 0x30, 0xff, 0x07, + 0x40, 0x0c, 0xd5, 0xcf, 0x20, 0x0d, 0x40, 0x0c, 0x20, 0x0d, 0x52, 0xcf, + 0x01, 0xef, 0xa2, 0x41, 0x07, 0x00, 0x20, 0x31, 0xff, 0xff, 0xc0, 0x30, + 0xff, 0x07, 0x00, 0x0d, 0x42, 0x50, 0xff, 0xff, 0x60, 0x0c, 0x62, 0x00, + 0x0c, 0x98, 0x49, 0x0c, 0x66, 0x00, 0x0c, 0xf5, 0x9f, 0x45, 0x68, 0x00, + 0xcc, 0xff, 0x81, 0xee, 0xeb, 0x06, 0x65, 0x90, 0x39, 0x00, 0xe3, 0x40, + 0x41, 0x00, 0x65, 0x90, 0x20, 0x00, 0xa9, 0x8d, 0x80, 0x30, 0xe1, 0xff, + 0xa0, 0xed, 0x25, 0x01, 0x50, 0x30, 0xd7, 0x05, 0x43, 0x00, 0x10, 0x20, + 0x23, 0x01, 0x10, 0x18, 0xe6, 0x44, 0x60, 0x00, 0x90, 0x1b, 0x45, 0x00, + 0x50, 0x10, 0xdc, 0x44, 0x35, 0x2e, 0x0d, 0x8e, 0x82, 0x00, 0xec, 0x05, + 0x84, 0xee, 0x37, 0x2e, 0xa4, 0x94, 0x05, 0x00, 0x32, 0x6e, 0x64, 0x00, + 0x90, 0x1b, 0x34, 0x05, 0x64, 0x0c, 0x82, 0x00, 0xec, 0x05, 0xa4, 0x40, + 0x20, 0x00, 0x22, 0x01, 0x00, 0xe8, 0xb7, 0x25, 0x27, 0x25, 0x69, 0x00, + 0x90, 0x4a, 0xc6, 0xcf, 0xc0, 0x0c, 0xa0, 0x00, 0xd0, 0x19, 0x69, 0x06, + 0x43, 0x00, 0x10, 0x18, 0x44, 0x00, 0x50, 0x20, 0x45, 0x70, 0x20, 0x00, + 0x40, 0x00, 0x58, 0x18, 0x40, 0x0c, 0x23, 0x01, 0x90, 0x1a, 0x60, 0x00, + 0x90, 0x1b, 0xd6, 0xcf, 0xdc, 0x44, 0x40, 0x0c, 0x99, 0xcf, 0x20, 0x0d, + 0x40, 0x0c, 0xe7, 0xcf, 0x20, 0x0d, 0x40, 0x0c, 0x20, 0x0d, 0xaa, 0xcf, + 0x01, 0xef, 0x00, 0x0c, 0xc5, 0x00, 0x2c, 0x55, 0x46, 0x90, 0xff, 0x03, + 0x35, 0xad, 0x65, 0x00, 0x2c, 0x98, 0xa5, 0x00, 0x40, 0xf8, 0xae, 0xae, + 0x46, 0x90, 0x3e, 0x04, 0x46, 0x90, 0x3f, 0x04, 0x10, 0x8d, 0x5e, 0x6d, + 0xa5, 0x41, 0x10, 0x00, 0x46, 0x90, 0x33, 0x04, 0x0c, 0xad, 0xeb, 0x44, + 0xf5, 0x4f, 0xe5, 0xcb, 0x02, 0xf4, 0x5a, 0x27, 0xc6, 0x30, 0xcd, 0xfb, + 0xe5, 0x4b, 0x06, 0x47, 0x5e, 0x6d, 0x9f, 0x45, 0x62, 0x0c, 0x60, 0x30, + 0x33, 0x04, 0xe7, 0x05, 0x43, 0x90, 0x20, 0x00, 0x0a, 0x8d, 0x83, 0x00, + 0x50, 0x20, 0x46, 0x30, 0xed, 0xfb, 0xa2, 0x00, 0x10, 0x10, 0xa3, 0x00, + 0x50, 0x18, 0x9f, 0x45, 0xd4, 0x44, 0x40, 0x30, 0x13, 0x04, 0x65, 0x05, + 0xa2, 0x00, 0x50, 0x10, 0x9f, 0x45, 0x60, 0x0c, 0xe2, 0x40, 0xe4, 0xff, + 0xfb, 0xcf, 0x40, 0x0c, 0xed, 0x4f, 0xa4, 0x00, 0x90, 0x12, 0xbd, 0x22, + 0x10, 0xd0, 0x02, 0x94, 0x7c, 0x00, 0x64, 0x02, 0x3c, 0x5b, 0x65, 0x00, + 0x3c, 0x5b, 0x73, 0x32, 0x20, 0x00, 0x20, 0x32, 0x3e, 0x04, 0xa3, 0x00, + 0x18, 0x98, 0x04, 0x0e, 0x45, 0x0e, 0x71, 0x02, 0xd0, 0x89, 0x71, 0x90, + 0x34, 0x04, 0xa6, 0x8d, 0x45, 0x0c, 0x60, 0x30, 0x33, 0x04, 0x97, 0x05, + 0x8e, 0x8d, 0xa3, 0x90, 0x20, 0x00, 0x97, 0x8e, 0xab, 0xee, 0x43, 0x02, + 0x10, 0x10, 0x65, 0x02, 0xd0, 0x99, 0x93, 0x00, 0x50, 0x98, 0x83, 0x00, + 0x10, 0x20, 0x53, 0x00, 0x90, 0x12, 0x60, 0x0c, 0x62, 0x00, 0x0c, 0x98, + 0x44, 0x0c, 0x71, 0x00, 0x0c, 0xf5, 0xbd, 0x22, 0x10, 0x50, 0xa3, 0x00, + 0x2c, 0xf0, 0x65, 0x0c, 0x0a, 0x47, 0x40, 0x30, 0x13, 0x04, 0x15, 0x05, + 0x82, 0x00, 0x10, 0x10, 0xee, 0xcf, 0x80, 0x0c, 0x51, 0x90, 0x37, 0x04, + 0x12, 0xad, 0xc0, 0x30, 0x76, 0x04, 0x02, 0xf4, 0x5a, 0x27, 0x26, 0x02, + 0xd0, 0x31, 0x08, 0xef, 0xd8, 0x86, 0x66, 0x02, 0xd0, 0x31, 0xd3, 0x44, + 0x02, 0xf4, 0x44, 0x27, 0x40, 0x00, 0x90, 0xa3, 0x54, 0x00, 0x90, 0x82, + 0x43, 0x0e, 0xa0, 0x30, 0x36, 0x04, 0x9b, 0x06, 0x85, 0x40, 0x0c, 0x00, + 0x90, 0x0c, 0x28, 0xed, 0x45, 0x02, 0x10, 0x90, 0x62, 0x02, 0xd0, 0x11, + 0x05, 0x02, 0x10, 0x20, 0x02, 0x02, 0x50, 0x10, 0x42, 0x02, 0x90, 0x92, + 0x52, 0x0c, 0xc5, 0x2d, 0x8b, 0x8d, 0x40, 0x00, 0xcc, 0xbd, 0x84, 0xee, + 0xc7, 0x2d, 0xa3, 0x94, 0x05, 0x00, 0xc2, 0x6d, 0x83, 0x00, 0x90, 0x23, + 0x44, 0x05, 0x83, 0x0c, 0x62, 0x00, 0xec, 0x05, 0x8a, 0x8d, 0x62, 0x00, + 0x00, 0xe8, 0x20, 0x32, 0x3f, 0x04, 0x40, 0x00, 0xcc, 0xbd, 0x71, 0x02, + 0xd0, 0x89, 0x62, 0x00, 0x00, 0xe8, 0x47, 0x26, 0x27, 0x25, 0xa9, 0xcf, + 0xe3, 0x44, 0x40, 0x0c, 0x80, 0x0c, 0xa5, 0xcf, 0x20, 0x0e, 0x00, 0x0c, + 0x0d, 0x8f, 0x44, 0x0c, 0xa0, 0xed, 0xe7, 0x05, 0xc3, 0x40, 0x0a, 0x00, + 0xa6, 0x00, 0x50, 0x20, 0x60, 0x00, 0xd0, 0x11, 0x80, 0x0c, 0xa2, 0x00, + 0x50, 0x10, 0xa4, 0x0c, 0x9f, 0x45, 0x65, 0x0c, 0x46, 0x00, 0x50, 0x10, + 0xa3, 0x00, 0x10, 0x28, 0xf8, 0xcf, 0xd5, 0x44, 0x0d, 0x8f, 0x44, 0x0c, + 0x20, 0xee, 0x69, 0x06, 0xc4, 0x40, 0x0a, 0x00, 0xa6, 0x00, 0x10, 0x28, + 0x80, 0x00, 0xd0, 0x29, 0x60, 0x0c, 0x45, 0x00, 0x10, 0x28, 0x43, 0x0c, + 0x9f, 0x45, 0x65, 0x0c, 0x46, 0x00, 0x10, 0x18, 0x44, 0x00, 0x50, 0x10, + 0xf8, 0xcf, 0xea, 0x44, 0xc0, 0x0a, 0x87, 0xed, 0x65, 0x94, 0x05, 0x00, + 0xb9, 0x41, 0x01, 0x80, 0x39, 0x33, 0x45, 0x1a, 0xb9, 0x45, 0x41, 0x69, + 0x0c, 0x8d, 0x81, 0xed, 0x62, 0xb4, 0x08, 0x00, 0xa3, 0x41, 0x00, 0xa4, + 0x43, 0xfc, 0xc8, 0x2d, 0x40, 0x00, 0x8c, 0x52, 0x43, 0xf8, 0xc8, 0x2d, + 0xbf, 0x45, 0xa3, 0x41, 0x00, 0xa4, 0x43, 0xfc, 0xc8, 0x2d, 0x42, 0x50, + 0x00, 0x04, 0x43, 0xf8, 0xc8, 0x2d, 0xbf, 0x45, 0x55, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x3d, 0x22, 0x50, 0xd1, 0x42, 0x30, 0x39, 0x17, 0xe2, 0x45, + 0x04, 0x0e, 0x10, 0xb4, 0x6d, 0x00, 0xa4, 0x41, 0x01, 0xa4, 0xa2, 0x41, + 0x05, 0x80, 0x84, 0x50, 0x00, 0xbc, 0x81, 0xed, 0x42, 0x30, 0xe8, 0x92, + 0xbd, 0x30, 0x0c, 0x01, 0xc0, 0xe9, 0x40, 0xe8, 0x65, 0x0c, 0x82, 0x30, + 0x40, 0x00, 0x22, 0xfd, 0x00, 0x00, 0x02, 0xfd, 0x04, 0x00, 0xa2, 0x6b, + 0x23, 0x6b, 0x28, 0x6d, 0x23, 0xf9, 0x00, 0x00, 0x03, 0xf9, 0x04, 0x00, + 0xb2, 0xeb, 0x33, 0xeb, 0x82, 0xb4, 0xf1, 0xff, 0xb8, 0x6d, 0xa6, 0x41, + 0x01, 0xa4, 0xc6, 0x50, 0x04, 0xbc, 0xfd, 0x30, 0x4c, 0x01, 0x45, 0x0c, + 0x5d, 0x07, 0x20, 0x6a, 0xac, 0x05, 0x22, 0x6d, 0x30, 0xea, 0xe2, 0xb4, + 0xfa, 0xff, 0x89, 0x6d, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0x28, 0x93, + 0x82, 0x30, 0xf0, 0x00, 0x22, 0xfd, 0x00, 0x00, 0x02, 0xfd, 0x04, 0x00, + 0xa2, 0x6b, 0x23, 0x6b, 0x28, 0x6d, 0x23, 0xf9, 0x00, 0x00, 0x03, 0xf9, + 0x04, 0x00, 0xb2, 0xeb, 0x33, 0xeb, 0x82, 0xb4, 0xf1, 0xff, 0xb8, 0x6d, + 0x21, 0x6b, 0x02, 0xfd, 0x00, 0x00, 0x22, 0x6a, 0xa7, 0x41, 0x01, 0xa4, + 0xe7, 0x50, 0x44, 0xbc, 0x09, 0x6d, 0x31, 0xeb, 0x03, 0xf9, 0x00, 0x00, + 0x32, 0xea, 0x2f, 0x07, 0x20, 0x6a, 0xac, 0x05, 0x22, 0x6d, 0x30, 0xea, + 0x45, 0xb4, 0xfa, 0xff, 0xa3, 0x41, 0x00, 0xa5, 0x63, 0x50, 0x34, 0x9a, + 0x30, 0x69, 0x40, 0x00, 0x0c, 0x50, 0x42, 0x50, 0x00, 0x07, 0x30, 0xe9, + 0x47, 0xfc, 0xbc, 0xff, 0x47, 0xf8, 0xbc, 0xff, 0xa2, 0x41, 0x01, 0x80, + 0x42, 0x30, 0xf5, 0x15, 0xe2, 0x45, 0x00, 0x0c, 0xa3, 0x41, 0x00, 0xa4, + 0x43, 0xfc, 0xc8, 0x2d, 0x3d, 0x22, 0x50, 0x51, 0x42, 0x50, 0x00, 0x02, + 0x43, 0xf8, 0xc8, 0x2d, 0x9f, 0x45, 0xad, 0x4c, 0xf1, 0x4f, 0xa3, 0x41, + 0x01, 0xa4, 0x63, 0x50, 0x00, 0xbc, 0x01, 0xed, 0xa8, 0x41, 0x04, 0x80, + 0x30, 0xe9, 0xa8, 0x30, 0x00, 0x00, 0xa6, 0x41, 0x04, 0x80, 0xa2, 0x41, + 0x04, 0x80, 0xe3, 0x0c, 0xc6, 0x30, 0x40, 0x01, 0xd7, 0x06, 0x30, 0xe8, + 0x42, 0x30, 0x04, 0x00, 0x20, 0x6a, 0xaa, 0x05, 0x22, 0x6d, 0x30, 0xea, + 0xc2, 0xb4, 0xfa, 0xff, 0xa4, 0x41, 0x00, 0xa5, 0xa8, 0xfc, 0x00, 0x00, + 0x84, 0x50, 0x34, 0x9a, 0xa3, 0x41, 0x02, 0xa5, 0xc4, 0x30, 0x20, 0x9a, + 0xf0, 0xea, 0x43, 0x31, 0x24, 0x0c, 0x84, 0x31, 0x04, 0x00, 0x64, 0x31, + 0x08, 0x00, 0xb6, 0x6d, 0x24, 0x31, 0x28, 0xff, 0x04, 0x31, 0x08, 0x9a, + 0xc7, 0xc8, 0xa6, 0x41, 0x04, 0x80, 0x80, 0xc8, 0x81, 0xc9, 0x62, 0xc9, + 0x43, 0xc9, 0x64, 0xc8, 0x25, 0xc9, 0x06, 0xc9, 0x83, 0x6e, 0x04, 0xcc, + 0xc6, 0x30, 0x60, 0x01, 0x50, 0x6a, 0xd2, 0x6e, 0xa0, 0x69, 0x22, 0x6d, + 0xb0, 0x25, 0xc0, 0xe9, 0xc2, 0xb4, 0xf8, 0xff, 0x00, 0x0c, 0x9f, 0x45, + 0x11, 0x4c, 0x00, 0x0c, 0xf5, 0x4f, 0x44, 0x45, 0xb0, 0x41, 0x01, 0xa4, + 0x10, 0x52, 0x00, 0xbc, 0x01, 0xed, 0x00, 0xe9, 0xa2, 0x41, 0x01, 0x80, + 0x00, 0xe8, 0x42, 0x30, 0xfd, 0x19, 0xe2, 0x45, 0x00, 0x0c, 0x00, 0x69, + 0x42, 0x50, 0x02, 0x00, 0x00, 0xe9, 0x04, 0x45, 0x06, 0x47, 0x00, 0x0c, + 0x42, 0x69, 0x81, 0xee, 0xa2, 0x94, 0x14, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x6c, 0x23, 0xa2, 0x69, 0x43, 0x6a, 0xb0, 0x6d, 0xa4, 0x94, + 0x06, 0x00, 0xa2, 0xe9, 0xa4, 0x69, 0xb0, 0x6d, 0xa4, 0xe9, 0x9f, 0x45, + 0x40, 0x0c, 0xa3, 0x69, 0xb0, 0x6d, 0xa3, 0xe9, 0x9f, 0x45, 0x40, 0x0c, + 0xb9, 0x41, 0x01, 0x80, 0x39, 0x33, 0x31, 0x1c, 0xb9, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x02, 0xa5, 0x62, 0xfc, 0x10, 0x0d, 0xa4, 0x41, 0x05, 0x80, + 0xb1, 0x25, 0x64, 0xf8, 0xa0, 0x94, 0x62, 0xfc, 0x14, 0x0d, 0xa4, 0x41, + 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xa4, 0x94, 0x62, 0xfc, 0x18, 0x0d, + 0xa4, 0x41, 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xa8, 0x94, 0x62, 0xfc, + 0x1c, 0x0d, 0xa4, 0x41, 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xac, 0x94, + 0x62, 0xfc, 0x20, 0x0d, 0xa4, 0x41, 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, + 0xb0, 0x94, 0x62, 0xfc, 0x24, 0x0d, 0xa4, 0x41, 0x05, 0x80, 0xb1, 0x25, + 0x64, 0xf8, 0xb4, 0x94, 0x62, 0xfc, 0x28, 0x0d, 0xa4, 0x41, 0x05, 0x80, + 0xb1, 0x25, 0x64, 0xf8, 0xb8, 0x94, 0x62, 0xfc, 0x2c, 0x0d, 0xa4, 0x41, + 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xbc, 0x94, 0x62, 0xfc, 0x30, 0x0d, + 0xa4, 0x41, 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xc0, 0x94, 0x62, 0xfc, + 0x34, 0x0d, 0xa4, 0x41, 0x05, 0x80, 0xb1, 0x25, 0x64, 0xf8, 0xc4, 0x94, + 0x42, 0xfc, 0x38, 0x0d, 0xa3, 0x41, 0x05, 0x80, 0x21, 0x25, 0x9f, 0x45, + 0x43, 0xf8, 0xc8, 0x94, 0x44, 0xfc, 0xbc, 0x01, 0x64, 0xfc, 0xc8, 0x01, + 0xa5, 0x2e, 0xb0, 0xae, 0x63, 0x00, 0xac, 0x28, 0xa2, 0x41, 0x05, 0x80, + 0xa2, 0xfc, 0xa0, 0x94, 0x44, 0x34, 0xbc, 0x01, 0xa3, 0x00, 0x50, 0x28, + 0x45, 0x00, 0x8c, 0x52, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x05, 0x80, + 0xa5, 0xfc, 0xac, 0x94, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0xcc, 0x5a, + 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x05, 0x80, 0xa5, 0xfc, 0xb8, 0x94, + 0xa3, 0x00, 0x50, 0x18, 0x43, 0x00, 0x0c, 0x63, 0x44, 0x38, 0xbc, 0x01, + 0x64, 0xfc, 0xbc, 0x01, 0x63, 0xd0, 0x18, 0x00, 0xbc, 0xad, 0xa3, 0x41, + 0x05, 0x80, 0x63, 0xfc, 0xc4, 0x94, 0x43, 0x00, 0x4c, 0x73, 0x9f, 0x45, + 0x44, 0x38, 0xbc, 0x01, 0x42, 0xd0, 0x05, 0x00, 0x01, 0xef, 0xc2, 0x94, + 0x36, 0x00, 0x00, 0x0c, 0x07, 0xed, 0x45, 0x94, 0x70, 0x00, 0xa2, 0x41, + 0x05, 0x80, 0xa2, 0xfc, 0xa8, 0x94, 0x44, 0x34, 0xbc, 0x01, 0xa3, 0x00, + 0x50, 0x28, 0x45, 0x00, 0x8c, 0x52, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, + 0x05, 0x80, 0xa5, 0xfc, 0xb4, 0x94, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, + 0xcc, 0x5a, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, 0x05, 0x80, 0xa5, 0xfc, + 0xc0, 0x94, 0xa3, 0x00, 0x50, 0x18, 0x43, 0x00, 0x0c, 0x63, 0x44, 0x38, + 0xbc, 0x01, 0xa3, 0x41, 0x05, 0x80, 0x63, 0xfc, 0xc4, 0x94, 0xb1, 0x25, + 0x43, 0x00, 0x4c, 0x73, 0x9f, 0x45, 0x44, 0x38, 0xbc, 0x01, 0x63, 0xfc, + 0xc4, 0x94, 0xb5, 0x25, 0x43, 0x00, 0x4c, 0x73, 0x9f, 0x45, 0x44, 0x38, + 0xbc, 0x01, 0xa5, 0x41, 0x05, 0x80, 0xc5, 0xfc, 0xa4, 0x94, 0xa4, 0x34, + 0xbc, 0x01, 0xc3, 0x00, 0x50, 0x30, 0xa6, 0x00, 0x8c, 0x52, 0xa4, 0x38, + 0xbc, 0x01, 0xa6, 0x41, 0x05, 0x80, 0xc6, 0xfc, 0xb0, 0x94, 0xc3, 0x00, + 0x50, 0x30, 0xa6, 0x00, 0xcc, 0x5a, 0xa4, 0x38, 0xbc, 0x01, 0xa6, 0x41, + 0x05, 0x80, 0xc6, 0xfc, 0xbc, 0x94, 0xc3, 0x00, 0x50, 0x30, 0xa6, 0x00, + 0x0c, 0x63, 0xa4, 0x38, 0xbc, 0x01, 0xc4, 0xfc, 0xbc, 0x01, 0x65, 0x2f, + 0x46, 0x94, 0x0a, 0x00, 0xa2, 0x41, 0x05, 0x80, 0x42, 0xfc, 0xc4, 0x94, + 0x2d, 0x25, 0xa2, 0x00, 0x4c, 0x73, 0x9f, 0x45, 0xa4, 0x38, 0xbc, 0x01, + 0xa2, 0x41, 0x05, 0x80, 0xc2, 0xfc, 0xc8, 0x94, 0x46, 0x00, 0xac, 0x10, + 0x43, 0x00, 0x90, 0x1b, 0xe3, 0x40, 0x2e, 0x00, 0xa6, 0x00, 0x4c, 0x73, + 0x9f, 0x45, 0xa4, 0x38, 0xbc, 0x01, 0xa2, 0xfc, 0xa8, 0x94, 0x44, 0x34, + 0xbc, 0x01, 0xa3, 0x00, 0x50, 0x28, 0x45, 0x00, 0x8c, 0x52, 0x44, 0x38, + 0xbc, 0x01, 0xa5, 0x41, 0x05, 0x80, 0xa5, 0xfc, 0xb4, 0x94, 0xa3, 0x00, + 0x50, 0x28, 0x45, 0x00, 0xcc, 0x5a, 0x44, 0x38, 0xbc, 0x01, 0xa5, 0x41, + 0x05, 0x80, 0xa5, 0xfc, 0xc0, 0x94, 0xa3, 0x00, 0x50, 0x18, 0x43, 0x00, + 0x0c, 0x63, 0x44, 0x38, 0xbc, 0x01, 0xa3, 0x41, 0x05, 0x80, 0x63, 0xfc, + 0xc4, 0x94, 0x63, 0x00, 0x40, 0x50, 0x43, 0x00, 0x4c, 0x73, 0x9f, 0x45, + 0x44, 0x38, 0xbc, 0x01, 0xa2, 0x41, 0x05, 0x80, 0x42, 0xfc, 0xc4, 0x94, + 0x29, 0x25, 0xa2, 0x00, 0x4c, 0x73, 0x9f, 0x45, 0xa4, 0x38, 0xbc, 0x01, + 0xf5, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xc9, 0x51, 0xe5, 0xcb, + 0xe2, 0x45, 0xe4, 0x0c, 0x44, 0x34, 0xbc, 0x01, 0x40, 0x00, 0x4c, 0x4a, + 0x44, 0x38, 0xbc, 0x01, 0x64, 0x60, 0x52, 0x00, 0x64, 0x60, 0x4f, 0x10, + 0x31, 0x2e, 0xe4, 0x40, 0x27, 0x00, 0x87, 0x14, 0x75, 0x00, 0x87, 0xee, + 0x45, 0x00, 0x0c, 0x10, 0x9a, 0xee, 0xa4, 0x94, 0x91, 0x00, 0x47, 0x38, + 0xbc, 0x01, 0x34, 0xed, 0x44, 0x94, 0xaf, 0x00, 0x6a, 0xed, 0x44, 0x94, + 0x94, 0x00, 0x40, 0x30, 0xf2, 0x00, 0x44, 0x94, 0xbf, 0x00, 0x00, 0x0c, + 0x47, 0xfc, 0xe4, 0x01, 0x87, 0xfc, 0xe8, 0x01, 0xa0, 0x30, 0xa0, 0x0f, + 0x45, 0x00, 0x4c, 0xa2, 0x80, 0x00, 0x8c, 0x52, 0x40, 0x00, 0x4c, 0xb5, + 0x80, 0x00, 0xcc, 0x6a, 0x47, 0xf8, 0xe4, 0x01, 0x87, 0xf8, 0xe8, 0x01, + 0x47, 0xfc, 0xbc, 0x01, 0x04, 0xee, 0x42, 0xd0, 0x05, 0x00, 0x82, 0x94, + 0x3e, 0x00, 0xa7, 0xfc, 0xf8, 0x01, 0xa5, 0xd0, 0x00, 0x3f, 0x40, 0x30, + 0x00, 0x01, 0x45, 0x94, 0x56, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0xe8, 0x02, 0x62, 0xfc, 0xa4, 0x0b, 0xb6, 0x2d, 0xa4, 0x8d, + 0xbc, 0xfc, 0x90, 0xab, 0x87, 0x34, 0x44, 0x01, 0xc7, 0xfc, 0xa4, 0x01, + 0xd6, 0x25, 0xd6, 0x05, 0xb6, 0x25, 0xd7, 0x05, 0xb6, 0x25, 0x34, 0x05, + 0x62, 0xfc, 0x50, 0x02, 0x68, 0x05, 0x43, 0x00, 0x90, 0x13, 0xe2, 0x40, + 0x0b, 0x00, 0xe3, 0x40, 0x09, 0x00, 0x47, 0xfc, 0x48, 0x01, 0x06, 0x8d, + 0x81, 0xed, 0x47, 0x14, 0x76, 0x00, 0x62, 0x94, 0x83, 0x00, 0x00, 0x0c, + 0x07, 0x18, 0x15, 0x01, 0xe5, 0x4b, 0x07, 0x18, 0xf4, 0x01, 0x06, 0x47, + 0x47, 0x14, 0x15, 0x01, 0x7a, 0x8d, 0xe5, 0x4b, 0xe5, 0x4b, 0x01, 0xed, + 0x47, 0x18, 0xf4, 0x01, 0x06, 0x47, 0x40, 0x30, 0x10, 0x01, 0x85, 0xd0, + 0x10, 0x3f, 0x44, 0x94, 0x3e, 0x00, 0xb2, 0x2d, 0xc7, 0xfc, 0xc8, 0x01, + 0x87, 0x30, 0x60, 0x00, 0x60, 0x0c, 0x00, 0x31, 0x04, 0x00, 0xc6, 0x00, + 0xac, 0x28, 0x40, 0x09, 0x2b, 0x2d, 0xc2, 0x94, 0x48, 0x00, 0x40, 0x6e, + 0xb0, 0x6d, 0x03, 0xb5, 0xf8, 0xff, 0x40, 0x30, 0x00, 0x01, 0xa5, 0xd0, + 0x00, 0x3f, 0x45, 0xb4, 0xaf, 0xff, 0xa2, 0x41, 0x04, 0x80, 0x47, 0x14, + 0x7d, 0x00, 0x81, 0xed, 0x62, 0xb4, 0xa6, 0xff, 0x00, 0x0c, 0x67, 0xfc, + 0xf8, 0x01, 0x62, 0x00, 0x0c, 0x21, 0xa0, 0xcf, 0x67, 0xf8, 0xf8, 0x01, + 0x47, 0x14, 0x74, 0x00, 0x87, 0xfc, 0xe8, 0x01, 0x2e, 0x6d, 0x22, 0x25, + 0x82, 0x00, 0x8c, 0x48, 0x73, 0xcf, 0x87, 0xf8, 0xe8, 0x01, 0x47, 0x14, + 0x74, 0x00, 0x87, 0xfc, 0xe8, 0x01, 0x42, 0x30, 0x34, 0x00, 0x22, 0x25, + 0x82, 0x00, 0x8c, 0x48, 0x67, 0xcf, 0x87, 0xf8, 0xe8, 0x01, 0xc2, 0x8d, + 0x01, 0xed, 0x67, 0x14, 0x7d, 0x00, 0x43, 0x94, 0xbd, 0xff, 0x00, 0x0c, + 0xa0, 0x00, 0x0c, 0x21, 0xb9, 0xcf, 0xa7, 0xf8, 0xf8, 0x01, 0x47, 0x14, + 0x74, 0x00, 0x87, 0xfc, 0xe8, 0x01, 0x42, 0x30, 0x24, 0x00, 0x22, 0x25, + 0x82, 0x00, 0x8c, 0x48, 0x4f, 0xcf, 0x87, 0xf8, 0xe8, 0x01, 0xbe, 0x05, + 0x43, 0x14, 0x70, 0x00, 0x67, 0x34, 0xd0, 0x01, 0x27, 0x25, 0x62, 0x00, + 0x8c, 0x7b, 0x5f, 0xcf, 0x67, 0x38, 0xd0, 0x01, 0x47, 0x14, 0x74, 0x00, + 0x87, 0xfc, 0xe8, 0x01, 0x42, 0x30, 0x3c, 0x00, 0x22, 0x25, 0x82, 0x00, + 0x8c, 0x48, 0x38, 0xcf, 0x87, 0xf8, 0xe8, 0x01, 0x87, 0xcf, 0x47, 0x18, + 0x15, 0x01, 0x00, 0x0c, 0xb9, 0x41, 0x02, 0x80, 0x60, 0x30, 0xb0, 0x03, + 0xa2, 0x41, 0x04, 0x80, 0x39, 0x33, 0xd5, 0x09, 0x99, 0x45, 0x62, 0xf8, + 0x9c, 0x0e, 0x00, 0x0c, 0xe9, 0x4f, 0xa5, 0x41, 0x00, 0x00, 0xbd, 0x22, + 0x18, 0xd0, 0xb2, 0x41, 0x02, 0x80, 0xb1, 0x41, 0x04, 0x80, 0x31, 0x32, + 0x20, 0x0f, 0xa5, 0x30, 0x00, 0x00, 0x01, 0xee, 0x52, 0x32, 0x4d, 0x1b, + 0xb0, 0x41, 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, 0x04, 0xc8, 0xd2, 0x45, + 0x1d, 0xf8, 0x14, 0x00, 0x51, 0xfc, 0x68, 0x00, 0x70, 0xfc, 0x24, 0x06, + 0x20, 0x6d, 0x87, 0xad, 0x51, 0xf8, 0x68, 0x00, 0x50, 0xfc, 0x20, 0x06, + 0x05, 0x8d, 0xb3, 0x41, 0x04, 0x80, 0xbd, 0x22, 0x18, 0x50, 0x0c, 0x47, + 0x73, 0x32, 0x2c, 0x36, 0x53, 0xfc, 0x2c, 0x00, 0xe2, 0x40, 0xf7, 0xff, + 0xe2, 0x45, 0x0b, 0x6e, 0x80, 0x32, 0x01, 0x00, 0x82, 0x96, 0xf1, 0xff, + 0x00, 0x0c, 0x53, 0xfc, 0x30, 0x00, 0xe2, 0x40, 0x05, 0x00, 0xe2, 0x45, + 0x09, 0x6e, 0x82, 0x96, 0xe8, 0xff, 0x00, 0x0c, 0x45, 0x48, 0x70, 0xfe, + 0x34, 0x00, 0x82, 0x0c, 0x53, 0x00, 0xd0, 0x99, 0x53, 0x00, 0x80, 0xf8, + 0x62, 0x02, 0x10, 0x9b, 0x53, 0x00, 0xd0, 0x99, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0xcd, 0x8f, 0xe2, 0x45, 0x00, 0x0c, 0x07, 0x69, 0x62, 0x02, + 0x50, 0x9b, 0x13, 0xb4, 0x3f, 0x00, 0x45, 0x48, 0x86, 0x69, 0x0c, 0x69, + 0x62, 0x94, 0x4c, 0x00, 0x05, 0x6a, 0x82, 0x94, 0x3b, 0x00, 0x00, 0x0c, + 0x84, 0x6a, 0xa2, 0x94, 0x54, 0x00, 0x44, 0x48, 0xf3, 0x40, 0xc1, 0xff, + 0x51, 0xfc, 0x6c, 0x00, 0x20, 0x6d, 0x51, 0xf8, 0x6c, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x49, 0x1a, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xcf, 0x12, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0xb4, + 0x54, 0x00, 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x30, + 0x30, 0x00, 0xf2, 0x45, 0x01, 0xee, 0xa2, 0x41, 0x08, 0x80, 0xb3, 0x0c, + 0x42, 0x30, 0x83, 0x19, 0xe2, 0x45, 0x01, 0xee, 0xa5, 0x41, 0x00, 0x00, + 0xa5, 0x30, 0x40, 0x00, 0xf2, 0x45, 0x01, 0xee, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xab, 0x18, 0xe2, 0x45, 0x00, 0x0c, 0x92, 0xcf, 0x00, 0x0c, + 0x70, 0xfe, 0x04, 0x00, 0xbf, 0xcf, 0x0d, 0xe9, 0x04, 0x6a, 0x44, 0x48, + 0x44, 0x00, 0x50, 0x2b, 0x93, 0x8e, 0x62, 0x00, 0x50, 0x13, 0xa2, 0x40, + 0xc1, 0xff, 0x02, 0x69, 0x8c, 0xe9, 0xbe, 0xcf, 0x53, 0x00, 0x90, 0x9a, + 0x44, 0x48, 0x44, 0x00, 0x50, 0x1b, 0xa3, 0x40, 0x16, 0x00, 0x84, 0x69, + 0x43, 0x00, 0x50, 0x13, 0xe2, 0x40, 0xf1, 0xff, 0x02, 0x69, 0x0c, 0xea, + 0xaf, 0xcf, 0x53, 0x00, 0x90, 0x9a, 0x62, 0x00, 0x50, 0x2b, 0xe9, 0x8e, + 0x82, 0x00, 0x50, 0x13, 0xa2, 0x40, 0xa6, 0xff, 0x02, 0x69, 0x0c, 0xea, + 0xa3, 0xcf, 0x53, 0x00, 0x90, 0x9a, 0x84, 0x69, 0x43, 0x00, 0x50, 0x13, + 0xa2, 0x40, 0x9c, 0xff, 0x02, 0x69, 0x8c, 0xe9, 0x99, 0xcf, 0x53, 0x00, + 0x90, 0x9a, 0xb1, 0x41, 0x08, 0x80, 0xa5, 0x30, 0x10, 0x00, 0x01, 0xee, + 0x31, 0x32, 0x9f, 0x18, 0xd2, 0x45, 0xb0, 0x41, 0x08, 0x80, 0xd1, 0x45, + 0x10, 0x32, 0xe7, 0x18, 0xf0, 0x45, 0x01, 0xee, 0xa5, 0x41, 0x00, 0x00, + 0x01, 0xee, 0xd2, 0x45, 0xa5, 0x30, 0x30, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x83, 0x19, 0xb3, 0x0c, 0xe2, 0x45, 0x01, 0xee, 0xa5, 0x41, + 0x00, 0x00, 0xa5, 0x30, 0x40, 0x00, 0xf2, 0x45, 0x01, 0xee, 0xa5, 0x41, + 0x00, 0x00, 0x01, 0xee, 0xd2, 0x45, 0xa5, 0x30, 0x58, 0x00, 0xf1, 0x45, + 0x00, 0x0c, 0xf0, 0x45, 0x80, 0x0c, 0x96, 0xcf, 0xa2, 0x41, 0x08, 0x80, + 0xde, 0x6e, 0xd8, 0x06, 0x44, 0x30, 0x24, 0x00, 0xa2, 0x00, 0x90, 0x1b, + 0x93, 0x8d, 0x83, 0xed, 0x84, 0x14, 0x24, 0x00, 0x64, 0x94, 0x0f, 0x00, + 0x03, 0xee, 0x06, 0xcc, 0xa1, 0x09, 0xa0, 0x09, 0x83, 0x94, 0x0a, 0x00, + 0x81, 0xed, 0xa1, 0x09, 0x64, 0x4c, 0x34, 0x05, 0xa2, 0x00, 0x90, 0x1b, + 0xa3, 0x40, 0xf5, 0xff, 0xbf, 0x45, 0x81, 0xed, 0xe0, 0x89, 0x22, 0x09, + 0x9f, 0x45, 0x70, 0x89, 0xed, 0x4f, 0x08, 0xed, 0x75, 0x45, 0x05, 0x0e, + 0x44, 0x0e, 0x45, 0x94, 0x27, 0x00, 0x66, 0x0e, 0x05, 0xed, 0x45, 0xb4, + 0x10, 0x00, 0x44, 0xb0, 0x01, 0x04, 0x0f, 0xad, 0xb1, 0x41, 0x08, 0x80, + 0x44, 0x02, 0x40, 0x50, 0x52, 0x00, 0x00, 0x28, 0x42, 0x02, 0xd0, 0x11, + 0x24, 0x25, 0x42, 0x02, 0x50, 0x91, 0x52, 0x02, 0x00, 0x18, 0xb1, 0x41, + 0x08, 0x80, 0xc0, 0x86, 0x31, 0x32, 0x23, 0x19, 0xf1, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x08, 0x80, 0xca, 0x86, 0x42, 0x30, 0x29, 0x19, 0xe2, 0x45, + 0x00, 0x0c, 0xcc, 0x86, 0x31, 0x0f, 0x35, 0x45, 0x99, 0x45, 0x15, 0x4c, + 0xa2, 0x41, 0x07, 0x00, 0x42, 0x50, 0x20, 0xa1, 0xb1, 0x41, 0x08, 0x80, + 0x54, 0x44, 0x60, 0x50, 0x50, 0xc3, 0xc0, 0x86, 0x31, 0x32, 0x23, 0x19, + 0xd1, 0x45, 0x43, 0x00, 0x58, 0x90, 0xa2, 0x41, 0x08, 0x80, 0xca, 0x86, + 0x42, 0x30, 0x29, 0x19, 0xe2, 0x45, 0x00, 0x0c, 0xcc, 0x86, 0x31, 0x0f, + 0x35, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x00, 0x0c, 0x09, 0x8e, 0xb9, 0x41, + 0x02, 0x80, 0x44, 0x14, 0x6a, 0x00, 0x22, 0x25, 0x44, 0x60, 0x46, 0x80, + 0x44, 0x60, 0x43, 0x90, 0x39, 0x33, 0x35, 0x88, 0xb9, 0x45, 0x00, 0x0c, + 0xe9, 0x4f, 0x44, 0xfc, 0x50, 0x00, 0x77, 0x45, 0x60, 0x0c, 0x42, 0x16, + 0x16, 0x00, 0x40, 0x0c, 0x5d, 0x20, 0x10, 0x90, 0xa2, 0x41, 0x02, 0x80, + 0x42, 0x30, 0x95, 0xc3, 0xe2, 0x45, 0x04, 0x0e, 0x09, 0xad, 0x22, 0x0e, + 0x0a, 0x69, 0x83, 0xed, 0x62, 0x94, 0x07, 0x00, 0x86, 0xed, 0x62, 0x94, + 0x04, 0x00, 0x00, 0x0c, 0x51, 0x0c, 0x37, 0x45, 0x0c, 0x47, 0x50, 0x14, + 0x4e, 0x00, 0xb0, 0xfc, 0x50, 0x00, 0xb3, 0x41, 0x01, 0x80, 0x50, 0x4c, + 0x02, 0xef, 0x09, 0x6e, 0x73, 0x32, 0x61, 0xda, 0xf3, 0x45, 0xaa, 0x06, + 0x50, 0x14, 0x4e, 0x00, 0xb0, 0xfc, 0x50, 0x00, 0x52, 0xd2, 0x0f, 0x00, + 0x58, 0x4c, 0x04, 0xef, 0x9d, 0x30, 0x12, 0x00, 0xf3, 0x45, 0xaa, 0x06, + 0x12, 0x94, 0x11, 0x00, 0xa3, 0x41, 0x05, 0x80, 0x43, 0xfc, 0xf8, 0x94, + 0xc3, 0xfc, 0xfc, 0x94, 0xa4, 0x48, 0x20, 0x6e, 0x44, 0x00, 0x90, 0x13, + 0x85, 0x94, 0x10, 0x00, 0x64, 0x05, 0x81, 0xec, 0x51, 0x0c, 0x37, 0x45, + 0x0c, 0x47, 0x9d, 0x20, 0x10, 0x10, 0xa2, 0x41, 0x05, 0x80, 0x82, 0xf8, + 0xf8, 0x94, 0xa2, 0xf8, 0xfc, 0x94, 0x51, 0x0c, 0x37, 0x45, 0x0c, 0x47, + 0x85, 0x48, 0x44, 0xb4, 0xee, 0xff, 0x00, 0x0c, 0xa3, 0xf8, 0xf8, 0x94, + 0xbf, 0xcf, 0x83, 0xf8, 0xfc, 0x94, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0xfc, 0x34, 0x0e, 0xe2, 0x40, 0x06, 0x00, 0x42, 0x14, 0x76, 0x00, + 0x42, 0xb0, 0x10, 0x00, 0xe2, 0x40, 0x16, 0x00, 0xf5, 0x4f, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xcf, 0x12, 0x44, 0x45, 0xe2, 0x45, 0x04, 0x0e, + 0x05, 0x8d, 0xb9, 0x41, 0x02, 0x80, 0x01, 0xed, 0x04, 0x45, 0x06, 0x47, + 0x90, 0x0c, 0xc0, 0x0c, 0x83, 0xee, 0x39, 0x33, 0xa9, 0x95, 0x04, 0x45, + 0x99, 0x45, 0x0d, 0x4c, 0x9f, 0x45, 0x01, 0xed, 0xa2, 0x41, 0x04, 0x80, + 0xc2, 0xfc, 0xe0, 0x0d, 0x67, 0x6b, 0x05, 0xaf, 0xb9, 0x41, 0x02, 0x80, + 0x39, 0x33, 0x69, 0xf7, 0xb9, 0x45, 0xf1, 0x4f, 0x64, 0x45, 0xb2, 0x41, + 0x02, 0x80, 0x04, 0x0e, 0x25, 0x0e, 0xc0, 0x0c, 0x52, 0x32, 0xa9, 0x95, + 0x83, 0xee, 0xf2, 0x45, 0x01, 0xee, 0xa2, 0x41, 0x02, 0x80, 0x98, 0x86, + 0x42, 0x30, 0x69, 0xf7, 0xe2, 0x45, 0x00, 0x0c, 0x32, 0x0f, 0xc0, 0x0c, + 0x83, 0xee, 0x80, 0x0c, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, + 0xe9, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0xdd, 0x22, 0x14, 0xd0, 0xb0, 0x41, + 0x04, 0x80, 0x42, 0x32, 0x23, 0x19, 0xa2, 0x41, 0x08, 0x80, 0x10, 0x32, + 0x28, 0x03, 0x81, 0xec, 0x80, 0x32, 0x01, 0x00, 0x62, 0x32, 0x29, 0x19, + 0x00, 0x69, 0x82, 0x96, 0x0a, 0x00, 0x00, 0x0c, 0x90, 0x6c, 0x03, 0xed, + 0x51, 0xb4, 0xf8, 0xff, 0x10, 0x32, 0x38, 0x02, 0xdd, 0x22, 0x14, 0x50, + 0x0c, 0x47, 0x50, 0xfc, 0x48, 0x00, 0x90, 0x86, 0x73, 0xad, 0xa0, 0x52, + 0x51, 0xc3, 0x50, 0xfc, 0xf8, 0x00, 0x60, 0x50, 0x50, 0xc3, 0x42, 0x00, + 0x00, 0x50, 0xa2, 0x02, 0x90, 0xab, 0x42, 0x30, 0xe0, 0xb1, 0xa2, 0x02, + 0x58, 0x18, 0xf2, 0x45, 0xa3, 0x0e, 0xb1, 0x0c, 0xf3, 0x45, 0x95, 0x0c, + 0xb1, 0x0c, 0xf2, 0x45, 0x05, 0xee, 0xdd, 0xcf, 0x90, 0x6c, 0x00, 0x0c, + 0xf5, 0x4f, 0x44, 0x45, 0x44, 0x60, 0x17, 0x00, 0x44, 0x60, 0x14, 0x10, + 0x42, 0xd0, 0x00, 0x40, 0x14, 0x8d, 0x04, 0x0e, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0xe8, 0x02, 0x02, 0xf8, 0x50, 0x02, 0x02, 0xf8, 0x88, 0x04, + 0x70, 0x14, 0x55, 0x00, 0xa4, 0x41, 0x04, 0x80, 0x86, 0x8d, 0x04, 0xf8, + 0x9c, 0x1a, 0x62, 0x14, 0xc0, 0x0b, 0xa3, 0x40, 0x08, 0x00, 0xb9, 0x41, + 0x01, 0x80, 0x90, 0x0c, 0x39, 0x33, 0x11, 0x23, 0x04, 0x45, 0x99, 0x45, + 0x0d, 0x4c, 0x02, 0x18, 0xc0, 0x0b, 0x02, 0x18, 0xc1, 0x0b, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xd5, 0x18, 0xe2, 0x45, 0x01, 0xee, 0xb9, 0x41, + 0x01, 0x80, 0x90, 0x0c, 0x39, 0x33, 0x11, 0x23, 0x04, 0x45, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0xa2, 0x41, 0x04, 0x80, 0x64, 0x45, + 0x42, 0x30, 0x29, 0x51, 0xb2, 0x41, 0x08, 0x80, 0xb1, 0x41, 0x03, 0x80, + 0xc2, 0x45, 0xb0, 0x41, 0x08, 0x80, 0x52, 0x32, 0x3f, 0x15, 0x31, 0x32, + 0x6d, 0xc2, 0x10, 0x32, 0x7c, 0x49, 0x90, 0x0c, 0xf1, 0x45, 0xff, 0xee, + 0x7c, 0x8d, 0x82, 0x0c, 0xf2, 0x45, 0x00, 0x0c, 0xf9, 0xcf, 0x90, 0x0c, + 0xf1, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x01, 0x99, 0x46, 0x45, + 0x1d, 0x38, 0x10, 0x00, 0xe2, 0x45, 0x04, 0x0e, 0xa2, 0x41, 0x01, 0x80, + 0x02, 0xef, 0xb0, 0x30, 0x7e, 0x00, 0x42, 0x30, 0x61, 0xda, 0xe2, 0x45, + 0x09, 0x6e, 0x5d, 0x34, 0x10, 0x00, 0x60, 0x30, 0xa4, 0x00, 0x42, 0xd0, + 0xfc, 0x00, 0x62, 0xb4, 0x0f, 0x00, 0xa2, 0x41, 0x04, 0x80, 0x70, 0xfc, + 0xac, 0x01, 0x42, 0xfc, 0x24, 0x04, 0x83, 0xfc, 0x34, 0x01, 0xa0, 0x30, + 0x00, 0xc0, 0xd5, 0x44, 0x82, 0x00, 0x0c, 0xba, 0x83, 0xf8, 0x34, 0x01, + 0x06, 0x45, 0x08, 0x47, 0xf5, 0x4f, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, + 0x91, 0x36, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, + 0x42, 0x30, 0xe8, 0x02, 0x62, 0xfc, 0x68, 0x0b, 0xe5, 0x4b, 0x62, 0xf8, + 0x1c, 0x06, 0x06, 0x47, 0xa3, 0x41, 0x04, 0x80, 0x63, 0x30, 0xe8, 0x02, + 0xa3, 0xfc, 0xf8, 0x0a, 0x44, 0x34, 0x50, 0x01, 0x53, 0x6a, 0xa2, 0x30, + 0xe0, 0xff, 0xc2, 0xb0, 0x21, 0x00, 0xdf, 0x2e, 0xc5, 0x00, 0x58, 0x10, + 0x84, 0xb0, 0x0f, 0x00, 0x09, 0xae, 0x26, 0x25, 0xa4, 0x41, 0xaa, 0xaa, + 0x84, 0x50, 0xab, 0xaa, 0x82, 0x00, 0x3c, 0x9b, 0x02, 0x46, 0x25, 0x25, + 0x83, 0xfc, 0x1c, 0x06, 0x84, 0x30, 0xc8, 0x00, 0x28, 0x05, 0x43, 0xf8, + 0x68, 0x0b, 0x9f, 0x45, 0x43, 0xf8, 0xf4, 0x0b, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0xfc, 0x00, 0x95, 0x44, 0x00, 0x10, 0x12, 0xa4, 0x41, 0x1b, 0x43, + 0x84, 0x50, 0x83, 0xde, 0x82, 0x00, 0x3c, 0x9b, 0x02, 0x46, 0x9f, 0x45, + 0x42, 0x00, 0x40, 0x90, 0xc9, 0x4f, 0x3d, 0x23, 0x48, 0xd0, 0xb1, 0x41, + 0x04, 0x80, 0x31, 0x32, 0xe8, 0x02, 0x71, 0xfc, 0xf8, 0x0a, 0x44, 0x34, + 0x50, 0x01, 0x44, 0x0e, 0xb3, 0x69, 0x82, 0x30, 0xe0, 0xff, 0xa2, 0xb0, + 0x21, 0x00, 0x4f, 0x2e, 0xa4, 0x00, 0x58, 0x10, 0x63, 0xb0, 0x0f, 0x00, + 0x26, 0x25, 0x06, 0xc8, 0x07, 0xc8, 0x08, 0xc8, 0x09, 0xc8, 0x0a, 0xc8, + 0x1d, 0x18, 0x34, 0x00, 0x8a, 0xad, 0x1d, 0x18, 0x35, 0x00, 0xa3, 0x41, + 0xaa, 0xaa, 0x63, 0x50, 0xab, 0xaa, 0x62, 0x00, 0x3c, 0x9b, 0x02, 0x46, + 0x25, 0x25, 0x71, 0xfc, 0x1c, 0x06, 0xb2, 0xfc, 0x50, 0x00, 0xb0, 0x41, + 0x01, 0x80, 0x63, 0x30, 0xc8, 0x00, 0x26, 0x05, 0x17, 0x6e, 0x04, 0xef, + 0x10, 0x32, 0x61, 0xda, 0xdc, 0x6e, 0x51, 0xf8, 0x68, 0x0b, 0xd0, 0x45, + 0x51, 0xf8, 0xf4, 0x0b, 0xb2, 0xfc, 0x50, 0x00, 0x04, 0xef, 0x19, 0x6e, + 0xd0, 0x45, 0xa5, 0x30, 0x1c, 0x00, 0x4b, 0x48, 0x62, 0x30, 0x28, 0x00, + 0x42, 0xb0, 0xd8, 0xff, 0x02, 0x94, 0xea, 0x00, 0x6b, 0xc8, 0x97, 0x6e, + 0x0d, 0x6e, 0xf0, 0x45, 0x03, 0xef, 0x0f, 0x6e, 0x03, 0xef, 0xd0, 0x45, + 0xbd, 0x30, 0x2f, 0x00, 0x11, 0x6e, 0x02, 0xef, 0xd0, 0x45, 0xbd, 0x30, + 0x32, 0x00, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0xf1, 0x23, 0x11, 0x6f, + 0x8f, 0x6e, 0xe2, 0x45, 0x0d, 0x6e, 0x4c, 0x48, 0xb0, 0x41, 0x04, 0x80, + 0xb3, 0x41, 0x04, 0x80, 0x49, 0xc8, 0x4b, 0x48, 0x10, 0x32, 0x24, 0x03, + 0x73, 0x32, 0x94, 0x07, 0x4a, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xc2, 0x32, + 0x65, 0x13, 0xa2, 0x41, 0x02, 0x80, 0xa2, 0x32, 0xd5, 0xc2, 0xa2, 0x41, + 0x08, 0x80, 0x40, 0x0d, 0x20, 0x0d, 0xbe, 0x41, 0x08, 0x80, 0xb7, 0x41, + 0x05, 0x80, 0x82, 0x32, 0x29, 0x19, 0x01, 0x69, 0x81, 0xed, 0x62, 0x94, + 0x1b, 0x00, 0x00, 0x0c, 0x10, 0x32, 0x38, 0x02, 0x13, 0xb6, 0xf7, 0xff, + 0x00, 0x0c, 0x51, 0xfc, 0x40, 0x02, 0x02, 0xb4, 0x92, 0x00, 0x81, 0xed, + 0x51, 0xfc, 0x44, 0x02, 0x71, 0xfc, 0x78, 0x04, 0x03, 0xb4, 0x94, 0x00, + 0x40, 0x00, 0x90, 0x13, 0x91, 0xfc, 0x7c, 0x04, 0x81, 0xed, 0x83, 0x00, + 0x18, 0x10, 0x3d, 0x23, 0x48, 0x50, 0x1c, 0x47, 0x70, 0xfc, 0x48, 0x00, + 0x43, 0xb4, 0xe2, 0xff, 0xb0, 0x30, 0x39, 0x00, 0x92, 0xfc, 0x50, 0x00, + 0x3d, 0x21, 0x38, 0x90, 0xf6, 0x45, 0x48, 0x6e, 0x3d, 0x21, 0x38, 0x10, + 0x02, 0xb4, 0x94, 0x00, 0xb0, 0x30, 0x40, 0x00, 0x51, 0xfc, 0x60, 0x0b, + 0x83, 0xed, 0x62, 0x94, 0x83, 0x00, 0x81, 0xed, 0x62, 0xb4, 0x09, 0x00, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, 0xfc, 0x01, + 0xb0, 0x6d, 0x62, 0xf8, 0xfc, 0x01, 0x51, 0x14, 0xc0, 0x0b, 0x81, 0xed, + 0x02, 0x94, 0x89, 0x00, 0x71, 0xf8, 0x64, 0x0b, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x23, 0x19, 0x4e, 0xc8, 0x50, 0xfc, 0xfc, 0x00, 0x09, 0xad, + 0xa2, 0x00, 0x00, 0x50, 0x64, 0xed, 0x50, 0xf8, 0xfc, 0x00, 0xa2, 0x41, + 0x01, 0x00, 0xa2, 0x50, 0x00, 0x90, 0x3d, 0x21, 0x3c, 0x90, 0xf5, 0x45, + 0x13, 0x6e, 0x62, 0x0d, 0x50, 0xfc, 0x4c, 0x00, 0x3d, 0x21, 0x3c, 0x10, + 0x02, 0x94, 0x7b, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x50, 0xfc, 0xfc, 0x00, + 0x42, 0x00, 0x00, 0x50, 0x62, 0x01, 0xd0, 0x11, 0x80, 0x6a, 0x91, 0xfc, + 0x58, 0x0b, 0xde, 0x30, 0x00, 0x47, 0xd4, 0x25, 0xe6, 0x05, 0x02, 0xef, + 0xc4, 0x94, 0xc1, 0x00, 0x30, 0xe9, 0x81, 0xed, 0x64, 0x94, 0xc5, 0x00, + 0x00, 0x0c, 0x77, 0xfc, 0x00, 0x95, 0xa6, 0x41, 0x1b, 0x43, 0xc6, 0x50, + 0x83, 0xde, 0x62, 0x00, 0x10, 0x1a, 0xd0, 0x6e, 0x3d, 0x21, 0x40, 0x90, + 0xc3, 0x00, 0x3c, 0x9b, 0x03, 0x46, 0x63, 0x00, 0x40, 0x90, 0x35, 0x05, + 0x4f, 0xc8, 0x4e, 0x48, 0xe2, 0x45, 0x80, 0x0c, 0x4f, 0x48, 0x80, 0x6a, + 0x82, 0x0c, 0xf4, 0x45, 0xd0, 0x6e, 0x80, 0x6a, 0x4e, 0x48, 0x05, 0xee, + 0xe2, 0x45, 0xd0, 0x6e, 0x3d, 0x21, 0x40, 0x10, 0x69, 0xcf, 0x10, 0x32, + 0x38, 0x02, 0x62, 0x94, 0x0d, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x71, 0xfc, + 0x78, 0x04, 0x03, 0x94, 0x6f, 0xff, 0x01, 0xed, 0x01, 0xed, 0x43, 0xb4, + 0x70, 0xff, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x47, 0x16, + 0xe2, 0x45, 0x00, 0x0c, 0x68, 0xcf, 0x01, 0xed, 0x4c, 0x48, 0x20, 0x6d, + 0x14, 0xcf, 0x4c, 0xc8, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, + 0x62, 0xfc, 0xf8, 0x01, 0xb0, 0x6d, 0x81, 0xcf, 0x62, 0xf8, 0xf8, 0x01, + 0x92, 0xfc, 0x50, 0x00, 0x3d, 0x21, 0x38, 0x90, 0xf6, 0x45, 0x48, 0x6e, + 0x3d, 0x21, 0x38, 0x10, 0xe2, 0x40, 0x64, 0xff, 0x39, 0xcf, 0x10, 0x32, + 0x38, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x23, 0x19, 0x88, 0xee, + 0x4e, 0xc8, 0x3d, 0x21, 0x3c, 0x90, 0xe2, 0x45, 0x80, 0x0c, 0x02, 0xed, + 0x3d, 0x21, 0x3c, 0x10, 0x70, 0xcf, 0x51, 0xf8, 0x60, 0x0b, 0xb2, 0x34, + 0x50, 0x01, 0x92, 0xfc, 0x50, 0x00, 0x9b, 0x6f, 0x42, 0x30, 0x41, 0x16, + 0x04, 0xca, 0x6f, 0xc9, 0x3d, 0x21, 0x40, 0x90, 0xc2, 0x45, 0xdd, 0x30, + 0x35, 0x00, 0x92, 0x34, 0x50, 0x01, 0x72, 0xfc, 0x50, 0x00, 0x4e, 0x6e, + 0x46, 0x06, 0x43, 0x30, 0x24, 0x00, 0x82, 0x00, 0x90, 0x2b, 0x3d, 0x21, + 0x40, 0x10, 0x94, 0x8e, 0x6f, 0x49, 0xa3, 0x14, 0x24, 0x00, 0x83, 0xed, + 0x65, 0x94, 0x51, 0x00, 0x83, 0xee, 0x06, 0xcc, 0xa1, 0x09, 0xa0, 0x09, + 0xa3, 0x94, 0x4b, 0x00, 0x00, 0x0c, 0xa1, 0x09, 0x64, 0x4c, 0x34, 0x05, + 0x82, 0x00, 0x90, 0x1b, 0xa3, 0x40, 0xf5, 0xff, 0xa9, 0x40, 0x43, 0x00, + 0x10, 0xf8, 0xec, 0x01, 0x5d, 0x14, 0x34, 0x00, 0x05, 0xad, 0x62, 0x0c, + 0x01, 0xed, 0x81, 0xed, 0x5d, 0x18, 0x34, 0x00, 0x51, 0xfc, 0x9c, 0x0b, + 0x0e, 0x8d, 0x9d, 0x14, 0x35, 0x00, 0x51, 0xfc, 0x08, 0x06, 0x62, 0x00, + 0x3c, 0xbb, 0x03, 0x00, 0x3c, 0x70, 0x42, 0x46, 0xe2, 0x40, 0x03, 0x00, + 0x2e, 0x6d, 0x62, 0x00, 0x10, 0x12, 0xe4, 0x40, 0x1a, 0x00, 0x70, 0xfc, + 0xfc, 0x00, 0x28, 0x05, 0x62, 0x00, 0x10, 0x12, 0x42, 0x00, 0x00, 0x50, + 0x37, 0xcf, 0x62, 0x01, 0xd0, 0x11, 0x71, 0xfc, 0x68, 0x0b, 0x43, 0x00, + 0x90, 0x23, 0xb5, 0x05, 0x3e, 0xcf, 0x83, 0x00, 0x18, 0x10, 0x71, 0xfc, + 0x6c, 0x0b, 0x43, 0x00, 0x90, 0x23, 0xb5, 0x05, 0x36, 0xcf, 0x83, 0x00, + 0x18, 0x10, 0x90, 0xfc, 0xfc, 0x00, 0x34, 0x05, 0x82, 0x00, 0x10, 0x12, + 0x42, 0x00, 0x00, 0x50, 0x1d, 0xcf, 0x62, 0x01, 0xd0, 0x11, 0x42, 0x15, + 0x02, 0x00, 0x51, 0xfc, 0xf8, 0x0a, 0x24, 0x69, 0x4a, 0xb4, 0xba, 0xff, + 0x20, 0x31, 0x01, 0x00, 0xb7, 0xcf, 0x10, 0xf8, 0xec, 0x01, 0x00, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0xf1, 0x19, 0xe5, 0xcb, + 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, 0xe5, 0x4b, 0x42, 0x30, + 0xb4, 0x1a, 0x81, 0xed, 0x62, 0x60, 0x17, 0x80, 0x62, 0x60, 0x14, 0x90, + 0x06, 0x47, 0x00, 0x0c, 0xa3, 0x41, 0x00, 0xa4, 0x43, 0xfc, 0x24, 0x2c, + 0x63, 0xfc, 0x28, 0x2c, 0x42, 0x00, 0x2c, 0x98, 0x63, 0x00, 0x2c, 0x98, + 0x83, 0x00, 0x00, 0xa0, 0xd4, 0x44, 0x9f, 0x45, 0x63, 0x00, 0x40, 0x60, + 0xf5, 0x4f, 0xa3, 0x41, 0x00, 0xa4, 0x43, 0xfc, 0x24, 0x2c, 0xa3, 0xfc, + 0x28, 0x2c, 0xe5, 0xcb, 0x42, 0x00, 0x2c, 0x98, 0xa5, 0x00, 0x2c, 0x98, + 0x85, 0x00, 0x00, 0xa0, 0xe2, 0x44, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x79, 0x4d, 0xc2, 0x45, 0xa5, 0x00, 0x40, 0x60, 0xa4, 0x41, 0x05, 0x80, + 0xc4, 0xfc, 0x30, 0x95, 0xe4, 0xfc, 0x34, 0x95, 0xb4, 0x86, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x69, 0x48, 0xe2, 0x45, 0x00, 0x0c, 0xb4, 0x86, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x01, 0x4d, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0xa4, 0x41, 0x04, 0x80, 0x34, 0x85, 0x84, 0x30, 0xe8, 0x02, + 0xc4, 0xf8, 0x20, 0x0c, 0xe4, 0xf8, 0x24, 0x0c, 0x06, 0x47, 0x00, 0x0c, + 0xf5, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xa3, 0x14, 0x44, 0x45, + 0xe2, 0x45, 0x00, 0x0c, 0xa5, 0x41, 0x05, 0x80, 0x05, 0x32, 0x00, 0x95, + 0x50, 0xfd, 0x2c, 0x00, 0x0a, 0x6b, 0x6a, 0x00, 0x90, 0x23, 0x2d, 0x8e, + 0x01, 0xe8, 0xa4, 0x41, 0x04, 0x80, 0x84, 0x30, 0xe8, 0x02, 0xe4, 0xfc, + 0xe8, 0x0b, 0x65, 0xfd, 0x00, 0x95, 0xa4, 0xfc, 0xec, 0x0b, 0x6f, 0x07, + 0x2c, 0x05, 0x62, 0x01, 0x3c, 0x9b, 0xc7, 0x00, 0x90, 0x3b, 0x45, 0x01, + 0xd0, 0x29, 0xfb, 0x06, 0xba, 0x05, 0xc2, 0x00, 0x90, 0x13, 0x34, 0x05, + 0xa6, 0x41, 0x0f, 0x00, 0xc6, 0x50, 0x40, 0x42, 0xe0, 0x0c, 0x48, 0x46, + 0x88, 0x0c, 0x09, 0x46, 0x62, 0x01, 0x10, 0x1a, 0xa2, 0x41, 0x01, 0x80, + 0x42, 0x30, 0xdd, 0xd5, 0x23, 0x01, 0x50, 0x49, 0xe2, 0x45, 0xa9, 0x0c, + 0x01, 0xe9, 0x04, 0x45, 0x06, 0x47, 0x43, 0xb5, 0x05, 0x00, 0x46, 0x00, + 0x90, 0x23, 0x51, 0xae, 0xa4, 0x41, 0x04, 0x80, 0x40, 0x0c, 0x04, 0x45, + 0x06, 0x47, 0x00, 0x0c, 0xf1, 0x4f, 0x01, 0xed, 0x46, 0x45, 0x44, 0x94, + 0x14, 0x00, 0x82, 0xed, 0x64, 0x94, 0x03, 0x00, 0x40, 0x0c, 0x06, 0x45, + 0x08, 0x47, 0xa3, 0x41, 0x08, 0x80, 0x07, 0xef, 0x88, 0xee, 0x80, 0x30, + 0xd0, 0x07, 0x63, 0x30, 0x1d, 0x19, 0xc3, 0x45, 0x5d, 0xf8, 0x10, 0x00, + 0x44, 0x48, 0x06, 0x45, 0x08, 0x47, 0xb0, 0x41, 0x04, 0x80, 0x10, 0x32, + 0x20, 0x0f, 0x50, 0xfc, 0xb0, 0x02, 0x84, 0xc8, 0x20, 0x6d, 0x50, 0xf8, + 0xb0, 0x02, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x41, 0x60, 0xe2, 0x45, + 0x00, 0x0c, 0xa3, 0x41, 0x04, 0x80, 0x63, 0x30, 0xe8, 0x02, 0xc3, 0xfc, + 0xec, 0x0b, 0xa3, 0xfc, 0xe8, 0x0b, 0x15, 0xaf, 0x84, 0x48, 0xa2, 0x00, + 0x90, 0x3b, 0xa7, 0x40, 0x10, 0x00, 0x43, 0xfc, 0xf0, 0x0b, 0xe3, 0xfc, + 0xf4, 0x0b, 0x15, 0xaf, 0x2e, 0x05, 0x45, 0x00, 0x90, 0x13, 0x11, 0x8d, + 0x44, 0x0c, 0x70, 0xfc, 0xdc, 0x02, 0xb0, 0x6d, 0xc4, 0xcf, 0x70, 0xf8, + 0xdc, 0x02, 0x2b, 0x05, 0x45, 0x00, 0x90, 0x2b, 0x5d, 0x07, 0x43, 0xf8, + 0xe8, 0x0b, 0xa2, 0x0c, 0xe8, 0xcf, 0xc3, 0xf8, 0xec, 0x0b, 0xfb, 0x07, + 0xe5, 0x00, 0x90, 0x2b, 0x5d, 0x07, 0xb9, 0x41, 0x08, 0x80, 0x87, 0x0c, + 0xa6, 0x0c, 0x39, 0x33, 0xe1, 0x12, 0x06, 0x45, 0xe3, 0xf8, 0xe8, 0x0b, + 0xc3, 0xf8, 0xec, 0x0b, 0x99, 0x45, 0x11, 0x4c, 0xf1, 0x4f, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x49, 0x1a, 0x55, 0x45, 0xc2, 0x45, 0xb0, 0x41, + 0x04, 0x80, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x9f, 0x18, 0xc2, 0x45, + 0x10, 0x32, 0xe8, 0x02, 0x50, 0xfc, 0x40, 0x00, 0x81, 0xed, 0x62, 0x94, + 0x0e, 0x00, 0x00, 0x0c, 0x50, 0xfc, 0x78, 0x02, 0x81, 0xed, 0x62, 0x94, + 0x2e, 0x00, 0x00, 0x0c, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, 0xab, 0x18, + 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x70, 0xfc, 0x84, 0x00, 0x43, 0xb4, + 0xef, 0xff, 0x00, 0x0c, 0x50, 0xfc, 0x88, 0x00, 0x6b, 0xad, 0x02, 0xed, + 0x90, 0xfc, 0x20, 0x01, 0x44, 0x94, 0x42, 0x00, 0xa4, 0x41, 0x04, 0x80, + 0x30, 0xfe, 0x18, 0x01, 0xa2, 0x41, 0x08, 0x80, 0x84, 0x30, 0x24, 0x03, + 0x42, 0x30, 0xed, 0x18, 0xc2, 0x45, 0x70, 0xf8, 0x18, 0x01, 0x30, 0xfa, + 0x18, 0x01, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, + 0xf0, 0x02, 0xb0, 0x6d, 0xcf, 0xcf, 0x62, 0xf8, 0xf0, 0x02, 0x70, 0xfc, + 0xbc, 0x02, 0x43, 0xb4, 0xd1, 0xff, 0xb9, 0x41, 0x08, 0x80, 0x50, 0xfc, + 0xc0, 0x02, 0x4e, 0xad, 0x39, 0x33, 0xab, 0x18, 0x90, 0xfc, 0x58, 0x03, + 0x02, 0xed, 0x44, 0x94, 0x25, 0x00, 0xa4, 0x41, 0x04, 0x80, 0x30, 0xfe, + 0x50, 0x03, 0xa2, 0x41, 0x08, 0x80, 0x84, 0x30, 0x5c, 0x05, 0x42, 0x30, + 0xed, 0x18, 0xc2, 0x45, 0x70, 0xf8, 0x50, 0x03, 0x30, 0xfa, 0x50, 0x03, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, 0xf0, 0x02, + 0xb0, 0x6d, 0xac, 0xcf, 0x62, 0xf8, 0xf0, 0x02, 0xa2, 0x41, 0x08, 0x80, + 0x01, 0xef, 0x81, 0xee, 0x42, 0x30, 0xe1, 0x18, 0xc2, 0x45, 0x84, 0x30, + 0x24, 0x03, 0xc5, 0xcf, 0xa2, 0x41, 0x04, 0x80, 0xa2, 0x41, 0x08, 0x80, + 0x01, 0xef, 0x81, 0xee, 0x42, 0x30, 0xe1, 0x18, 0xc2, 0x45, 0x84, 0x30, + 0x5c, 0x05, 0xe2, 0xcf, 0xa2, 0x41, 0x04, 0x80, 0xf1, 0x4f, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xa3, 0x14, 0x64, 0x45, 0xe2, 0x45, 0x00, 0x0c, + 0x22, 0x0e, 0x43, 0x0e, 0xa2, 0x41, 0x02, 0xa5, 0x60, 0x30, 0x00, 0x10, + 0x62, 0xf8, 0x68, 0x0c, 0xa2, 0x41, 0x04, 0x80, 0x22, 0xfa, 0x1c, 0x12, + 0xb0, 0x41, 0x04, 0x80, 0xa2, 0x41, 0x08, 0x80, 0x10, 0x32, 0xe8, 0x02, + 0x42, 0x30, 0xd5, 0x18, 0xe2, 0x45, 0x01, 0xee, 0x70, 0x14, 0xc2, 0x0b, + 0x01, 0xed, 0x43, 0x94, 0x4e, 0x00, 0x10, 0x18, 0xc1, 0x0b, 0xa6, 0x41, + 0x05, 0x80, 0xc6, 0x30, 0x00, 0x95, 0x50, 0xfc, 0xf4, 0x0b, 0x90, 0xfc, + 0x18, 0x0c, 0xe1, 0x69, 0xb0, 0xfc, 0xd8, 0x0b, 0x10, 0xfd, 0xdc, 0x0b, + 0xf0, 0xfc, 0x1c, 0x0c, 0x22, 0x25, 0xd8, 0x06, 0x34, 0x05, 0x07, 0x01, + 0x50, 0x39, 0x85, 0x00, 0x90, 0x23, 0x2b, 0x05, 0x78, 0x06, 0x45, 0x00, + 0x90, 0x3b, 0xf9, 0x07, 0xf2, 0x00, 0x90, 0x43, 0xe8, 0x40, 0x19, 0x00, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x47, 0x13, 0xe2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x00, 0xa4, 0x42, 0xfc, 0x04, 0x2c, 0x21, 0x2d, 0xe2, 0x40, + 0x0a, 0x00, 0x50, 0x14, 0xc5, 0x0b, 0x21, 0x2d, 0xa2, 0x40, 0x05, 0x00, + 0x50, 0x14, 0xc7, 0x0b, 0x25, 0x8d, 0xb9, 0x41, 0x04, 0x80, 0x24, 0x45, + 0x08, 0x47, 0x47, 0x96, 0x19, 0x00, 0x00, 0x0c, 0x6a, 0x69, 0xb0, 0xf8, + 0x18, 0x0c, 0x90, 0xf8, 0x1c, 0x0c, 0xa3, 0x04, 0xa2, 0x41, 0xe1, 0x11, + 0x42, 0x50, 0x00, 0xa3, 0x51, 0x00, 0x90, 0x8b, 0x87, 0xac, 0x62, 0x69, + 0xd5, 0xcf, 0x50, 0xf8, 0x08, 0x0c, 0xd2, 0xcf, 0x10, 0x18, 0xc2, 0x0b, + 0xb4, 0x05, 0xce, 0xcf, 0x70, 0xf8, 0x08, 0x0c, 0x51, 0x00, 0x90, 0x13, + 0xa2, 0x40, 0xc8, 0xff, 0xe4, 0xcf, 0x6a, 0x69, 0x39, 0x33, 0x99, 0x61, + 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0x64, 0x45, + 0x24, 0x0e, 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, 0x5c, 0xfe, + 0xec, 0x81, 0x88, 0xee, 0x80, 0x0c, 0x52, 0x30, 0x01, 0x00, 0x5c, 0xf8, + 0xec, 0x81, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x23, 0x19, 0xe2, 0x45, + 0x00, 0x0c, 0x51, 0x14, 0x14, 0x00, 0x02, 0x94, 0x46, 0x00, 0xa5, 0x41, + 0x00, 0x00, 0xa5, 0x41, 0x00, 0x00, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0x4d, 0x1b, 0xa5, 0x30, 0x78, 0x00, 0xe2, 0x45, 0x01, 0xee, 0xa2, 0x41, + 0x02, 0xa5, 0x02, 0xf8, 0x68, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x4d, 0x13, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0xb4, 0xf8, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0xb0, 0x41, 0x04, 0x80, 0xa2, 0x41, 0x08, 0x80, 0x10, 0x32, + 0xe8, 0x02, 0x01, 0xee, 0x42, 0x30, 0xd5, 0x18, 0xc2, 0x45, 0x10, 0x18, + 0xc0, 0x0b, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, + 0x9c, 0x02, 0x9c, 0xfc, 0xe8, 0x81, 0x5c, 0xfa, 0xec, 0x81, 0xb0, 0x6d, + 0x62, 0xf8, 0x9c, 0x02, 0x10, 0xae, 0x10, 0x18, 0xc1, 0x0b, 0x5c, 0xfc, + 0xec, 0x81, 0xa2, 0x40, 0x0a, 0x00, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, + 0xa0, 0x00, 0xa2, 0x40, 0x04, 0x00, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, + 0x00, 0x18, 0x24, 0x45, 0x08, 0x47, 0xa2, 0x41, 0x02, 0x80, 0xa5, 0x30, + 0x84, 0x00, 0x42, 0x30, 0x4d, 0x1b, 0xe2, 0x45, 0x01, 0xee, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, 0x98, 0x02, 0xb0, 0x41, + 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, 0xb0, 0x6d, 0x62, 0xf8, 0x98, 0x02, + 0x01, 0xed, 0x10, 0x18, 0xc0, 0x0b, 0x50, 0x18, 0xc2, 0x0b, 0x51, 0x14, + 0x16, 0x00, 0xb0, 0xfc, 0x68, 0x0b, 0x02, 0xee, 0x50, 0x18, 0xc5, 0x0b, + 0x51, 0x14, 0x17, 0x00, 0x50, 0x18, 0xc6, 0x0b, 0x51, 0x14, 0x15, 0x00, + 0x50, 0x18, 0xc4, 0x0b, 0x51, 0x14, 0x19, 0x00, 0x50, 0x18, 0xc9, 0x0b, + 0x51, 0x14, 0x1b, 0x00, 0x71, 0x14, 0x1a, 0x00, 0x20, 0x25, 0xd3, 0x44, + 0x50, 0x38, 0xca, 0x0b, 0x71, 0x60, 0x1f, 0x00, 0x51, 0x60, 0x23, 0x00, + 0x71, 0x60, 0x1c, 0x10, 0x51, 0x60, 0x20, 0x10, 0x70, 0xf8, 0x28, 0x0c, + 0x50, 0xf8, 0x2c, 0x0c, 0x51, 0x14, 0x25, 0x00, 0x71, 0x14, 0x24, 0x00, + 0x10, 0x18, 0xc8, 0x0b, 0x20, 0x25, 0xd3, 0x44, 0x50, 0x38, 0xcc, 0x0b, + 0x40, 0x30, 0x88, 0x13, 0x50, 0xf8, 0xf0, 0x0b, 0xb0, 0xf8, 0xf4, 0x0b, + 0x71, 0x14, 0x18, 0x00, 0x50, 0xfc, 0x58, 0x0b, 0x10, 0x18, 0xc1, 0x0b, + 0x70, 0x18, 0xc7, 0x0b, 0xa3, 0x41, 0x05, 0x80, 0x82, 0x94, 0x3a, 0x00, + 0x03, 0xf8, 0x10, 0x95, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xff, 0x12, + 0xe2, 0x45, 0x00, 0x0c, 0x90, 0xfc, 0x78, 0x0b, 0xb0, 0xfc, 0x7c, 0x0b, + 0xd0, 0xfc, 0x80, 0x0b, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xdd, 0xd5, + 0xc2, 0x45, 0xf0, 0xfc, 0x84, 0x0b, 0x50, 0xf8, 0xf8, 0x0b, 0x81, 0xed, + 0xa2, 0x41, 0x00, 0xa4, 0x62, 0xf8, 0x20, 0x2c, 0x50, 0xfc, 0x40, 0x00, + 0x81, 0xed, 0x62, 0x94, 0x2e, 0x00, 0x00, 0x0c, 0x50, 0xfc, 0x78, 0x02, + 0x81, 0xed, 0x62, 0x94, 0x4e, 0x00, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xf3, 0x12, 0xe2, 0x45, 0x00, 0x0c, 0x5c, 0xfc, 0xe8, 0x81, + 0x5c, 0xfa, 0xec, 0x81, 0xa2, 0x40, 0x6d, 0xff, 0x5c, 0xfc, 0xec, 0x81, + 0xe2, 0x40, 0x5f, 0xff, 0xe0, 0x40, 0x67, 0xff, 0x90, 0xfc, 0x78, 0x0b, + 0xb0, 0xfc, 0x7c, 0x0b, 0xd0, 0xfc, 0x80, 0x0b, 0xa2, 0x41, 0x01, 0x80, + 0x42, 0x30, 0xdd, 0xd5, 0xc2, 0x45, 0xf0, 0xfc, 0x84, 0x0b, 0x50, 0xf8, + 0xf8, 0x0b, 0x50, 0xfc, 0x40, 0x00, 0x81, 0xed, 0x62, 0xb4, 0xd4, 0xff, + 0x00, 0x0c, 0x70, 0xfc, 0x84, 0x00, 0x43, 0xb4, 0xcf, 0xff, 0x00, 0x0c, + 0x50, 0xfc, 0x88, 0x00, 0x4b, 0xad, 0x40, 0x0c, 0xa6, 0x26, 0xaa, 0x06, + 0xd6, 0x26, 0xab, 0x06, 0xd6, 0x26, 0xa5, 0x30, 0x6f, 0x00, 0xa4, 0x41, + 0x04, 0x80, 0xa2, 0x41, 0x01, 0x80, 0x06, 0xef, 0xd0, 0x06, 0x42, 0x30, + 0x61, 0xda, 0xc2, 0x45, 0x84, 0x30, 0x18, 0x0f, 0xbf, 0xcf, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x37, 0x14, 0xc2, 0x45, 0xb0, 0x41, 0x04, 0x80, + 0x08, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0x70, 0xfc, 0xbc, 0x02, 0x43, 0xb4, + 0xb1, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x50, 0xfc, 0xc0, 0x02, 0x02, 0xb4, + 0xa9, 0xff, 0x01, 0xed, 0xd8, 0xcf, 0xa6, 0x26, 0xd9, 0x4f, 0xa5, 0x41, + 0x00, 0x00, 0x1d, 0x23, 0x2c, 0xd0, 0xb3, 0x41, 0x02, 0x80, 0xb0, 0x41, + 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, 0x40, 0x0c, 0x60, 0x0c, 0xa5, 0x30, + 0x8c, 0x00, 0x73, 0x32, 0x4d, 0x1b, 0x5d, 0x20, 0x10, 0x90, 0xf3, 0x45, + 0x01, 0xee, 0x90, 0xfc, 0x78, 0x0b, 0xb2, 0x41, 0x04, 0x80, 0x52, 0x32, + 0x79, 0x4d, 0xd2, 0x45, 0xb0, 0xfc, 0x7c, 0x0b, 0x90, 0xfc, 0x80, 0x0b, + 0xb0, 0xfc, 0x84, 0x0b, 0xc2, 0x0e, 0xf2, 0x45, 0xe3, 0x0e, 0x34, 0x85, + 0xa2, 0x41, 0x04, 0x80, 0x96, 0x0c, 0x42, 0x30, 0x41, 0x43, 0xe2, 0x45, + 0xb7, 0x0c, 0xb0, 0x14, 0xc9, 0x0b, 0xb4, 0x41, 0x05, 0x80, 0x34, 0x32, + 0x00, 0x95, 0x51, 0x20, 0x30, 0x90, 0x85, 0x8e, 0x01, 0xee, 0x5e, 0x6e, + 0x82, 0xed, 0x64, 0x00, 0x10, 0x20, 0x70, 0x34, 0xca, 0x0b, 0x50, 0x14, + 0xc5, 0x0b, 0x10, 0xf8, 0xd4, 0x0b, 0x83, 0x00, 0x10, 0x1a, 0x22, 0x2e, + 0x10, 0xf8, 0xdc, 0x0b, 0x70, 0xf8, 0xd8, 0x0b, 0x04, 0x94, 0xd9, 0x00, + 0x70, 0x34, 0xcc, 0x0b, 0x63, 0x00, 0x00, 0x50, 0x70, 0xf8, 0xd0, 0x0b, + 0x24, 0x2d, 0x06, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0x01, 0xed, 0x14, 0xe9, + 0xa2, 0x41, 0x08, 0x80, 0x0d, 0x6f, 0x8f, 0x6e, 0x11, 0x6e, 0x42, 0x30, + 0x6d, 0x1a, 0xc2, 0x45, 0xb2, 0x41, 0x01, 0x80, 0x52, 0x32, 0x61, 0xda, + 0x91, 0x6e, 0x03, 0xef, 0xf2, 0x45, 0x09, 0x6e, 0x8f, 0x6e, 0x03, 0xef, + 0xd2, 0x45, 0x9d, 0x30, 0x13, 0x00, 0x8d, 0x6e, 0x9d, 0x30, 0x16, 0x00, + 0xf2, 0x45, 0x02, 0xef, 0x90, 0xfc, 0x2c, 0x0c, 0x65, 0x48, 0x50, 0xfc, + 0x28, 0x0c, 0x83, 0x00, 0x90, 0x2b, 0x05, 0xb4, 0x71, 0x00, 0x44, 0x4a, + 0x64, 0x94, 0x6a, 0x00, 0x52, 0x00, 0x90, 0x1b, 0xb5, 0x41, 0x04, 0x80, + 0xb5, 0x32, 0x20, 0x0f, 0x75, 0xfc, 0xe4, 0x02, 0x52, 0x00, 0xd0, 0x91, + 0xa2, 0x41, 0x08, 0x80, 0xb0, 0x6d, 0x42, 0x30, 0xa3, 0x14, 0xc2, 0x45, + 0x75, 0xf8, 0xe4, 0x02, 0xe3, 0x40, 0xa3, 0x00, 0x42, 0x02, 0xd0, 0x91, + 0x42, 0x02, 0x90, 0x13, 0xa7, 0x05, 0x50, 0xfa, 0x00, 0x0c, 0x70, 0xf8, + 0x04, 0x0c, 0xb0, 0xfc, 0xd4, 0x0b, 0x50, 0xfc, 0xdc, 0x0b, 0x70, 0xfc, + 0xd0, 0x0b, 0x45, 0x00, 0x90, 0x33, 0x06, 0xb4, 0x76, 0x00, 0x90, 0xfc, + 0xd8, 0x0b, 0xa2, 0x94, 0x80, 0x00, 0x83, 0x00, 0x90, 0x33, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x82, 0xfc, 0xec, 0x02, 0x00, 0x85, + 0xd0, 0xf8, 0x10, 0x0c, 0x40, 0x6e, 0x82, 0xf8, 0xec, 0x02, 0xf0, 0xf8, + 0x14, 0x0c, 0x90, 0xfc, 0x00, 0x0c, 0xb0, 0xfc, 0x04, 0x0c, 0xd0, 0xfc, + 0x58, 0x0b, 0xe4, 0xef, 0x90, 0xf8, 0x18, 0x0c, 0x91, 0x20, 0x28, 0x90, + 0x01, 0xee, 0xf4, 0xf8, 0x00, 0x95, 0x70, 0xf8, 0x08, 0x0c, 0x92, 0xe9, + 0x13, 0xea, 0x81, 0xef, 0xa3, 0x41, 0x02, 0xa5, 0x80, 0x30, 0x00, 0x10, + 0x02, 0xed, 0xf0, 0x18, 0xc0, 0x0b, 0xb0, 0xf8, 0x1c, 0x0c, 0x11, 0xe8, + 0x15, 0xe8, 0x17, 0xe8, 0x18, 0xe8, 0x19, 0xe8, 0x83, 0xf8, 0x68, 0x0c, + 0x46, 0x94, 0x61, 0x00, 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x30, 0x9c, 0x00, + 0xf3, 0x45, 0x01, 0xee, 0x40, 0x0c, 0x1d, 0x23, 0x2c, 0x50, 0x14, 0x47, + 0x03, 0x94, 0x98, 0xff, 0xb5, 0x41, 0x04, 0x80, 0x42, 0x02, 0xd0, 0x91, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xa3, 0x14, 0xe2, 0x45, 0x00, 0x0c, + 0xd0, 0xfc, 0xf0, 0x0b, 0xb0, 0xfc, 0xf4, 0x0b, 0x52, 0x00, 0x50, 0x11, + 0x42, 0x02, 0x90, 0x23, 0xea, 0x06, 0xb8, 0x05, 0xb2, 0x00, 0x90, 0x93, + 0x50, 0xf8, 0x00, 0x0c, 0x12, 0x94, 0x97, 0xff, 0x70, 0xf8, 0x04, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, 0xe0, 0x02, + 0xb0, 0xfc, 0xd4, 0x0b, 0x90, 0xfc, 0xd8, 0x0b, 0xb0, 0x6d, 0x62, 0xf8, + 0xe0, 0x02, 0x50, 0xfc, 0xdc, 0x0b, 0x45, 0x00, 0x90, 0x33, 0x06, 0x94, + 0x8e, 0xff, 0x70, 0xfc, 0xd0, 0x0b, 0x39, 0x07, 0xc4, 0x00, 0x90, 0x23, + 0x55, 0x05, 0x45, 0x05, 0xd0, 0xf8, 0x10, 0x0c, 0x96, 0xcf, 0x50, 0xf8, + 0x14, 0x0c, 0xb0, 0x25, 0x2b, 0xcf, 0x70, 0xf8, 0xd0, 0x0b, 0x06, 0x94, + 0x80, 0xff, 0x39, 0x07, 0xc4, 0x00, 0x90, 0x23, 0x55, 0x05, 0x45, 0x05, + 0xd0, 0xf8, 0x10, 0x0c, 0x86, 0xcf, 0x50, 0xf8, 0x14, 0x0c, 0x52, 0x00, + 0x90, 0x23, 0xa4, 0x40, 0x59, 0xff, 0x55, 0xfc, 0xe8, 0x02, 0x20, 0x6d, + 0x5e, 0xcf, 0x55, 0xf8, 0xe8, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x8f, 0x19, 0xe2, 0x45, 0x00, 0x0c, 0xa5, 0x41, 0x00, 0x00, 0xa5, 0x30, + 0x9c, 0x00, 0xf3, 0x45, 0x01, 0xee, 0x40, 0x0c, 0x1d, 0x23, 0x2c, 0x50, + 0x14, 0x47, 0x00, 0x0c, 0xdd, 0x4f, 0xdd, 0x22, 0x2c, 0xd0, 0xb1, 0x41, + 0x04, 0x80, 0x31, 0x32, 0x20, 0x0f, 0x51, 0xfc, 0x8c, 0x02, 0xb4, 0x41, + 0x05, 0x80, 0x20, 0x6d, 0x51, 0xf8, 0x8c, 0x02, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xa3, 0x14, 0xc2, 0x45, 0x94, 0x32, 0x00, 0x95, 0x42, 0x0e, + 0x54, 0xfc, 0x0c, 0x00, 0xb0, 0x41, 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, + 0x63, 0x0e, 0x50, 0xfa, 0x20, 0x0c, 0x13, 0x8d, 0x70, 0xf8, 0x24, 0x0c, + 0x54, 0x20, 0x28, 0x10, 0x63, 0x02, 0x90, 0x23, 0xe4, 0x40, 0xa4, 0x00, + 0xa3, 0x41, 0xe1, 0x11, 0x52, 0x00, 0xd0, 0x11, 0x63, 0x50, 0x00, 0xa3, + 0x62, 0x00, 0x90, 0x13, 0x02, 0x94, 0x50, 0x01, 0x60, 0x0c, 0xb0, 0xfc, + 0x18, 0x0c, 0xd0, 0xfc, 0x1c, 0x0c, 0x50, 0x14, 0xc2, 0x0b, 0xe2, 0x40, + 0x45, 0x00, 0x50, 0xfc, 0xf0, 0x0b, 0x70, 0xfc, 0xf4, 0x0b, 0xa6, 0x05, + 0xbb, 0x05, 0x65, 0x00, 0x90, 0x13, 0x2d, 0x05, 0x53, 0x00, 0x90, 0x23, + 0xa4, 0x40, 0x93, 0x00, 0x62, 0x96, 0x8d, 0x00, 0x66, 0x02, 0x90, 0x13, + 0x02, 0xb4, 0x29, 0x01, 0xa2, 0x41, 0x08, 0x80, 0xd3, 0x94, 0x21, 0x01, + 0x45, 0x02, 0x90, 0x13, 0x70, 0xfc, 0x08, 0x0c, 0x66, 0x02, 0xd0, 0x99, + 0x07, 0xef, 0x43, 0x02, 0xd0, 0x91, 0xb2, 0x00, 0x50, 0x11, 0x43, 0x02, + 0x90, 0x1b, 0x73, 0x00, 0xd0, 0x19, 0x42, 0x02, 0x90, 0x93, 0x82, 0x0c, + 0x50, 0xf8, 0xe0, 0x0b, 0xa2, 0x41, 0x08, 0x80, 0x72, 0x00, 0x50, 0x91, + 0x42, 0x30, 0x1d, 0x19, 0x88, 0xee, 0x10, 0x18, 0xc2, 0x0b, 0xc2, 0x45, + 0x50, 0xfa, 0xe4, 0x0b, 0x70, 0x14, 0xc1, 0x0b, 0x01, 0xed, 0x43, 0xb4, + 0x52, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xd5, 0x18, 0xe2, 0x45, + 0x01, 0xee, 0x4b, 0xcc, 0x10, 0x18, 0xc1, 0x0b, 0x70, 0xfc, 0x08, 0x0c, + 0x56, 0x05, 0x62, 0x00, 0x90, 0x1b, 0xe6, 0x05, 0xe2, 0x30, 0x0c, 0xfe, + 0x03, 0x31, 0xff, 0xff, 0x47, 0x00, 0x90, 0x23, 0x04, 0x01, 0x50, 0x21, + 0x93, 0x00, 0x90, 0x43, 0xa8, 0x40, 0x13, 0x00, 0x64, 0x96, 0xae, 0x00, + 0xf2, 0x00, 0x90, 0x3b, 0xf0, 0xfc, 0xd8, 0x0b, 0x10, 0xfd, 0xdc, 0x0b, + 0xfa, 0x07, 0x06, 0x01, 0x50, 0x41, 0xa7, 0x00, 0x90, 0x23, 0x04, 0x01, + 0x50, 0x21, 0x64, 0x02, 0x90, 0x43, 0xe8, 0x40, 0xa4, 0x00, 0x73, 0x00, + 0x90, 0x23, 0xe4, 0x40, 0x2a, 0x01, 0xb1, 0xfc, 0xc4, 0x02, 0x42, 0x02, + 0xd0, 0x21, 0x63, 0x02, 0xd0, 0x99, 0x82, 0x00, 0x90, 0x13, 0xd0, 0x14, + 0xc1, 0x0b, 0x53, 0x00, 0xd0, 0x11, 0xd0, 0x6d, 0x50, 0xf8, 0xe4, 0x0b, + 0x81, 0xee, 0x02, 0xed, 0x90, 0xf8, 0xe0, 0x0b, 0x71, 0xf8, 0xc4, 0x02, + 0xa6, 0x94, 0x3a, 0x01, 0x51, 0xf8, 0xa0, 0x02, 0xa2, 0x41, 0x08, 0x80, + 0x07, 0xef, 0x42, 0x30, 0x1d, 0x19, 0xe2, 0x45, 0x88, 0xee, 0xdd, 0x22, + 0x2c, 0x50, 0x12, 0x47, 0x73, 0xb4, 0x65, 0xff, 0x42, 0x02, 0x90, 0x1b, + 0x03, 0x94, 0x61, 0xff, 0xa3, 0x41, 0xe1, 0x11, 0x57, 0xcf, 0x52, 0x00, + 0xd0, 0x11, 0x72, 0x00, 0x90, 0x1b, 0xe3, 0x40, 0x71, 0xff, 0x71, 0xfc, + 0xc8, 0x02, 0x45, 0x02, 0xd0, 0x91, 0x90, 0x14, 0xc1, 0x0b, 0x66, 0x02, + 0xd0, 0x99, 0x45, 0x02, 0x90, 0x13, 0x53, 0x00, 0xd0, 0x11, 0xb0, 0x6d, + 0x60, 0x32, 0x01, 0x00, 0x50, 0xfa, 0xe0, 0x0b, 0x50, 0xf8, 0xe4, 0x0b, + 0x50, 0xfa, 0xe8, 0x0b, 0x50, 0xf8, 0xec, 0x0b, 0x71, 0xfa, 0xa0, 0x02, + 0x04, 0x94, 0xd4, 0x00, 0x71, 0xf8, 0xc8, 0x02, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x35, 0x13, 0xe2, 0x45, 0x00, 0x0c, 0xe2, 0x40, 0x2e, 0x00, + 0x51, 0xfc, 0xd4, 0x02, 0x20, 0x6d, 0x51, 0xf8, 0xd4, 0x02, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x4d, 0x13, 0xe2, 0x45, 0x00, 0x0c, 0x16, 0x8d, + 0xa2, 0x41, 0x02, 0xa5, 0x42, 0xfc, 0x8c, 0x0c, 0x7c, 0xfc, 0xc8, 0xa7, + 0x21, 0x25, 0xd3, 0x44, 0x0f, 0xad, 0xa2, 0x41, 0x08, 0x80, 0x54, 0xfc, + 0x1c, 0x00, 0x20, 0x6d, 0x54, 0xf8, 0x1c, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x37, 0x14, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, + 0x07, 0xef, 0x88, 0xee, 0x42, 0x30, 0x1d, 0x19, 0xc2, 0x45, 0x80, 0x30, + 0xd0, 0x07, 0xdd, 0x22, 0x2c, 0x50, 0x12, 0x47, 0x51, 0xfc, 0x90, 0x02, + 0x90, 0xfc, 0xe8, 0x0b, 0x20, 0x6d, 0x51, 0xf8, 0x90, 0x02, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xe7, 0x12, 0xe2, 0x45, 0x00, 0x0c, 0x81, 0xed, + 0x62, 0x94, 0xe4, 0xff, 0x00, 0x0c, 0xdd, 0x22, 0x2c, 0x50, 0x12, 0x47, + 0x07, 0xb4, 0x63, 0xff, 0x73, 0x00, 0x90, 0x23, 0x51, 0xcf, 0xf0, 0xfc, + 0xd8, 0x0b, 0x93, 0xb4, 0x04, 0x00, 0x47, 0x02, 0x90, 0x43, 0xa8, 0x40, + 0x56, 0xff, 0x47, 0x02, 0xd0, 0x11, 0x70, 0x14, 0xc1, 0x0b, 0x47, 0x00, + 0x90, 0x3b, 0x64, 0x02, 0xd0, 0x21, 0x79, 0x06, 0xa0, 0x32, 0x01, 0x00, + 0x50, 0xf8, 0xe0, 0x0b, 0x90, 0xf8, 0xe4, 0x0b, 0x50, 0xf8, 0xe8, 0x0b, + 0x90, 0xf8, 0xec, 0x0b, 0x03, 0x94, 0xa1, 0x00, 0xb1, 0xfa, 0xa0, 0x02, + 0xb0, 0xfc, 0xf0, 0x0b, 0x70, 0xfc, 0xf4, 0x0b, 0x04, 0x94, 0xa6, 0x00, + 0xd6, 0x05, 0x51, 0xfc, 0xc8, 0x02, 0x20, 0x6d, 0x87, 0xcf, 0x51, 0xf8, + 0xc8, 0x02, 0x02, 0x94, 0xdf, 0xfe, 0xa2, 0x41, 0x08, 0x80, 0x07, 0xef, + 0x88, 0xee, 0x80, 0x30, 0xd0, 0x07, 0x42, 0x30, 0x1d, 0x19, 0xc2, 0x45, + 0x10, 0x18, 0xc2, 0x0b, 0x48, 0xcf, 0x00, 0x0c, 0x40, 0x0c, 0x5d, 0x20, + 0x10, 0x90, 0xa2, 0x41, 0x08, 0x80, 0x0d, 0x6f, 0x8f, 0x6e, 0x11, 0x6e, + 0x42, 0x30, 0x6d, 0x1a, 0xc2, 0x45, 0xb5, 0x41, 0x01, 0x80, 0xb5, 0x32, + 0x61, 0xda, 0x91, 0x6e, 0x03, 0xef, 0xf5, 0x45, 0x09, 0x6e, 0x8f, 0x6e, + 0x03, 0xef, 0xd5, 0x45, 0x9d, 0x30, 0x13, 0x00, 0x02, 0xef, 0x8d, 0x6e, + 0xd5, 0x45, 0x9d, 0x30, 0x16, 0x00, 0x47, 0x48, 0x02, 0x94, 0xa3, 0x00, + 0x45, 0x48, 0xa4, 0x48, 0x90, 0xfc, 0x28, 0x0c, 0x70, 0xfc, 0x2c, 0x0c, + 0x4b, 0x06, 0xd0, 0xfc, 0xd8, 0x0b, 0x35, 0x05, 0x85, 0x00, 0x90, 0x2b, + 0xd5, 0x06, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0x01, 0x40, 0xc2, 0x45, + 0xf0, 0xfc, 0xdc, 0x0b, 0x74, 0xfc, 0x14, 0x00, 0x52, 0x00, 0xd0, 0x29, + 0xb2, 0x00, 0x90, 0x33, 0xd3, 0x00, 0xd0, 0x31, 0xb0, 0x6d, 0xb0, 0xf8, + 0x18, 0x0c, 0xd0, 0xf8, 0x1c, 0x0c, 0x74, 0xf8, 0x14, 0x00, 0x54, 0x22, + 0x28, 0x90, 0x71, 0xce, 0x50, 0x14, 0xc2, 0x0b, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xd5, 0x18, 0xe2, 0x45, 0x00, 0x0c, 0x27, 0xcf, 0x70, 0x1a, + 0xc1, 0x0b, 0x63, 0xb6, 0x04, 0x00, 0x52, 0x00, 0x90, 0x23, 0xa4, 0x40, + 0xd0, 0xfe, 0x70, 0xfc, 0xd8, 0x0b, 0xf1, 0xfc, 0xd0, 0x02, 0x70, 0xfe, + 0xdc, 0x0b, 0x56, 0x05, 0x62, 0x00, 0x90, 0x1b, 0xd3, 0x00, 0x50, 0x31, + 0xf0, 0x6f, 0x50, 0xf8, 0x18, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0xe6, 0x05, + 0xf1, 0xf8, 0xd0, 0x02, 0x80, 0x30, 0xd0, 0x07, 0x83, 0xef, 0x07, 0xef, + 0x88, 0xee, 0x42, 0x30, 0x1d, 0x19, 0x70, 0xf8, 0x1c, 0x0c, 0xc2, 0x45, + 0xf1, 0xf8, 0xa0, 0x02, 0xd0, 0xce, 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xd5, 0x18, 0xe2, 0x45, 0x01, 0xee, 0x90, 0xfc, 0xe0, 0x0b, + 0xbf, 0xce, 0x10, 0x18, 0xc1, 0x0b, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xd5, 0x18, 0xe2, 0x45, 0x80, 0x0c, 0x50, 0xfc, 0xe0, 0x0b, 0x90, 0xfc, + 0xe4, 0x0b, 0x56, 0xcf, 0xb0, 0x1a, 0xc1, 0x0b, 0x43, 0x00, 0x90, 0x13, + 0x02, 0xb4, 0x57, 0xff, 0x07, 0xef, 0x50, 0xfc, 0x18, 0x0c, 0x70, 0xfc, + 0xd8, 0x0b, 0xb0, 0xfc, 0xdc, 0x0b, 0x90, 0xfc, 0x1c, 0x0c, 0xb4, 0x05, + 0x43, 0x00, 0x90, 0x13, 0x58, 0x06, 0x44, 0x05, 0xf1, 0xfc, 0xcc, 0x02, + 0x43, 0x02, 0xd0, 0x91, 0x62, 0x02, 0xd0, 0x99, 0x50, 0xf8, 0x1c, 0x0c, + 0x04, 0xed, 0x43, 0x02, 0x90, 0x23, 0x51, 0xf8, 0xa0, 0x02, 0xa2, 0x41, + 0x08, 0x80, 0x93, 0x00, 0xd0, 0x99, 0xf0, 0x6f, 0x88, 0xee, 0x92, 0x0c, + 0x42, 0x30, 0x1d, 0x19, 0x50, 0xfa, 0xe0, 0x0b, 0x70, 0xfa, 0xe4, 0x0b, + 0x70, 0xf8, 0x18, 0x0c, 0xc2, 0x45, 0xf1, 0xf8, 0xcc, 0x02, 0x85, 0xce, + 0x00, 0x0c, 0x54, 0xfc, 0x18, 0x00, 0x07, 0xef, 0x88, 0xee, 0x20, 0x6d, + 0x54, 0xf8, 0x18, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1d, 0x19, + 0xc2, 0x45, 0x80, 0x30, 0xd0, 0x07, 0x75, 0xce, 0x00, 0x0c, 0x00, 0x0c, + 0xe1, 0x4f, 0xa2, 0x41, 0x02, 0xa5, 0x04, 0xc8, 0x3d, 0x23, 0x18, 0xd0, + 0x02, 0xfe, 0x00, 0x28, 0x01, 0x24, 0x50, 0xd0, 0x00, 0x01, 0xe2, 0x40, + 0x11, 0x00, 0xb1, 0x41, 0x04, 0x80, 0x31, 0x32, 0xe8, 0x02, 0x51, 0x14, + 0xc0, 0x0b, 0x0a, 0xad, 0x85, 0xed, 0x51, 0xfc, 0x60, 0x0b, 0x62, 0x94, + 0x81, 0x00, 0x84, 0xed, 0x62, 0x94, 0x60, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x06, 0x2c, 0x21, 0x8c, 0xa2, 0x41, 0x04, 0x80, 0x42, 0xfc, 0x8c, 0x0e, + 0x21, 0x2d, 0x1b, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0xb0, 0x41, 0x04, 0x80, + 0xb1, 0x41, 0x04, 0x80, 0xc2, 0x32, 0x17, 0x19, 0xa2, 0x41, 0x04, 0x80, + 0x10, 0x32, 0xcc, 0x03, 0x31, 0x32, 0x3c, 0x08, 0x42, 0x32, 0x20, 0x0f, + 0x50, 0xfc, 0x5c, 0xff, 0x81, 0xed, 0x62, 0x94, 0x0f, 0x00, 0x00, 0x0c, + 0x10, 0x32, 0x38, 0x02, 0x30, 0xb6, 0xf6, 0xff, 0x00, 0x0c, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0xfd, 0x25, 0xe2, 0x45, 0x00, 0x0c, 0x3d, 0x23, + 0x18, 0x50, 0x10, 0x47, 0x70, 0xfc, 0xa0, 0xff, 0x43, 0xb4, 0xee, 0xff, + 0xf0, 0x32, 0x18, 0x00, 0xb0, 0x32, 0xb0, 0xff, 0x90, 0x0e, 0x60, 0x0e, + 0xc0, 0x33, 0x04, 0x00, 0x54, 0x14, 0x00, 0x00, 0x0d, 0xad, 0xb3, 0x0c, + 0x62, 0x4e, 0x82, 0x4e, 0xe6, 0x4e, 0xd3, 0xb7, 0xf7, 0xff, 0xa8, 0x4e, + 0x52, 0xfc, 0x48, 0x03, 0x20, 0x6d, 0xd8, 0xcf, 0x52, 0xf8, 0x48, 0x03, + 0x57, 0x14, 0x00, 0x00, 0x8b, 0x69, 0x27, 0x2d, 0x62, 0x00, 0x10, 0x12, + 0x1c, 0xef, 0x82, 0x0c, 0xd6, 0x45, 0x55, 0xf8, 0x00, 0x00, 0x55, 0x14, + 0x58, 0x00, 0xa7, 0x2d, 0x29, 0x25, 0x75, 0xf8, 0x28, 0x00, 0x55, 0xf8, + 0x3c, 0x00, 0xe0, 0xcf, 0x14, 0x18, 0x00, 0x00, 0x42, 0x30, 0x8b, 0x14, + 0x89, 0x6e, 0xe2, 0x45, 0x01, 0xee, 0x51, 0xfc, 0x68, 0x0b, 0x64, 0x48, + 0x62, 0x00, 0x90, 0x13, 0x02, 0x94, 0x96, 0xff, 0x07, 0xef, 0x88, 0xee, + 0x80, 0x30, 0xb8, 0x0b, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1d, 0x19, + 0xe2, 0x45, 0x06, 0x2c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe7, 0x15, + 0xe2, 0x45, 0x00, 0x0c, 0x86, 0xcf, 0x00, 0x0c, 0x07, 0xef, 0x88, 0xee, + 0xef, 0xcf, 0x80, 0x30, 0x88, 0x13, 0x00, 0x0c, 0xd9, 0x4f, 0xa3, 0x41, + 0x08, 0x80, 0x3d, 0x23, 0x28, 0xd0, 0xa8, 0x41, 0x08, 0x80, 0xa9, 0x41, + 0x02, 0xa5, 0xb2, 0x41, 0x08, 0x80, 0xb1, 0x41, 0x04, 0x80, 0xb3, 0x41, + 0x04, 0x80, 0xa3, 0x32, 0x84, 0x46, 0xe8, 0x32, 0x80, 0x47, 0xc9, 0x33, + 0xf0, 0x0a, 0x05, 0xec, 0x52, 0x32, 0xd0, 0x46, 0x31, 0x32, 0x20, 0x0f, + 0x73, 0x32, 0xe8, 0x02, 0x5c, 0xfc, 0xc8, 0xa7, 0xa4, 0x41, 0x02, 0xa5, + 0x04, 0xc8, 0x1d, 0x38, 0x14, 0x00, 0x84, 0xfc, 0x8c, 0x0c, 0x08, 0xad, + 0x04, 0x25, 0x42, 0x02, 0x50, 0x11, 0x20, 0x6b, 0x81, 0xee, 0xa6, 0x94, + 0x0d, 0x00, 0x00, 0x0c, 0x00, 0x6c, 0x09, 0xed, 0xc8, 0x4f, 0xb5, 0x32, + 0x08, 0x00, 0x50, 0xb4, 0xe7, 0xff, 0xf7, 0x32, 0x10, 0x00, 0x3d, 0x23, + 0x28, 0x50, 0x14, 0x47, 0x41, 0x26, 0x72, 0xae, 0xb6, 0x41, 0x03, 0x80, + 0x20, 0xe8, 0x1c, 0xf8, 0xc8, 0xa7, 0x56, 0x30, 0xc9, 0xd0, 0x95, 0x0c, + 0x1e, 0xf8, 0x00, 0x00, 0xc2, 0x45, 0x5d, 0xf8, 0x18, 0x00, 0x64, 0x8d, + 0xb4, 0x41, 0x05, 0x80, 0x94, 0x32, 0x00, 0x95, 0xa3, 0x41, 0x03, 0x80, + 0x54, 0xfd, 0x10, 0x00, 0x63, 0x30, 0xe5, 0xd0, 0xb6, 0x41, 0x08, 0x80, + 0x68, 0xc8, 0xa3, 0x41, 0x08, 0x80, 0x69, 0xc8, 0x82, 0x0c, 0x89, 0x6f, + 0xd0, 0x0c, 0x81, 0xee, 0x0a, 0xb4, 0x2f, 0x00, 0x96, 0x31, 0x95, 0x19, + 0x51, 0xfd, 0xf0, 0x00, 0x62, 0xfd, 0x48, 0x01, 0x1c, 0x18, 0xa0, 0x81, + 0x42, 0x4d, 0x0b, 0x94, 0x4e, 0x00, 0x51, 0xf9, 0xf0, 0x00, 0x53, 0x15, + 0xc0, 0x0b, 0x0a, 0x94, 0x06, 0x00, 0x1c, 0xf8, 0xbc, 0xa7, 0x53, 0x15, + 0xc1, 0x0b, 0xaa, 0x40, 0x38, 0x00, 0xec, 0x45, 0x00, 0x0c, 0x54, 0xfc, + 0x20, 0x00, 0x17, 0xf8, 0x50, 0x00, 0x20, 0x6d, 0x54, 0xf8, 0x20, 0x00, + 0x46, 0x48, 0xe2, 0x45, 0x95, 0x0c, 0x02, 0x94, 0xa9, 0xff, 0x89, 0x6f, + 0x54, 0xfd, 0x10, 0x00, 0x82, 0x0c, 0xd0, 0x0c, 0x81, 0xee, 0x0a, 0x94, + 0xd5, 0xff, 0x96, 0x31, 0x95, 0x19, 0xa2, 0x0c, 0x47, 0xc8, 0x48, 0x48, + 0xe2, 0x45, 0x95, 0x0c, 0x47, 0x48, 0x69, 0x48, 0xa6, 0x41, 0x03, 0x80, + 0x82, 0x14, 0x21, 0x00, 0xa3, 0x30, 0x5c, 0x46, 0xc6, 0x30, 0xa9, 0xd0, + 0x46, 0x26, 0x4a, 0x06, 0x02, 0x18, 0x7d, 0x00, 0xe6, 0x45, 0xa2, 0x0c, + 0x47, 0x48, 0x02, 0xf8, 0xb8, 0x01, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x65, 0x19, 0xe2, 0x45, 0x80, 0x0c, 0xd3, 0xcf, 0x46, 0x48, 0x82, 0x0c, + 0x89, 0x6f, 0xd0, 0x0c, 0x56, 0x30, 0x95, 0x19, 0xe2, 0x45, 0x89, 0xee, + 0xc4, 0xcf, 0x54, 0xfc, 0x20, 0x00, 0x82, 0x0c, 0x40, 0x84, 0x56, 0x30, + 0x95, 0x19, 0xe2, 0x45, 0x89, 0x6f, 0xc1, 0xcf, 0x46, 0x48, 0x00, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x14, 0xa8, 0x0e, 0x09, 0x8d, 0xa3, 0x41, + 0x08, 0x80, 0x48, 0x25, 0x63, 0x30, 0x80, 0x47, 0x34, 0x05, 0x20, 0x69, + 0xe2, 0x40, 0x05, 0x00, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0xe5, 0xe6, + 0xb9, 0x45, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0x00, 0x95, 0xa9, 0x69, + 0xb0, 0x6d, 0xa9, 0xe9, 0x9f, 0x45, 0x40, 0x0c, 0xe9, 0x4f, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0x80, 0xaf, 0xbd, 0x22, 0x18, 0xd0, 0xe2, 0x45, + 0x24, 0x0e, 0x02, 0x94, 0xc8, 0x00, 0xb2, 0x41, 0x04, 0x80, 0x22, 0x62, + 0x0b, 0x00, 0x52, 0x32, 0xe8, 0x02, 0x02, 0x0e, 0x22, 0x62, 0x08, 0x10, + 0x52, 0xfc, 0x54, 0x0b, 0x0e, 0xad, 0x14, 0xed, 0x51, 0x94, 0x94, 0x00, + 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0xc2, 0x86, 0x42, 0x30, 0x6b, 0x16, + 0xe2, 0x45, 0x00, 0x0c, 0xbd, 0x22, 0x18, 0x50, 0x0c, 0x47, 0x51, 0xb4, + 0x3d, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, + 0x00, 0x18, 0x9c, 0xfe, 0xec, 0x81, 0x54, 0x30, 0x01, 0x00, 0x5c, 0xf8, + 0xec, 0x81, 0x50, 0x60, 0x17, 0x00, 0x50, 0x60, 0x14, 0x10, 0x33, 0x8d, + 0xb3, 0x41, 0x04, 0x80, 0x73, 0x32, 0x20, 0x0f, 0x53, 0xfc, 0x7c, 0x02, + 0x72, 0x14, 0xc0, 0x0b, 0x20, 0x6d, 0x03, 0xb4, 0xad, 0x00, 0x53, 0xf8, + 0x7c, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, + 0x02, 0xee, 0x5c, 0xfc, 0xe8, 0x81, 0x9c, 0xfa, 0xec, 0x81, 0x4d, 0xad, + 0xa2, 0x41, 0x08, 0x80, 0x5c, 0xfc, 0xec, 0x81, 0x48, 0xad, 0xa2, 0x41, + 0x08, 0x80, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, 0xa0, 0x00, 0xa2, 0x40, + 0xbe, 0xff, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, 0x00, 0x18, 0xbb, 0xcf, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, 0x02, 0xee, + 0xb4, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0x79, 0xc9, 0xe2, 0x45, 0x00, 0x0c, 0x02, 0x94, 0x6f, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0xb3, 0x41, 0x04, 0x80, 0xa2, 0x41, 0x04, 0x80, 0x73, 0x32, + 0x20, 0x0f, 0x62, 0xfc, 0xc4, 0x02, 0x53, 0xfc, 0x80, 0x02, 0x43, 0x94, + 0x87, 0x00, 0x00, 0x0c, 0x53, 0xfc, 0x84, 0x02, 0x20, 0x6d, 0x53, 0xf8, + 0x84, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, + 0x01, 0xee, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x54, 0xaf, 0xe2, 0x45, + 0x90, 0x0c, 0x52, 0x14, 0xc0, 0x0b, 0x02, 0xb4, 0xa4, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x5c, 0xfc, 0xe8, 0x81, 0x9c, 0xfa, 0xec, 0x81, 0xa2, 0x40, + 0x83, 0xff, 0x5c, 0xfc, 0xec, 0x81, 0xa2, 0x40, 0x7f, 0xff, 0xfa, 0x40, + 0x04, 0x00, 0x5a, 0xfc, 0xa0, 0x00, 0xa2, 0x40, 0x79, 0xff, 0x00, 0x00, + 0x7c, 0x57, 0x76, 0xcf, 0x00, 0x00, 0x00, 0x18, 0x52, 0x14, 0xc0, 0x0b, + 0x02, 0x94, 0x6b, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x72, 0xfc, 0x58, 0x0b, + 0x02, 0xed, 0x43, 0xb4, 0x64, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x50, 0x60, + 0x17, 0x00, 0x50, 0x60, 0x14, 0x10, 0xa2, 0x40, 0x70, 0x00, 0xa2, 0x41, + 0x04, 0x80, 0x42, 0x30, 0x20, 0x0f, 0x62, 0xfc, 0xb0, 0x02, 0xb0, 0x6d, + 0x62, 0xf8, 0xb0, 0x02, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xc5, 0x16, + 0xe2, 0x45, 0x02, 0xee, 0x4c, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, 0x02, 0xee, 0x17, 0x6a, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x71, 0x16, 0xe2, 0x45, 0xb1, 0x0c, + 0xe0, 0x40, 0x40, 0xff, 0x80, 0x86, 0x42, 0x30, 0xe1, 0x12, 0xe2, 0x45, + 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe1, 0x15, 0xe2, 0x45, + 0x01, 0xee, 0x5f, 0xcf, 0x5c, 0xfc, 0xe8, 0x81, 0xa5, 0x41, 0x00, 0x00, + 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x4d, 0x1b, 0xa5, 0x30, 0xac, 0x00, + 0xe2, 0x45, 0x01, 0xee, 0x53, 0xfc, 0xb4, 0x02, 0xb2, 0x41, 0x08, 0x80, + 0x52, 0x32, 0xc5, 0x16, 0x20, 0x6d, 0x53, 0xf8, 0xb4, 0x02, 0xf2, 0x45, + 0x02, 0xee, 0x41, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0x52, 0x14, 0xc0, 0x0b, + 0x0e, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0xb2, 0x41, 0x08, 0x80, 0x52, 0x32, + 0xc5, 0x16, 0xf2, 0x45, 0x01, 0xee, 0x81, 0xed, 0x62, 0xb4, 0xd1, 0xff, + 0x00, 0x0c, 0xe0, 0x40, 0xea, 0xff, 0x42, 0x30, 0x85, 0x14, 0xe2, 0x45, + 0x00, 0x0c, 0x20, 0x6e, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x8b, 0x14, + 0xe2, 0x45, 0x89, 0x6e, 0x52, 0xfc, 0x68, 0x0b, 0x64, 0x48, 0x62, 0x00, + 0x90, 0x13, 0xa2, 0x40, 0x17, 0x00, 0x53, 0xfc, 0x70, 0x02, 0x20, 0x6d, + 0xb8, 0xcf, 0x53, 0xf8, 0x70, 0x02, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0x20, 0x0f, 0x62, 0xfc, 0xb4, 0x02, 0xb0, 0x6d, 0x91, 0xcf, 0x62, 0xf8, + 0xb4, 0x02, 0x42, 0x30, 0xc5, 0x16, 0xe2, 0x45, 0x02, 0xee, 0x5b, 0xcf, + 0x5c, 0xfc, 0xe8, 0x81, 0xa2, 0x41, 0x08, 0x80, 0x86, 0x86, 0x42, 0x30, + 0xe1, 0x12, 0xc2, 0x45, 0x73, 0xf8, 0x74, 0x02, 0x9e, 0xcf, 0xa2, 0x41, + 0x08, 0x80, 0x00, 0x0c, 0xed, 0x4f, 0xa4, 0xfc, 0x50, 0x00, 0xa2, 0x41, + 0x01, 0x80, 0x57, 0x45, 0x02, 0xef, 0x04, 0x0e, 0x42, 0x30, 0x61, 0xda, + 0xe2, 0x45, 0x09, 0x6e, 0x30, 0xfe, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xaf, 0x14, 0xb1, 0x30, 0x0a, 0x00, 0xe2, 0x45, 0x12, 0x6e, + 0x08, 0x8d, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x59, 0xfa, 0xe2, 0x45, + 0x90, 0x0c, 0x17, 0x45, 0x0a, 0x47, 0x14, 0x09, 0x21, 0x2d, 0x02, 0x94, + 0x67, 0x00, 0x5d, 0x34, 0x10, 0x00, 0x42, 0x00, 0x2c, 0x0a, 0x10, 0x8d, + 0x81, 0xed, 0x62, 0x94, 0x6b, 0x00, 0x82, 0xed, 0x62, 0x94, 0x72, 0x00, + 0x90, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe5, 0x14, + 0xe2, 0x45, 0x4c, 0x6e, 0x0a, 0xcc, 0xc2, 0x0c, 0x90, 0xfc, 0x50, 0x00, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe5, 0x14, 0xe2, 0x45, 0x48, 0x6e, + 0xc2, 0x0c, 0x06, 0x94, 0x51, 0x00, 0x00, 0x31, 0x18, 0x00, 0xb0, 0xfc, + 0x50, 0x00, 0x20, 0x31, 0x1a, 0x00, 0xd0, 0x09, 0x51, 0x0a, 0x48, 0x0c, + 0x63, 0xd0, 0x88, 0x00, 0x63, 0x70, 0x88, 0x00, 0x69, 0x00, 0x58, 0x10, + 0x86, 0xef, 0x43, 0x2e, 0x62, 0x0c, 0x84, 0x70, 0x03, 0x00, 0x47, 0x0c, + 0x80, 0x00, 0x18, 0x10, 0xba, 0x05, 0xa6, 0x05, 0xb3, 0x09, 0xba, 0x2d, + 0x03, 0xb4, 0xbd, 0xff, 0x01, 0xed, 0x66, 0xfc, 0x20, 0x01, 0x83, 0xb0, + 0x02, 0x00, 0xe4, 0x40, 0xb6, 0xff, 0x86, 0xfc, 0x28, 0x01, 0x44, 0xb4, + 0xb2, 0xff, 0x00, 0x0c, 0x9d, 0x34, 0x10, 0x00, 0x40, 0x0c, 0x44, 0xd1, + 0x88, 0x00, 0x4a, 0x71, 0x88, 0x00, 0x84, 0xd0, 0x00, 0x03, 0x84, 0x70, + 0x00, 0x03, 0x49, 0x01, 0x58, 0x40, 0x80, 0x00, 0x18, 0x38, 0x05, 0x01, + 0x50, 0x29, 0xfa, 0x06, 0x53, 0x0a, 0x8a, 0xe9, 0x4d, 0x26, 0xc2, 0x25, + 0xc6, 0x05, 0xb4, 0x25, 0xc6, 0x05, 0x63, 0x30, 0x30, 0x01, 0x3c, 0x07, + 0x94, 0xcf, 0x0c, 0xeb, 0x90, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xdf, 0x14, 0xe2, 0x45, 0x42, 0x6e, 0xae, 0xcf, 0xc2, 0x0c, + 0x88, 0xcf, 0x01, 0xed, 0x90, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0xe5, 0x14, 0xe2, 0x45, 0x42, 0x6e, 0xa2, 0xcf, 0xc2, 0x0c, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe5, 0x14, 0xc2, 0x45, 0x84, 0x30, + 0x0a, 0x00, 0x99, 0xcf, 0xc2, 0x0c, 0x00, 0x0c, 0xf1, 0x4f, 0xa0, 0xed, + 0x55, 0x45, 0x64, 0x94, 0x5c, 0x00, 0x05, 0x0e, 0x9d, 0xed, 0x64, 0x94, + 0x6b, 0x00, 0x9e, 0xed, 0x64, 0x94, 0x7b, 0x00, 0x86, 0xed, 0x64, 0x94, + 0x07, 0x00, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0xed, 0x8b, 0x15, 0x45, + 0x99, 0x45, 0x11, 0x4c, 0x45, 0x60, 0x17, 0x00, 0xc5, 0x60, 0x1b, 0x00, + 0xa4, 0x41, 0x04, 0x80, 0x45, 0x60, 0x14, 0x10, 0xc5, 0x60, 0x18, 0x10, + 0x84, 0x30, 0x20, 0x0f, 0x62, 0x0c, 0x26, 0x25, 0x34, 0x05, 0x26, 0x25, + 0x35, 0x05, 0xb1, 0x41, 0x04, 0x80, 0xa4, 0xfc, 0x5c, 0x02, 0x31, 0x32, + 0xe8, 0x02, 0x26, 0x25, 0x22, 0x05, 0xc2, 0xf8, 0x18, 0x01, 0xa2, 0x41, + 0x08, 0x80, 0xd0, 0x6d, 0x42, 0x30, 0xfb, 0x19, 0xc2, 0x45, 0x64, 0xf8, + 0x5c, 0x02, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, 0x54, 0xaf, 0xe2, 0x45, + 0x90, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x61, 0x14, 0xe2, 0x45, + 0x00, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x0b, 0x13, 0xe2, 0x45, + 0x00, 0x0c, 0x03, 0xad, 0x07, 0xef, 0x15, 0x45, 0x08, 0x47, 0x04, 0xed, + 0x51, 0xf8, 0x60, 0x0b, 0xa2, 0x41, 0x08, 0x80, 0x88, 0xee, 0x42, 0x30, + 0x1d, 0x19, 0xc2, 0x45, 0x80, 0x30, 0xb8, 0x0b, 0xb9, 0x41, 0x08, 0x80, + 0x39, 0x33, 0xe7, 0x15, 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0x30, 0x7d, 0x80, 0xe2, 0x45, 0x5a, 0x6e, 0xa2, 0x41, + 0x09, 0x80, 0x42, 0xfc, 0x54, 0xaf, 0xe2, 0x45, 0x90, 0x0c, 0xb9, 0x41, + 0x08, 0x80, 0x39, 0x33, 0x61, 0x14, 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0x45, 0x14, 0x15, 0x00, 0x85, 0x14, 0x14, 0x00, 0xa3, 0x41, 0x09, 0x80, + 0x20, 0x25, 0x63, 0xfc, 0x54, 0xaf, 0xd4, 0x44, 0xa4, 0x41, 0x04, 0x80, + 0x44, 0xf8, 0xf0, 0x08, 0xe3, 0x45, 0x85, 0x0c, 0xea, 0xcf, 0xb9, 0x41, + 0x08, 0x80, 0x85, 0x14, 0x14, 0x00, 0xa2, 0x41, 0x09, 0x80, 0x42, 0xfc, + 0x54, 0xaf, 0xa3, 0x41, 0x04, 0x80, 0x83, 0xf8, 0x84, 0x0e, 0xe2, 0x45, + 0x85, 0x0c, 0xdb, 0xcf, 0xb9, 0x41, 0x08, 0x80, 0xd9, 0x4f, 0xa2, 0x41, + 0x02, 0x80, 0x3d, 0x23, 0x28, 0xd0, 0x42, 0x30, 0xc1, 0xf1, 0xe2, 0x45, + 0x04, 0x0e, 0x50, 0x16, 0x2a, 0x01, 0x12, 0x94, 0x61, 0x00, 0xa2, 0x0e, + 0x50, 0x14, 0x17, 0x01, 0xac, 0x2d, 0x03, 0x94, 0x5f, 0x00, 0x62, 0x00, + 0x3c, 0x2b, 0x70, 0x14, 0x76, 0x00, 0x03, 0x94, 0x55, 0x00, 0x02, 0xee, + 0xa8, 0x2d, 0x03, 0x94, 0x5e, 0x00, 0x87, 0xc8, 0x50, 0x60, 0x29, 0x00, + 0x50, 0x60, 0x26, 0x10, 0x02, 0x94, 0x65, 0x00, 0x52, 0x00, 0x00, 0x28, + 0xb3, 0x41, 0x02, 0x80, 0x30, 0x32, 0x2a, 0x00, 0xd0, 0x33, 0x4c, 0x01, + 0xc0, 0x0e, 0x80, 0x0e, 0x40, 0x0e, 0x73, 0x32, 0xbd, 0x34, 0xa6, 0xca, + 0x09, 0xcc, 0x48, 0xc8, 0x50, 0x60, 0x29, 0x00, 0x50, 0x60, 0x26, 0x10, + 0x56, 0x00, 0x90, 0x13, 0x2e, 0x8d, 0xc8, 0x4f, 0x10, 0x29, 0xc2, 0x4e, + 0x75, 0x8d, 0x24, 0x4e, 0xf0, 0xfe, 0x3c, 0x01, 0x7e, 0xfc, 0x00, 0x00, + 0xd0, 0x14, 0x18, 0x01, 0xf7, 0x32, 0x08, 0x00, 0x77, 0x00, 0x50, 0xb9, + 0x57, 0x00, 0x50, 0xb9, 0x47, 0x48, 0x90, 0x14, 0x14, 0x01, 0xa6, 0x0c, + 0xf7, 0x0c, 0xd3, 0x45, 0x5d, 0xf8, 0x10, 0x00, 0x70, 0x34, 0x44, 0x01, + 0x52, 0x00, 0x50, 0x91, 0x48, 0x48, 0x43, 0x02, 0x50, 0x19, 0x43, 0x00, + 0x90, 0x1b, 0x8b, 0x8d, 0x97, 0x02, 0x50, 0xa1, 0x86, 0xca, 0x50, 0x60, + 0x29, 0x00, 0x50, 0x60, 0x26, 0x10, 0x56, 0x00, 0x90, 0x13, 0x54, 0xad, + 0xc8, 0x4f, 0x66, 0x48, 0xa3, 0x02, 0x90, 0x13, 0x43, 0x00, 0x18, 0xa8, + 0x55, 0x0c, 0x3d, 0x23, 0x28, 0x50, 0x14, 0x47, 0x03, 0x40, 0xa1, 0xff, + 0x62, 0xd0, 0x18, 0x00, 0xe3, 0x40, 0xf6, 0xff, 0x9e, 0xcf, 0x70, 0x14, + 0x76, 0x00, 0x26, 0x2d, 0x83, 0xed, 0x01, 0xee, 0x44, 0x00, 0x18, 0x18, + 0x67, 0xc8, 0x50, 0x60, 0x29, 0x00, 0x50, 0x60, 0x26, 0x10, 0x02, 0xb4, + 0x9f, 0xff, 0x52, 0x00, 0x00, 0x28, 0xdf, 0xcf, 0xa6, 0xca, 0x00, 0x0c, + 0xe1, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x8d, 0xc7, 0x3d, 0x23, + 0x18, 0xd0, 0x06, 0x0e, 0x24, 0x0e, 0xc2, 0x45, 0x44, 0x36, 0x50, 0x01, + 0x62, 0x0e, 0x50, 0x14, 0xc0, 0x00, 0x27, 0x2d, 0xe2, 0x40, 0x05, 0x00, + 0x50, 0x14, 0xc3, 0x00, 0x27, 0x2d, 0xa2, 0x40, 0x83, 0x00, 0x70, 0x14, + 0xc2, 0x00, 0x02, 0xed, 0x43, 0x94, 0x61, 0x00, 0x00, 0x0c, 0x70, 0x14, + 0xc5, 0x00, 0x43, 0x94, 0x5c, 0x00, 0x00, 0x0c, 0x70, 0x14, 0xcb, 0x00, + 0x43, 0x94, 0x59, 0x00, 0x00, 0x0c, 0x90, 0x14, 0xc8, 0x00, 0x44, 0x94, + 0x54, 0x00, 0x00, 0x0c, 0x13, 0x94, 0x68, 0x00, 0xa2, 0x41, 0x01, 0x80, + 0xb1, 0xfc, 0x50, 0x00, 0x01, 0xef, 0x09, 0x6e, 0x42, 0x30, 0x61, 0xda, + 0xe2, 0x45, 0xd8, 0x6e, 0x5d, 0x14, 0x10, 0x00, 0x27, 0x2d, 0x02, 0xb4, + 0x59, 0x00, 0x5d, 0x18, 0x10, 0x00, 0xa2, 0x41, 0xaa, 0x2a, 0x52, 0x32, + 0xe8, 0xff, 0x42, 0x50, 0xab, 0xaa, 0x52, 0x00, 0x3c, 0x8b, 0xb1, 0xfc, + 0x50, 0x00, 0x52, 0x02, 0x80, 0xf8, 0x02, 0x46, 0x42, 0x02, 0xd0, 0x91, + 0x92, 0x40, 0x46, 0x00, 0xdc, 0x6d, 0x52, 0x00, 0x00, 0x08, 0x42, 0x02, + 0x50, 0x91, 0x52, 0x02, 0x00, 0x08, 0x52, 0x32, 0x18, 0x00, 0x45, 0x02, + 0x50, 0x29, 0xc0, 0x30, 0xff, 0x0f, 0x81, 0xef, 0x00, 0x31, 0x03, 0x00, + 0x0b, 0xcc, 0xa9, 0x41, 0x05, 0x80, 0x90, 0xfc, 0x00, 0x01, 0x44, 0x94, + 0xa1, 0x00, 0x00, 0x0c, 0x6c, 0x4c, 0xa3, 0x94, 0x2c, 0x00, 0x53, 0x0c, + 0x31, 0x09, 0x30, 0x0a, 0x20, 0x25, 0xd4, 0x44, 0x42, 0xd0, 0xff, 0x0f, + 0x2e, 0x6e, 0x84, 0xb0, 0xd7, 0x07, 0xa4, 0x40, 0xec, 0xff, 0xc2, 0xb4, + 0xf0, 0xff, 0x6c, 0x4c, 0x74, 0x4c, 0x1b, 0xcc, 0x53, 0x0c, 0x70, 0x14, + 0xcb, 0x00, 0x91, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x01, 0x80, 0x63, 0x00, + 0x00, 0x68, 0x89, 0x6e, 0x84, 0x4c, 0x02, 0xef, 0x42, 0x30, 0x61, 0xda, + 0xc2, 0x45, 0x7d, 0x38, 0x10, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x81, 0xee, + 0x91, 0x0c, 0x42, 0x30, 0xd1, 0x19, 0xc2, 0x45, 0x00, 0x00, 0x90, 0x9a, + 0x53, 0x0c, 0x3d, 0x23, 0x18, 0x50, 0x10, 0x47, 0x50, 0x14, 0xc9, 0x00, + 0x27, 0x2d, 0xe2, 0x40, 0x78, 0xff, 0x50, 0x14, 0xc6, 0x00, 0x27, 0x2d, + 0x02, 0x94, 0x73, 0xff, 0x06, 0xed, 0x70, 0x14, 0xc2, 0x00, 0x43, 0x94, + 0x10, 0x00, 0x00, 0x0c, 0x70, 0x14, 0xc5, 0x00, 0x43, 0x94, 0x0b, 0x00, + 0x00, 0x0c, 0x70, 0x14, 0xcb, 0x00, 0x43, 0x94, 0x06, 0x00, 0x00, 0x0c, + 0x70, 0x14, 0xc8, 0x00, 0x43, 0xb4, 0x74, 0xff, 0x00, 0x0c, 0xa2, 0x41, + 0x08, 0x80, 0x91, 0x0c, 0x81, 0xee, 0x42, 0x30, 0xd1, 0x19, 0xb2, 0x41, + 0x08, 0x80, 0xc2, 0x45, 0xb1, 0x41, 0x04, 0x80, 0xd0, 0x33, 0xa8, 0x00, + 0xf0, 0x32, 0xc0, 0x00, 0xd0, 0x32, 0x58, 0x00, 0xa0, 0x0e, 0x52, 0x32, + 0x17, 0x19, 0x31, 0x32, 0x20, 0x0f, 0x80, 0x32, 0x01, 0x00, 0x60, 0x32, + 0x04, 0x00, 0x50, 0xfc, 0xd4, 0x00, 0x9e, 0x1a, 0x00, 0x00, 0x97, 0x14, + 0x00, 0x00, 0xb5, 0x0c, 0x1c, 0xef, 0x47, 0x2e, 0x44, 0x00, 0x10, 0x22, + 0xc2, 0x4f, 0x96, 0xf8, 0x00, 0x00, 0x57, 0x14, 0x01, 0x00, 0xe6, 0x4e, + 0xa7, 0x2d, 0x29, 0x25, 0x76, 0xf8, 0x28, 0x00, 0xd2, 0x45, 0x56, 0xf8, + 0x3c, 0x00, 0x55, 0x30, 0x69, 0x00, 0x26, 0x25, 0x22, 0x05, 0xa1, 0x69, + 0xa2, 0x6a, 0xa2, 0x4e, 0x30, 0x6e, 0x64, 0x00, 0x90, 0x1b, 0xd6, 0x05, + 0xc8, 0x4e, 0x21, 0xea, 0x75, 0xb6, 0xd9, 0xff, 0xa2, 0xe9, 0x90, 0x14, + 0xc2, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x07, 0xef, 0x83, 0xee, 0x42, 0x30, + 0x1d, 0x19, 0xc2, 0x45, 0x84, 0x00, 0x00, 0x68, 0x8f, 0xcf, 0x60, 0x0e, + 0x01, 0x69, 0xe2, 0xb4, 0x5d, 0xff, 0x00, 0x0c, 0x50, 0xfc, 0x48, 0x00, + 0xe2, 0xb4, 0x58, 0xff, 0x00, 0x0c, 0x35, 0x09, 0x82, 0x00, 0xac, 0x10, + 0x04, 0x94, 0x52, 0xff, 0x23, 0x2d, 0x02, 0x95, 0x04, 0x00, 0x00, 0x0c, + 0x4d, 0xcf, 0x09, 0x18, 0x38, 0x95, 0x4a, 0xcf, 0x09, 0x19, 0x38, 0x95, + 0xf1, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x55, 0x45, 0x42, 0x30, 0x41, 0x30, + 0x27, 0x0e, 0xe2, 0x45, 0x05, 0x0e, 0x71, 0x14, 0x7d, 0x00, 0x01, 0xed, + 0x43, 0x94, 0x03, 0x00, 0x00, 0x0c, 0x15, 0x45, 0x08, 0x47, 0x7d, 0x8c, + 0xa2, 0x41, 0x05, 0x80, 0x71, 0xfc, 0xf8, 0x01, 0xe2, 0x14, 0x38, 0x95, + 0xa2, 0x41, 0x03, 0x00, 0x42, 0x50, 0x00, 0x80, 0x9a, 0x44, 0xa4, 0x41, + 0x03, 0x00, 0x03, 0xef, 0x00, 0x31, 0x3c, 0x00, 0x05, 0xcc, 0x40, 0x0c, + 0x20, 0x6d, 0x02, 0x96, 0xe8, 0xff, 0x00, 0x0c, 0x83, 0xb4, 0xfa, 0xff, + 0x00, 0x0c, 0xc7, 0xb4, 0xf7, 0xff, 0xa2, 0x30, 0x82, 0x00, 0xd4, 0x26, + 0xd2, 0x06, 0xf2, 0xcf, 0x05, 0x19, 0x06, 0x00, 0xf5, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0xe1, 0x2f, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, 0xe8, 0x02, 0x62, 0xfc, 0x28, 0x02, + 0xa4, 0x41, 0x44, 0x00, 0x84, 0x50, 0x21, 0xaa, 0x83, 0x00, 0x90, 0x1b, + 0x86, 0xad, 0xa3, 0x41, 0x29, 0x01, 0x63, 0x50, 0xe0, 0x8b, 0x62, 0xf8, + 0x28, 0x02, 0x62, 0xfc, 0x60, 0x04, 0xa4, 0x41, 0x44, 0x00, 0x84, 0x50, + 0x21, 0xaa, 0x83, 0x00, 0x90, 0x1b, 0x88, 0xad, 0xe5, 0x4b, 0xa3, 0x41, + 0x29, 0x01, 0x63, 0x50, 0xe0, 0x8b, 0x62, 0xf8, 0x60, 0x04, 0xe5, 0x4b, + 0x06, 0x47, 0x00, 0x0c, 0xbf, 0x45, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x02, 0x80, 0x42, 0x30, 0x69, 0xfd, 0x75, 0x45, 0x24, 0x0e, 0xe2, 0x45, + 0x46, 0x0e, 0x02, 0x0e, 0x01, 0xed, 0x50, 0x94, 0x04, 0x00, 0x00, 0x0c, + 0x50, 0x0c, 0x35, 0x45, 0x0a, 0x47, 0x52, 0xfe, 0x00, 0x00, 0x12, 0x94, + 0xf9, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x91, 0xfc, 0x50, 0x00, 0x42, 0x30, + 0x9b, 0x13, 0xe2, 0x45, 0x42, 0x6e, 0x2c, 0xad, 0x60, 0x30, 0x88, 0x00, + 0x51, 0x34, 0x20, 0x00, 0x42, 0xd0, 0x8c, 0x00, 0x62, 0xb4, 0xe9, 0xff, + 0x50, 0x0c, 0xb3, 0x41, 0x04, 0x80, 0x73, 0x32, 0xe8, 0x02, 0x53, 0x14, + 0xc0, 0x0b, 0x61, 0xad, 0x50, 0x0c, 0xa2, 0x41, 0x08, 0x80, 0x82, 0x86, + 0x42, 0x30, 0xc1, 0x14, 0xe2, 0x45, 0x00, 0x0c, 0x28, 0x2d, 0x57, 0x8d, + 0x50, 0x0c, 0x52, 0xfc, 0x10, 0x02, 0x52, 0xad, 0x04, 0xed, 0x53, 0xf8, + 0x60, 0x0b, 0xa2, 0x41, 0x08, 0x80, 0x07, 0xef, 0x88, 0xee, 0x42, 0x30, + 0x1d, 0x19, 0xc2, 0x45, 0x80, 0x30, 0xb8, 0x0b, 0xc6, 0xcf, 0x50, 0x0c, + 0x91, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, 0xb2, 0x30, 0x33, 0x00, + 0x42, 0x30, 0x65, 0x13, 0xe2, 0x45, 0x48, 0x6e, 0xb9, 0xcf, 0x40, 0x00, + 0x90, 0x83, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, 0x00, 0xa4, 0x75, 0x45, + 0x02, 0xfe, 0x24, 0x2c, 0xb3, 0x41, 0x05, 0x80, 0x42, 0xfc, 0x28, 0x2c, + 0x33, 0x32, 0xd0, 0x94, 0x92, 0x69, 0xb2, 0x41, 0x04, 0x80, 0x52, 0x32, + 0xe8, 0x02, 0x10, 0x02, 0x2c, 0x98, 0x42, 0x00, 0x00, 0xa0, 0xd0, 0x44, + 0x92, 0xfc, 0x78, 0x0b, 0xb2, 0xfc, 0x7c, 0x0b, 0xd2, 0xfc, 0x80, 0x0b, + 0x35, 0x04, 0xa2, 0x41, 0x01, 0x80, 0x42, 0x30, 0xdd, 0xd5, 0xc2, 0x45, + 0xf2, 0xfc, 0x84, 0x0b, 0x50, 0x00, 0x10, 0x12, 0x98, 0x69, 0x62, 0x00, + 0x90, 0x23, 0x0b, 0x8e, 0x16, 0xe9, 0x27, 0x05, 0x62, 0xb0, 0xd0, 0x07, + 0x8d, 0x8d, 0x16, 0xe9, 0x53, 0xfc, 0xd0, 0x94, 0x20, 0x6d, 0x53, 0xf8, + 0xd0, 0x94, 0x40, 0x0c, 0x60, 0x0c, 0x51, 0x20, 0x08, 0x90, 0x18, 0xe8, + 0x35, 0x45, 0x0a, 0x47, 0xb0, 0x41, 0x08, 0x80, 0x04, 0xed, 0x10, 0x32, + 0x1d, 0x19, 0x07, 0xef, 0x88, 0xee, 0x80, 0x30, 0x88, 0x13, 0xd0, 0x45, + 0x52, 0xf8, 0x60, 0x0b, 0x16, 0x6a, 0x07, 0xef, 0x81, 0xee, 0xd0, 0x45, + 0x84, 0x30, 0x30, 0xf8, 0x40, 0x0c, 0x60, 0x0c, 0x51, 0x20, 0x08, 0x90, + 0x18, 0xe8, 0x35, 0x45, 0x0a, 0x47, 0x00, 0x0c, 0xa2, 0x41, 0x04, 0x80, + 0x62, 0x14, 0xa8, 0x0e, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0xd0, 0x94, + 0x00, 0x85, 0xc2, 0x20, 0x08, 0x90, 0x92, 0xad, 0xa3, 0x41, 0x00, 0xa4, + 0xc3, 0xfc, 0x24, 0x2c, 0x63, 0xfc, 0x28, 0x2c, 0x28, 0xea, 0xe6, 0x00, + 0x2c, 0x98, 0x63, 0x00, 0x2c, 0x98, 0xc3, 0x00, 0x00, 0xa0, 0xf7, 0x44, + 0x63, 0x00, 0x40, 0x60, 0x22, 0xeb, 0xa3, 0xe9, 0xb9, 0x41, 0x02, 0x80, + 0x39, 0x33, 0x0d, 0x1d, 0xb9, 0x45, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x29, 0x6e, 0x44, 0x45, 0xe2, 0x45, 0x00, 0x0c, + 0xa2, 0x41, 0x04, 0x80, 0x42, 0x14, 0xa8, 0x0e, 0x04, 0x8d, 0xa2, 0x41, + 0x08, 0x80, 0x04, 0x45, 0x06, 0x47, 0x42, 0x30, 0xcf, 0x12, 0xe2, 0x45, + 0x00, 0x0c, 0x79, 0x8d, 0xa2, 0x41, 0x04, 0x80, 0x62, 0x30, 0xb4, 0x1a, + 0x63, 0x60, 0x03, 0x00, 0x82, 0x30, 0xb4, 0x1a, 0x64, 0x60, 0x00, 0x10, + 0xa8, 0x8d, 0xa3, 0x41, 0x05, 0x80, 0xa2, 0x41, 0x00, 0xa4, 0x42, 0xfc, + 0x04, 0x2c, 0x22, 0x2d, 0x1b, 0x8d, 0xb9, 0x41, 0x04, 0x80, 0xb0, 0x41, + 0x05, 0x80, 0x10, 0x32, 0xd0, 0x94, 0x01, 0x69, 0x88, 0xee, 0x20, 0x6d, + 0x01, 0xe9, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x23, 0x19, 0xe2, 0x45, + 0x80, 0x0c, 0x50, 0x20, 0x08, 0x10, 0xd3, 0x44, 0x52, 0x8d, 0xb9, 0x41, + 0x04, 0x80, 0x39, 0x33, 0x61, 0x7a, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, + 0x39, 0x33, 0xc9, 0x59, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0x43, 0x30, + 0xd0, 0x94, 0x03, 0xf8, 0xd0, 0x94, 0x21, 0xe8, 0x22, 0xe8, 0x23, 0xe8, + 0x24, 0xe8, 0x25, 0xe8, 0x26, 0xe8, 0x27, 0xe8, 0x28, 0xe8, 0xcd, 0xcf, + 0x29, 0xe8, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0x1d, 0xf0, 0x66, 0x45, 0xc2, 0x45, 0x1d, 0xf8, 0x10, 0x00, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0xcf, 0x12, 0xe2, 0x45, 0x00, 0x0c, 0x09, 0x8d, + 0xb0, 0x41, 0x04, 0x80, 0x10, 0x32, 0xe8, 0x02, 0x50, 0x14, 0xc0, 0x0b, + 0x04, 0x8d, 0xa2, 0x41, 0x08, 0x80, 0x26, 0x45, 0x0a, 0x47, 0x42, 0x30, + 0x85, 0x14, 0xe2, 0x45, 0x00, 0x0c, 0xa6, 0x24, 0xa2, 0x04, 0x96, 0x24, + 0xa3, 0x04, 0x96, 0x24, 0x90, 0x04, 0x51, 0xfe, 0x1c, 0x01, 0x01, 0xed, + 0x52, 0xb4, 0xef, 0xff, 0x00, 0x0c, 0x50, 0xfc, 0x60, 0x0b, 0x42, 0x96, + 0xea, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x8b, 0x14, 0x89, 0x6e, + 0xe2, 0x45, 0x01, 0xee, 0x71, 0xfc, 0x20, 0x01, 0x02, 0xed, 0x43, 0x94, + 0x1b, 0x00, 0x04, 0xed, 0x50, 0xfc, 0x68, 0x0b, 0x64, 0x48, 0x62, 0x00, + 0x90, 0x13, 0x57, 0x8d, 0x04, 0xed, 0x50, 0xf8, 0x60, 0x0b, 0xa2, 0x41, + 0x08, 0x80, 0x07, 0xef, 0x88, 0xee, 0x42, 0x30, 0x1d, 0x19, 0xc2, 0x45, + 0x80, 0x30, 0xb8, 0x0b, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xe7, 0x15, + 0xe2, 0x45, 0x00, 0x0c, 0xc4, 0xcf, 0x00, 0x0c, 0x50, 0xf8, 0x60, 0x0b, + 0xe3, 0xcf, 0x51, 0xfa, 0x4c, 0x02, 0x00, 0x0c, 0xb9, 0x4f, 0x3d, 0x23, + 0x68, 0xd0, 0x14, 0xc8, 0x04, 0x0e, 0x25, 0x0e, 0x16, 0xc8, 0x17, 0xc8, + 0x00, 0x00, 0x7c, 0x47, 0x00, 0x00, 0x00, 0x18, 0x5c, 0xfc, 0xec, 0x81, + 0xb6, 0x41, 0x04, 0x80, 0xd6, 0x32, 0x20, 0x0f, 0x62, 0x0c, 0x56, 0xfc, + 0x58, 0x01, 0xb2, 0x41, 0x08, 0x80, 0x79, 0xc8, 0x20, 0x6d, 0x56, 0xf8, + 0x58, 0x01, 0xa2, 0x41, 0x03, 0x80, 0xb0, 0x6d, 0x92, 0x30, 0xc8, 0x45, + 0x42, 0x30, 0xc9, 0xd0, 0x7c, 0xf8, 0xec, 0x81, 0xe2, 0x45, 0x00, 0x0c, + 0x02, 0x94, 0x6c, 0x01, 0xa2, 0x0c, 0xe2, 0x0e, 0xa2, 0x41, 0x03, 0x80, + 0x42, 0x30, 0xe5, 0xd0, 0xc2, 0x45, 0x92, 0x30, 0xc8, 0x45, 0xb3, 0x41, + 0x01, 0x80, 0x01, 0xed, 0x73, 0x32, 0x61, 0xda, 0xb0, 0x0c, 0x2f, 0x6e, + 0x03, 0xef, 0x37, 0xfa, 0x10, 0x00, 0xd3, 0x45, 0x57, 0xf8, 0x1c, 0x00, + 0x5c, 0xfc, 0xd4, 0xa8, 0xd7, 0x4b, 0x03, 0xef, 0xb0, 0x30, 0x03, 0x00, + 0x97, 0x30, 0x18, 0x00, 0xd3, 0x45, 0x5e, 0x00, 0x50, 0xf1, 0x2f, 0x6e, + 0x03, 0xef, 0xd3, 0x45, 0xb0, 0x30, 0x06, 0x00, 0x37, 0x4a, 0xb2, 0x41, + 0x05, 0x80, 0x18, 0xef, 0xbe, 0x0c, 0x92, 0x30, 0x18, 0x96, 0xd3, 0x45, + 0x17, 0xf8, 0x0c, 0x00, 0x51, 0xb0, 0x15, 0x00, 0x02, 0xb4, 0xcf, 0x00, + 0xb4, 0x41, 0x02, 0x80, 0x54, 0x30, 0x85, 0xc3, 0xb0, 0x41, 0x04, 0x80, + 0x10, 0x32, 0xe8, 0x02, 0x46, 0xcc, 0x58, 0xc8, 0x96, 0x48, 0x64, 0xb0, + 0x05, 0x00, 0x03, 0xb4, 0x77, 0x00, 0x74, 0x00, 0x3c, 0x2b, 0x03, 0x40, + 0x1f, 0x01, 0x00, 0x0c, 0x74, 0xd0, 0x40, 0x00, 0xe3, 0x40, 0x05, 0x00, + 0x76, 0xfc, 0x80, 0x01, 0xb0, 0x6d, 0x76, 0xf8, 0x80, 0x01, 0x77, 0xfc, + 0x0c, 0x00, 0x76, 0xfd, 0x68, 0x01, 0x89, 0x6e, 0x03, 0x31, 0x14, 0x00, + 0xc3, 0x30, 0xa8, 0x00, 0x08, 0x01, 0x00, 0x10, 0x62, 0x27, 0x65, 0x00, + 0x50, 0x61, 0x3e, 0x31, 0x18, 0x00, 0x98, 0x4c, 0x62, 0x4d, 0x17, 0x01, + 0x50, 0x41, 0xd7, 0x00, 0x50, 0x31, 0xb0, 0x6d, 0x76, 0xf9, 0x68, 0x01, + 0x8c, 0x1a, 0x00, 0x00, 0x28, 0xf9, 0x00, 0x00, 0x60, 0xaa, 0x02, 0x94, + 0x8c, 0x00, 0x77, 0xf8, 0x0c, 0x00, 0x56, 0xfc, 0x70, 0x01, 0x20, 0x6d, + 0x56, 0xf8, 0x70, 0x01, 0x40, 0xed, 0x43, 0x94, 0x52, 0x00, 0xbe, 0x02, + 0x50, 0xf1, 0x51, 0xb0, 0x15, 0x00, 0x02, 0xb4, 0x86, 0x00, 0x5c, 0xfc, + 0xa8, 0xa7, 0x04, 0xef, 0xbe, 0x0c, 0xf3, 0x45, 0x2d, 0x6e, 0x56, 0x48, + 0xa2, 0x32, 0x19, 0x00, 0xb1, 0x02, 0x90, 0x1b, 0x03, 0xb4, 0x75, 0x00, + 0x62, 0xb0, 0x04, 0x00, 0x03, 0xb4, 0x71, 0x00, 0x5e, 0x00, 0x50, 0x11, + 0x82, 0x16, 0x18, 0x00, 0x58, 0x48, 0x92, 0x30, 0x18, 0x96, 0xc2, 0x45, + 0xb1, 0x02, 0xd0, 0x89, 0x70, 0xfc, 0x94, 0x0b, 0x50, 0x0d, 0x83, 0xb0, + 0x0a, 0x00, 0x05, 0xae, 0x23, 0x31, 0x01, 0x00, 0x20, 0x31, 0x01, 0x00, + 0x60, 0x0c, 0x92, 0x30, 0x18, 0x96, 0xc4, 0x14, 0x13, 0x00, 0x04, 0x15, + 0x04, 0x00, 0xb0, 0x05, 0x94, 0xd0, 0x01, 0x00, 0xc3, 0x18, 0x88, 0x0b, + 0x30, 0xf9, 0x94, 0x0b, 0xd7, 0xf8, 0x44, 0x00, 0x04, 0xb4, 0x86, 0xff, + 0x17, 0x19, 0x4d, 0x00, 0xe2, 0x40, 0x3b, 0x00, 0x56, 0xfc, 0x74, 0x01, + 0x20, 0x6d, 0x56, 0xf8, 0x74, 0x01, 0x56, 0xfc, 0x6c, 0x01, 0x77, 0xfc, + 0x0c, 0x00, 0x20, 0x6d, 0x56, 0xf8, 0x6c, 0x01, 0x40, 0xed, 0x43, 0xb4, + 0xb2, 0xff, 0xbe, 0x02, 0x50, 0xf1, 0x5c, 0xfc, 0xa8, 0xa7, 0xa0, 0x6d, + 0x57, 0xf8, 0x14, 0x00, 0x4a, 0xfc, 0xd4, 0x04, 0x02, 0x94, 0x40, 0x00, + 0x7c, 0xf8, 0xa8, 0xa7, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xcb, 0x19, + 0xe2, 0x45, 0x97, 0x0c, 0x79, 0x48, 0x5c, 0xfc, 0xe8, 0x81, 0x7c, 0xf8, + 0xec, 0x81, 0xa2, 0x40, 0x0e, 0x00, 0x5c, 0xfc, 0xec, 0x81, 0xa2, 0x40, + 0x0a, 0x00, 0xfa, 0x40, 0x04, 0x00, 0x5a, 0xfc, 0xa0, 0x00, 0xa2, 0x40, + 0x04, 0x00, 0x00, 0x00, 0x7c, 0x57, 0x00, 0x00, 0x00, 0x18, 0x3d, 0x23, + 0x68, 0x50, 0x9f, 0x45, 0x49, 0x4c, 0x56, 0xfc, 0xa0, 0x01, 0x20, 0x6d, + 0xc6, 0xcf, 0x56, 0xf8, 0xa0, 0x01, 0x56, 0xfc, 0x78, 0x01, 0x20, 0x6d, + 0x77, 0xcf, 0x56, 0xf8, 0x78, 0x01, 0x77, 0xfc, 0x0c, 0x00, 0x5c, 0xfc, + 0xa8, 0xa7, 0x20, 0x6e, 0x9c, 0xf8, 0xa8, 0xa7, 0xcd, 0x8d, 0x57, 0xf8, + 0x14, 0x00, 0xaa, 0x41, 0x04, 0x80, 0x4a, 0x31, 0xe8, 0x02, 0x4a, 0xfc, + 0xd4, 0x04, 0x46, 0xad, 0xa2, 0x41, 0x08, 0x80, 0xb7, 0xfc, 0x50, 0x00, + 0x97, 0x30, 0x20, 0x00, 0xf3, 0x45, 0x02, 0xef, 0x57, 0x34, 0x20, 0x00, + 0x60, 0x30, 0x94, 0x00, 0x82, 0xd0, 0xbc, 0x00, 0x64, 0x94, 0x4e, 0x00, + 0x42, 0xd0, 0xfc, 0x00, 0x60, 0x30, 0xe4, 0x00, 0x62, 0x94, 0x5b, 0x00, + 0xa2, 0x41, 0x08, 0x80, 0xab, 0x6e, 0xf2, 0x30, 0x18, 0x96, 0x29, 0x6f, + 0x42, 0x30, 0x2b, 0x14, 0xe2, 0x45, 0x97, 0x0c, 0xb5, 0x48, 0x05, 0xb4, + 0x45, 0x00, 0xa3, 0x41, 0x08, 0x80, 0x77, 0x34, 0x20, 0x00, 0x24, 0xee, + 0x63, 0xd0, 0xfc, 0x00, 0x83, 0x94, 0x66, 0x00, 0xd4, 0x48, 0x81, 0xed, + 0x62, 0xb4, 0x96, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x57, 0x34, 0x20, 0x00, + 0x42, 0xd0, 0x00, 0x40, 0x02, 0x94, 0x50, 0x00, 0x08, 0xed, 0x5d, 0x1c, + 0x10, 0x00, 0x02, 0x40, 0x87, 0xff, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xc7, 0x14, 0xe2, 0x45, 0x97, 0x0c, 0x02, 0xb4, 0x57, 0x00, 0x0a, 0xed, + 0x77, 0xfc, 0x28, 0x00, 0x43, 0xb4, 0x42, 0x00, 0xa2, 0x41, 0x08, 0x80, + 0x56, 0x34, 0xc4, 0x01, 0x20, 0x6d, 0x74, 0xcf, 0x56, 0x38, 0xc4, 0x01, + 0x76, 0xfc, 0x7c, 0x01, 0xb0, 0x6d, 0xde, 0xce, 0x76, 0xf8, 0x7c, 0x01, + 0x56, 0xfc, 0xb8, 0x01, 0x20, 0x6d, 0x6e, 0xcf, 0x56, 0xf8, 0xb8, 0x01, + 0xa2, 0x41, 0x08, 0x80, 0xb2, 0x30, 0x18, 0x96, 0x42, 0x30, 0xb3, 0x16, + 0xe2, 0x45, 0x97, 0x0c, 0x64, 0xcf, 0x79, 0x48, 0xdd, 0x2e, 0x97, 0x0c, + 0x63, 0x30, 0xd1, 0x19, 0xc3, 0x45, 0x5d, 0xf8, 0x60, 0x00, 0xb5, 0xcf, + 0x58, 0x48, 0x97, 0xfc, 0x50, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0xe5, 0x14, 0xc2, 0x45, 0x84, 0x30, 0x0a, 0x00, 0x02, 0x94, 0x48, 0xff, + 0x57, 0xf8, 0xd8, 0x01, 0xa2, 0x41, 0x08, 0x80, 0x82, 0xee, 0x42, 0x30, + 0xd1, 0x19, 0xe2, 0x45, 0x97, 0x0c, 0x40, 0xcf, 0xa2, 0x41, 0x08, 0x80, + 0x57, 0xf8, 0x28, 0x00, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0xa1, 0x13, + 0xe2, 0x45, 0x97, 0x0c, 0x3a, 0xcf, 0x79, 0x48, 0xa2, 0x41, 0x08, 0x80, + 0xb2, 0x30, 0x18, 0x96, 0x42, 0x30, 0xd1, 0x16, 0xe2, 0x45, 0x97, 0x0c, + 0x93, 0xcf, 0x81, 0xed, 0x77, 0xfc, 0x28, 0x00, 0x43, 0xb4, 0x24, 0xff, + 0x00, 0x0c, 0xac, 0xcf, 0x56, 0x34, 0xc4, 0x01, 0xa4, 0x0c, 0xb9, 0x41, + 0x01, 0x80, 0xa4, 0x41, 0x05, 0x80, 0x44, 0xef, 0x39, 0x33, 0x61, 0xda, + 0x99, 0x45, 0x84, 0x30, 0x40, 0x95, 0x00, 0x0c, 0xa2, 0x41, 0x01, 0xa4, + 0x81, 0xed, 0x42, 0x50, 0x10, 0xb0, 0xa0, 0xe9, 0xa4, 0x41, 0x00, 0xa4, + 0x44, 0xfc, 0xc8, 0x2d, 0xa3, 0x41, 0x02, 0xa5, 0xb9, 0x41, 0x04, 0x80, + 0x42, 0x50, 0x40, 0x00, 0x44, 0xf8, 0xc8, 0x2d, 0xa2, 0x41, 0x00, 0xa5, + 0x80, 0x30, 0x00, 0x1e, 0x82, 0xf8, 0xd4, 0x3c, 0xa2, 0x41, 0x05, 0x00, + 0x42, 0x50, 0x00, 0xab, 0x43, 0xf8, 0x34, 0x0d, 0x39, 0x33, 0x29, 0x51, + 0x03, 0xf8, 0x18, 0x0d, 0xb9, 0x45, 0x00, 0x0c, 0xf5, 0x4f, 0xa2, 0x41, + 0x03, 0x80, 0x42, 0x30, 0x85, 0x98, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, + 0xe5, 0x4b, 0xb9, 0x41, 0x04, 0x80, 0x39, 0x33, 0x29, 0x51, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xf1, 0x4f, 0x43, 0xe8, 0x51, 0x69, 0x89, 0xed, + 0x7d, 0x38, 0x0a, 0x00, 0x22, 0x25, 0x51, 0xe9, 0x61, 0x69, 0x8f, 0xed, + 0x7d, 0x38, 0x0c, 0x00, 0x22, 0x25, 0x61, 0xe9, 0x52, 0x69, 0x60, 0x30, + 0xfa, 0xff, 0xab, 0x41, 0xff, 0x01, 0x24, 0x25, 0x52, 0xe9, 0x62, 0x69, + 0xaa, 0x41, 0xff, 0x00, 0x7d, 0x38, 0x02, 0x00, 0x24, 0x25, 0x62, 0xe9, + 0x25, 0xfd, 0x00, 0x00, 0xe0, 0x0c, 0x7d, 0x20, 0x14, 0xd0, 0x49, 0x00, + 0x80, 0xf8, 0x22, 0x01, 0x10, 0x1b, 0x1d, 0x0f, 0xfd, 0x31, 0x08, 0x00, + 0xc4, 0x0d, 0x40, 0x0e, 0xa0, 0x0d, 0x6b, 0x51, 0x25, 0xc0, 0x4a, 0x51, + 0x00, 0xc0, 0x81, 0xec, 0x02, 0xec, 0x20, 0x33, 0x03, 0x00, 0x1d, 0x38, + 0x00, 0x00, 0x1d, 0x38, 0x04, 0x00, 0x1d, 0x38, 0x08, 0x00, 0x87, 0x40, + 0x8d, 0x00, 0xa7, 0x05, 0x43, 0x01, 0x50, 0x13, 0xe2, 0x40, 0xda, 0x00, + 0x03, 0xcc, 0x40, 0x0c, 0xe8, 0x40, 0x08, 0x00, 0x20, 0x6d, 0xb2, 0x25, + 0x42, 0x00, 0x3c, 0x3b, 0xe2, 0xb4, 0xf8, 0xff, 0x43, 0x01, 0x50, 0x43, + 0x52, 0x00, 0x50, 0x43, 0x08, 0x94, 0xba, 0x00, 0x63, 0x01, 0x50, 0x43, + 0x08, 0x94, 0x07, 0x00, 0x2e, 0x6d, 0x20, 0x6d, 0xb4, 0xcc, 0xe0, 0x69, + 0xa8, 0x40, 0x0b, 0x00, 0x2e, 0x6d, 0x42, 0x00, 0x3c, 0x3b, 0x63, 0x00, + 0x80, 0x08, 0x52, 0x00, 0x50, 0x63, 0x0c, 0xb4, 0xf5, 0xff, 0x63, 0x01, + 0x50, 0x43, 0xe0, 0x69, 0x03, 0x01, 0x80, 0xf8, 0x68, 0x00, 0x10, 0x1b, + 0x87, 0x40, 0xa9, 0x00, 0x03, 0x01, 0xd0, 0x19, 0x43, 0x01, 0x50, 0x43, + 0xe8, 0x40, 0xa3, 0x00, 0x03, 0xcc, 0x40, 0x0e, 0xec, 0x40, 0x0b, 0x00, + 0x12, 0x31, 0x01, 0x00, 0x48, 0x02, 0x3c, 0x3b, 0xb2, 0x25, 0xf2, 0x00, + 0x50, 0x43, 0x08, 0xb4, 0xf5, 0xff, 0x43, 0x01, 0x50, 0x63, 0x42, 0x02, + 0x50, 0x1b, 0x82, 0x8d, 0x12, 0x0d, 0x02, 0x0d, 0x2d, 0x96, 0x9e, 0x00, + 0x08, 0x01, 0x3c, 0x3b, 0x0d, 0x96, 0x92, 0x00, 0x00, 0x0c, 0x08, 0x31, + 0xf2, 0xff, 0xe8, 0x00, 0x3c, 0x3b, 0x87, 0x40, 0x5a, 0x00, 0xe0, 0x69, + 0x40, 0x0c, 0x20, 0x6d, 0x42, 0x00, 0x3c, 0x3b, 0x29, 0x01, 0x00, 0x08, + 0x47, 0xb4, 0xf9, 0xff, 0xb2, 0x25, 0x49, 0x30, 0x00, 0x10, 0xe9, 0x90, + 0x00, 0x00, 0xe2, 0x00, 0x18, 0x48, 0x43, 0x30, 0x00, 0x10, 0xe3, 0x90, + 0x00, 0x00, 0xa2, 0x4d, 0xe2, 0x00, 0x18, 0x18, 0x29, 0x01, 0x00, 0x60, + 0x69, 0x00, 0x50, 0x19, 0x4d, 0xd0, 0xff, 0xff, 0x6e, 0xf8, 0x00, 0x00, + 0xa2, 0x01, 0x3c, 0x3b, 0xd2, 0x6e, 0x04, 0x4f, 0xe4, 0x4d, 0x62, 0x6f, + 0x22, 0x97, 0x30, 0x00, 0xc8, 0x4d, 0x25, 0xfd, 0x00, 0x00, 0xef, 0x3c, + 0x00, 0x00, 0x58, 0x3e, 0x00, 0x00, 0x49, 0x00, 0x80, 0xf8, 0x22, 0x01, + 0x10, 0x1b, 0xc7, 0x40, 0x75, 0xff, 0xa7, 0x05, 0x52, 0x40, 0x52, 0x00, + 0x40, 0x0c, 0x63, 0x01, 0x50, 0x13, 0x02, 0x94, 0x8b, 0xff, 0x40, 0x0c, + 0xe0, 0x69, 0xe3, 0x00, 0x80, 0xf8, 0x5f, 0x44, 0xf7, 0x05, 0x63, 0x01, + 0x50, 0x43, 0x08, 0x94, 0x05, 0x00, 0xe0, 0x0c, 0xa6, 0xcf, 0x40, 0x0e, + 0xa8, 0x40, 0x2a, 0x00, 0xfe, 0x6f, 0x63, 0x00, 0x80, 0x08, 0xe7, 0x00, + 0x3c, 0x3b, 0x47, 0xb6, 0xf7, 0xff, 0x63, 0x01, 0x50, 0x43, 0x9b, 0xcf, + 0x42, 0x02, 0x50, 0x1b, 0x7d, 0x20, 0x14, 0x50, 0x08, 0x47, 0x07, 0x94, + 0xae, 0xff, 0xe0, 0x00, 0xd0, 0x39, 0x40, 0x0c, 0x20, 0x6d, 0x03, 0x01, + 0x40, 0xf8, 0x89, 0x01, 0x40, 0xf8, 0x42, 0x00, 0x3c, 0x3b, 0x68, 0x00, + 0x50, 0x19, 0x2c, 0x01, 0x50, 0x49, 0xe2, 0x00, 0x50, 0x43, 0x29, 0x01, + 0x80, 0x08, 0x08, 0xb4, 0xef, 0xff, 0x63, 0x00, 0x80, 0x08, 0x99, 0xcf, + 0x49, 0x30, 0x00, 0x10, 0x78, 0xcf, 0x47, 0x0e, 0xe0, 0x69, 0x03, 0x01, + 0x80, 0xf8, 0x68, 0x00, 0x10, 0x1b, 0x03, 0x01, 0xd0, 0x19, 0x43, 0x01, + 0x50, 0x43, 0xa8, 0x40, 0x5d, 0xff, 0x12, 0x40, 0xbe, 0xff, 0x00, 0x0c, + 0x68, 0xcf, 0x40, 0x0e, 0x31, 0xcf, 0x40, 0x0c, 0x64, 0xcf, 0x40, 0x0e, + 0x43, 0x69, 0x68, 0x00, 0x00, 0x20, 0x34, 0x05, 0x43, 0xe9, 0x69, 0xcf, + 0x25, 0xfd, 0x00, 0x00, 0x43, 0x69, 0x4c, 0x4c, 0x02, 0x01, 0x50, 0x11, + 0x43, 0xe9, 0x61, 0xcf, 0x25, 0xfd, 0x00, 0x00, 0xf1, 0x4f, 0x64, 0x45, + 0x24, 0x62, 0x03, 0x00, 0x04, 0x0e, 0xa2, 0x41, 0x03, 0x80, 0x30, 0x62, + 0x00, 0x10, 0x80, 0x30, 0x2c, 0x01, 0x42, 0x30, 0x65, 0xab, 0xe2, 0x45, + 0x47, 0x0e, 0x11, 0x94, 0x5d, 0x00, 0xb9, 0x41, 0x01, 0x80, 0x08, 0x09, + 0x82, 0x30, 0xdc, 0xff, 0x62, 0x30, 0x9c, 0xff, 0x84, 0x00, 0x3c, 0x2b, + 0x63, 0x00, 0x3c, 0x2b, 0xe4, 0x00, 0x80, 0xf8, 0xc3, 0x00, 0x80, 0xf8, + 0x42, 0x30, 0x5b, 0x00, 0x42, 0x00, 0x3c, 0x2b, 0x67, 0x44, 0x5e, 0x44, + 0xa2, 0x00, 0x80, 0xf8, 0x79, 0x06, 0xe7, 0x05, 0x55, 0x44, 0x84, 0x00, + 0x3c, 0x2b, 0x63, 0x00, 0x3c, 0x2b, 0x55, 0x05, 0x64, 0x00, 0x50, 0x2b, + 0xa0, 0x8e, 0x42, 0x00, 0x3c, 0x2b, 0x44, 0x00, 0x50, 0x13, 0x02, 0xb4, + 0x4b, 0x00, 0x39, 0x33, 0xf9, 0xf4, 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, + 0x0e, 0x00, 0xb9, 0x41, 0x01, 0x80, 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, + 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, + 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x39, 0x33, 0xf9, 0xf4, + 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x43, 0x00, 0x50, 0x13, 0x65, 0x8d, + 0xb9, 0x41, 0x01, 0x80, 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, 0x0d, 0x00, + 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, + 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, + 0x3c, 0x2b, 0x39, 0x33, 0xf9, 0xf4, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0x52, 0x14, 0x3d, 0x00, 0x72, 0x1c, 0x0b, 0x00, 0xa2, 0x00, 0xec, 0x01, + 0x82, 0x00, 0x00, 0xc8, 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, + 0xd2, 0x26, 0xa5, 0xd0, 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x39, 0x33, + 0xf9, 0xf4, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x52, 0x14, 0x3d, 0x00, + 0x72, 0x1c, 0x0c, 0x00, 0xa2, 0x00, 0xec, 0x01, 0x82, 0x00, 0x00, 0xc8, + 0xd0, 0x6e, 0x84, 0x00, 0x80, 0xc8, 0x38, 0x06, 0xd2, 0x26, 0xa5, 0xd0, + 0xfe, 0x00, 0x84, 0x00, 0x3c, 0x2b, 0x24, 0x45, 0x99, 0x45, 0x11, 0x4c, + 0xd5, 0x4f, 0x3d, 0x23, 0x30, 0xd0, 0x3f, 0x49, 0x9d, 0x22, 0x68, 0x10, + 0xdd, 0x22, 0x70, 0x10, 0x0f, 0x8e, 0xde, 0x4b, 0xb9, 0x41, 0x02, 0x80, + 0x39, 0x33, 0xfd, 0xa8, 0x9d, 0x22, 0x68, 0x90, 0xdd, 0x22, 0x70, 0x90, + 0xde, 0xcb, 0x3f, 0xc9, 0x3d, 0x23, 0x30, 0x50, 0x99, 0x45, 0x2d, 0x4c, + 0xb0, 0x41, 0x02, 0x80, 0x45, 0x0e, 0x66, 0x0e, 0x83, 0xee, 0xc0, 0x0c, + 0x01, 0xee, 0x10, 0x32, 0xa9, 0x95, 0x27, 0x0e, 0xd0, 0x45, 0x3d, 0xf9, + 0x28, 0x00, 0x2a, 0x49, 0xa2, 0x41, 0x02, 0x80, 0x6a, 0x84, 0x90, 0x87, + 0x42, 0x30, 0xfd, 0xa8, 0x29, 0xc9, 0x9d, 0x22, 0x10, 0x90, 0xdd, 0x22, + 0x18, 0x90, 0xc2, 0x45, 0xdd, 0xfb, 0x20, 0x00, 0x80, 0x0c, 0xc0, 0x0c, + 0xf0, 0x45, 0x83, 0xee, 0xa2, 0x41, 0x04, 0x80, 0x62, 0x30, 0xb4, 0x1a, + 0x63, 0x60, 0x03, 0x00, 0x82, 0x30, 0xb4, 0x1a, 0x64, 0x60, 0x00, 0x10, + 0xe3, 0x40, 0x03, 0x00, 0x3d, 0x23, 0x30, 0x50, 0x16, 0x47, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0xb9, 0x74, 0xe2, 0x45, 0x00, 0x0c, 0x81, 0xed, + 0xa2, 0x41, 0x05, 0x80, 0x62, 0x18, 0x3d, 0x95, 0x3d, 0x23, 0x30, 0x50, + 0x16, 0x47, 0x00, 0x0c, 0xc1, 0x4f, 0x9d, 0x22, 0x6c, 0xd0, 0xb3, 0x41, + 0x05, 0x80, 0x53, 0x14, 0x3d, 0x95, 0x04, 0x0e, 0x3d, 0xfe, 0x90, 0x00, + 0x23, 0x8d, 0x5d, 0xfe, 0xa0, 0x00, 0x45, 0xb0, 0x0f, 0x00, 0x42, 0x70, + 0x01, 0x00, 0x50, 0xc8, 0xa2, 0x41, 0x01, 0x80, 0x81, 0xed, 0x21, 0x6e, + 0x42, 0x30, 0xd9, 0x74, 0xbd, 0x18, 0x48, 0x00, 0xfd, 0x18, 0x4a, 0x00, + 0xf6, 0xc8, 0xbd, 0x20, 0x5c, 0x90, 0x11, 0xca, 0x3d, 0x1a, 0x49, 0x00, + 0x5d, 0x1a, 0x4b, 0x00, 0x7d, 0x18, 0x4c, 0x00, 0xc2, 0x45, 0x7d, 0x18, + 0x4d, 0x00, 0xf6, 0x48, 0xbd, 0x20, 0x5c, 0x10, 0x13, 0x18, 0x3d, 0x95, + 0x5d, 0xfc, 0xbc, 0x00, 0x24, 0xca, 0x4f, 0xc8, 0x5d, 0xfc, 0xb8, 0x00, + 0x48, 0xca, 0x4e, 0xc8, 0x5d, 0xfc, 0xb4, 0x00, 0x4d, 0xc8, 0x5d, 0xfc, + 0xb0, 0x00, 0x4c, 0xc8, 0x5d, 0x14, 0xac, 0x00, 0x4b, 0xc8, 0x5d, 0xfc, + 0xa8, 0x00, 0x4a, 0xc8, 0x5d, 0xfc, 0xa4, 0x00, 0x49, 0xc8, 0x5d, 0xfc, + 0x9c, 0x00, 0x47, 0xc8, 0x5d, 0xfc, 0x98, 0x00, 0x46, 0xc8, 0x5d, 0xfc, + 0x94, 0x00, 0x45, 0xc8, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, 0x49, 0xab, + 0xe2, 0x45, 0x90, 0x0c, 0x9d, 0x22, 0x6c, 0x50, 0x9f, 0x45, 0x41, 0x4c, + 0xe5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x1d, 0x23, 0x14, 0xd0, 0xa2, 0x36, + 0x42, 0x95, 0xb5, 0xd2, 0x0f, 0x00, 0x55, 0x30, 0xff, 0xff, 0x42, 0xb0, + 0x02, 0x00, 0x02, 0xb4, 0xc2, 0x00, 0x09, 0xed, 0xb5, 0x72, 0x03, 0x00, + 0x80, 0x32, 0x03, 0x00, 0xa0, 0x02, 0x18, 0x10, 0xa0, 0x02, 0x18, 0xa0, + 0xa2, 0x0e, 0x04, 0x94, 0xb0, 0x00, 0xb3, 0x41, 0x08, 0x80, 0xb2, 0x41, + 0x08, 0x80, 0xc4, 0x0e, 0x24, 0x32, 0x3c, 0x00, 0xe0, 0x0e, 0x00, 0x32, + 0xff, 0x3f, 0x73, 0x32, 0x43, 0x11, 0x11, 0xcc, 0x52, 0x32, 0x1f, 0x17, + 0x64, 0x94, 0x36, 0x00, 0x00, 0x0c, 0xc2, 0x00, 0x58, 0x28, 0xd3, 0x45, + 0xdc, 0xfc, 0x48, 0x81, 0xd2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0xc8, 0x4e, + 0xd1, 0x96, 0x2e, 0x00, 0x00, 0x0c, 0xb6, 0xfc, 0x00, 0x00, 0x40, 0x50, + 0x00, 0x90, 0x0f, 0xef, 0x51, 0x26, 0xa9, 0x05, 0x44, 0x00, 0x90, 0x13, + 0x84, 0xd0, 0xff, 0x3f, 0xf7, 0x30, 0x01, 0x00, 0x00, 0x31, 0x04, 0x09, + 0x04, 0x96, 0xeb, 0xff, 0x63, 0xd0, 0xff, 0x3f, 0x43, 0x00, 0x58, 0x20, + 0x44, 0x00, 0x2c, 0x1a, 0x60, 0x30, 0xd4, 0x09, 0xdd, 0x2e, 0xc2, 0x94, + 0xda, 0xff, 0xe7, 0xd2, 0xff, 0x00, 0x85, 0x02, 0xd0, 0x11, 0x2d, 0x2d, + 0x04, 0xb5, 0xce, 0xff, 0xc4, 0x70, 0xd8, 0x09, 0xa5, 0x02, 0xd0, 0x29, + 0xce, 0xcf, 0xdd, 0x2e, 0x85, 0x02, 0xd0, 0x29, 0xca, 0xcf, 0xdd, 0x2e, + 0x17, 0x94, 0x64, 0x00, 0x81, 0xed, 0xb4, 0x41, 0x05, 0x80, 0xb0, 0x41, + 0x05, 0x80, 0xb3, 0x41, 0x08, 0x80, 0xb2, 0x41, 0x08, 0x80, 0x94, 0x32, + 0x48, 0x95, 0x10, 0x32, 0x84, 0x95, 0x20, 0x32, 0xff, 0x3f, 0x73, 0x32, + 0x43, 0x11, 0x52, 0x32, 0x1f, 0x17, 0x54, 0xfc, 0x00, 0x00, 0x80, 0x50, + 0x00, 0x90, 0x88, 0x4e, 0xad, 0x2e, 0x21, 0x25, 0xc5, 0x05, 0x63, 0xd0, + 0xff, 0x3f, 0x82, 0x00, 0x90, 0x23, 0x42, 0xd0, 0xff, 0x3f, 0x82, 0x00, + 0x18, 0x18, 0x22, 0x96, 0x07, 0x00, 0x83, 0x0c, 0xd3, 0x45, 0xdc, 0xfc, + 0x48, 0x81, 0xd2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0x90, 0xb6, 0xe5, 0xff, + 0xa2, 0x41, 0x05, 0x80, 0x62, 0x14, 0x84, 0x95, 0x01, 0xed, 0x43, 0xb4, + 0x2b, 0x00, 0xa2, 0x41, 0x05, 0x80, 0x62, 0xfc, 0x88, 0x95, 0xa2, 0x41, + 0x00, 0xa4, 0x42, 0x50, 0x04, 0x99, 0xa0, 0xe9, 0xa3, 0x41, 0x05, 0x80, + 0x63, 0xfc, 0x8c, 0x95, 0x62, 0xf8, 0xd0, 0x00, 0xa3, 0x41, 0x05, 0x80, + 0x63, 0xfc, 0x90, 0x95, 0x62, 0xf8, 0xd4, 0x00, 0xa3, 0x41, 0x05, 0x80, + 0x63, 0xfc, 0x94, 0x95, 0x62, 0xf8, 0x00, 0x06, 0xa3, 0x41, 0x05, 0x80, + 0x63, 0xfc, 0x98, 0x95, 0x62, 0xf8, 0xd0, 0x06, 0xa3, 0x41, 0x05, 0x80, + 0x63, 0xfc, 0x9c, 0x95, 0x62, 0xf8, 0xd4, 0x06, 0xa2, 0x41, 0x05, 0x80, + 0x02, 0x18, 0x3c, 0x95, 0x1d, 0x23, 0x14, 0x50, 0x0e, 0x47, 0x81, 0xed, + 0xa2, 0x41, 0x05, 0x80, 0x9a, 0xcf, 0x62, 0x18, 0x3c, 0x95, 0x80, 0x0e, + 0x46, 0xcf, 0xa0, 0x32, 0x05, 0x00, 0x00, 0x0c, 0xd5, 0x4f, 0xdd, 0x22, + 0x3c, 0xd0, 0x04, 0x0e, 0x3d, 0x22, 0x68, 0x10, 0x7d, 0x22, 0x70, 0x10, + 0x2d, 0x8e, 0xbe, 0x4a, 0x47, 0x14, 0xa8, 0x00, 0xa4, 0x41, 0x05, 0x80, + 0x81, 0xed, 0x62, 0x94, 0x3a, 0x00, 0x44, 0x18, 0x84, 0x95, 0xa2, 0x41, + 0x03, 0x80, 0x90, 0x0c, 0x42, 0x30, 0x85, 0x99, 0x3d, 0x22, 0x10, 0x90, + 0x7d, 0x22, 0x18, 0x90, 0xc2, 0x45, 0xbd, 0xfa, 0x20, 0x00, 0x0e, 0x8c, + 0x01, 0xed, 0x50, 0xb4, 0x08, 0x00, 0xa2, 0x41, 0x05, 0x80, 0x02, 0x18, + 0xa5, 0x95, 0xa2, 0x41, 0x05, 0x80, 0x02, 0x18, 0xa0, 0x95, 0xdd, 0x22, + 0x3c, 0x50, 0x16, 0x47, 0xb9, 0x41, 0x05, 0x80, 0x39, 0x33, 0xe9, 0x90, + 0xdd, 0x22, 0x3c, 0x50, 0x99, 0x45, 0x2d, 0x4c, 0xa2, 0x41, 0x05, 0x80, + 0x42, 0x30, 0x05, 0x8e, 0xbd, 0x20, 0x28, 0x90, 0xc2, 0x45, 0xfd, 0xf8, + 0x30, 0x00, 0xec, 0x48, 0xa4, 0x41, 0x05, 0x80, 0x81, 0xed, 0x47, 0x14, + 0xa8, 0x00, 0xbd, 0x20, 0x28, 0x10, 0x62, 0xb4, 0xca, 0xff, 0x44, 0x18, + 0x84, 0x95, 0x67, 0x15, 0xa9, 0x00, 0x47, 0x15, 0xaa, 0x00, 0xa2, 0x41, + 0x05, 0x80, 0x27, 0x15, 0xab, 0x00, 0x07, 0x15, 0xac, 0x00, 0x62, 0xf9, + 0x88, 0x95, 0xa2, 0x41, 0x05, 0x80, 0x87, 0x14, 0xad, 0x00, 0x42, 0xf9, + 0x8c, 0x95, 0xa2, 0x41, 0x05, 0x80, 0x67, 0x14, 0xae, 0x00, 0x22, 0xf9, + 0x90, 0x95, 0xa2, 0x41, 0x05, 0x80, 0x02, 0xf9, 0x94, 0x95, 0xa2, 0x41, + 0x05, 0x80, 0x82, 0xf8, 0x98, 0x95, 0xa2, 0x41, 0x05, 0x80, 0xa5, 0xcf, + 0x62, 0xf8, 0x9c, 0x95, 0xf5, 0x4f, 0xa2, 0x41, 0x02, 0x80, 0x42, 0x30, + 0x45, 0x44, 0xe5, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xe5, 0x4b, 0xb9, 0x41, + 0x03, 0x80, 0x80, 0x30, 0x2c, 0x01, 0x39, 0x33, 0x65, 0xab, 0x99, 0x45, + 0x0d, 0x4c, 0x00, 0x0c, 0xe5, 0x4f, 0x1d, 0x23, 0x14, 0xd0, 0x86, 0x40, + 0x2d, 0x00, 0xc4, 0x0e, 0x66, 0x32, 0xff, 0xff, 0x73, 0xd2, 0xff, 0xff, + 0x62, 0x4e, 0x73, 0x02, 0x00, 0x10, 0xb7, 0x41, 0x02, 0x80, 0xb5, 0x41, + 0x02, 0x80, 0xb4, 0x41, 0x02, 0x80, 0x47, 0x0e, 0x05, 0x0e, 0x65, 0x02, + 0x50, 0x99, 0xf7, 0x32, 0xf5, 0x57, 0xb5, 0x32, 0xfd, 0x57, 0x94, 0x32, + 0x15, 0x58, 0xf7, 0x45, 0x00, 0x6a, 0x00, 0x6a, 0x32, 0x36, 0x00, 0x00, + 0xf5, 0x45, 0x95, 0x04, 0xb2, 0x34, 0x02, 0x00, 0x31, 0x02, 0x3c, 0x3b, + 0x91, 0x0c, 0xd5, 0x06, 0xd4, 0x45, 0xa5, 0x00, 0x3c, 0x3b, 0x00, 0xe9, + 0x02, 0x6c, 0x70, 0xb6, 0xec, 0xff, 0x00, 0x0c, 0x40, 0x30, 0xae, 0x00, + 0x56, 0x38, 0x00, 0x00, 0x5c, 0x38, 0xca, 0x81, 0x1d, 0x23, 0x14, 0x50, + 0x0e, 0x47, 0x00, 0x0c, 0xe9, 0x4f, 0x52, 0x48, 0x59, 0x45, 0xb1, 0x41, + 0x00, 0xa5, 0x11, 0xfe, 0x44, 0x12, 0x46, 0xc8, 0x51, 0x48, 0x45, 0xc8, + 0x5d, 0x14, 0x40, 0x00, 0x44, 0xc8, 0xa2, 0x41, 0x03, 0x80, 0x42, 0x30, + 0xb9, 0xa2, 0xe2, 0x45, 0x00, 0x0c, 0xa2, 0x41, 0xff, 0xff, 0x42, 0x30, + 0x00, 0x01, 0x82, 0x44, 0x10, 0x52, 0x00, 0x80, 0x11, 0xfa, 0x44, 0x12, + 0x19, 0x45, 0x0c, 0x47, 0x00, 0x31, 0x14, 0x00, 0x04, 0x01, 0x10, 0x40, + 0x06, 0xb4, 0x42, 0x00, 0x85, 0x49, 0x0e, 0xed, 0x45, 0x94, 0x08, 0x00, + 0xa0, 0x31, 0xb4, 0x09, 0xa5, 0x01, 0x00, 0x10, 0xad, 0x00, 0x50, 0x29, + 0xa5, 0x31, 0x67, 0x09, 0x5d, 0x14, 0x10, 0x00, 0x08, 0x01, 0x40, 0x08, + 0x0d, 0x01, 0xd0, 0x79, 0x44, 0x06, 0x44, 0x01, 0x00, 0x08, 0xca, 0x00, + 0x50, 0x51, 0x4a, 0x31, 0x10, 0x00, 0x4a, 0x01, 0x00, 0x10, 0x0d, 0x01, + 0x50, 0x41, 0xc0, 0x0c, 0x40, 0x0c, 0xc4, 0x0d, 0x47, 0x01, 0x50, 0x51, + 0x44, 0x26, 0x4e, 0x06, 0x24, 0xfd, 0x5c, 0x00, 0x64, 0xfc, 0x54, 0x00, + 0xaa, 0xfc, 0x00, 0x00, 0x8e, 0x0c, 0x69, 0x00, 0x50, 0x18, 0xdc, 0x06, + 0xa3, 0x00, 0x10, 0x1a, 0x60, 0x6f, 0xe3, 0x01, 0x90, 0x2b, 0x03, 0x01, + 0x90, 0x4b, 0x89, 0xae, 0x68, 0x00, 0x90, 0x5b, 0x0b, 0xb4, 0x07, 0x00, + 0xa3, 0x01, 0xd0, 0x19, 0x01, 0xed, 0x6c, 0xf8, 0x00, 0x00, 0xa9, 0x40, + 0xe1, 0xff, 0xbf, 0x45, 0x01, 0xed, 0x46, 0xb4, 0xc7, 0xff, 0xa0, 0x0d, + 0x45, 0xb0, 0xc5, 0x00, 0xa5, 0x01, 0x00, 0x10, 0x60, 0x30, 0x88, 0x13, + 0x20, 0x31, 0xa0, 0x0f, 0x49, 0x00, 0x58, 0x18, 0xad, 0x00, 0x50, 0x29, + 0xb9, 0xcf, 0x65, 0x00, 0x50, 0x69, 0x00, 0x0c, 0xed, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x79, 0x74, 0xc4, 0xc8, 0xa5, 0xc8, 0x86, 0xc8, + 0xe9, 0xcb, 0xe2, 0x45, 0x00, 0x0c, 0xc4, 0x48, 0xa5, 0x48, 0x86, 0x48, + 0xe9, 0x4b, 0xb9, 0x41, 0x02, 0x80, 0x39, 0x33, 0x71, 0x4f, 0x99, 0x45, + 0x15, 0x4c, 0x00, 0x0c, 0xd9, 0x4f, 0x05, 0xed, 0x4c, 0xc8, 0x08, 0xed, + 0x48, 0xc8, 0x01, 0xed, 0x5d, 0x22, 0x44, 0xd0, 0x86, 0xc8, 0x25, 0x0e, + 0x04, 0x0e, 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, + 0x0f, 0xc8, 0x9d, 0x8e, 0x45, 0xc8, 0x11, 0x6d, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0x83, 0xef, 0x18, 0xef, 0xa0, 0x0c, 0x42, 0x30, 0x2b, 0x11, + 0xc2, 0x45, 0x80, 0x30, 0x08, 0x10, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, + 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, + 0x42, 0x30, 0x1d, 0x0e, 0xe2, 0x45, 0x00, 0x0c, 0x5d, 0x22, 0x44, 0x50, + 0x14, 0x47, 0x19, 0x6d, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0x83, 0xef, + 0x18, 0xef, 0x42, 0x30, 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x08, 0x0a, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xe2, 0x45, 0x90, 0x0c, + 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, 0x42, 0x30, 0x1d, 0x0e, 0xe2, 0x45, + 0x00, 0x0c, 0x5d, 0x22, 0x44, 0x50, 0x14, 0x47, 0xf1, 0x4f, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x79, 0xf2, 0x55, 0x45, 0x04, 0x0e, 0xe2, 0x45, + 0x25, 0x0e, 0xb9, 0x41, 0x05, 0x80, 0x98, 0x86, 0x39, 0x33, 0xe5, 0x8a, + 0x15, 0x45, 0x99, 0x45, 0x11, 0x4c, 0x00, 0x0c, 0x45, 0x90, 0xf4, 0x01, + 0x3e, 0x8d, 0xa2, 0x41, 0x00, 0xa4, 0x04, 0xb4, 0x7c, 0x00, 0x01, 0xed, + 0x45, 0x90, 0x0f, 0x00, 0x02, 0x94, 0xa7, 0x00, 0x40, 0x30, 0xf8, 0x00, + 0x0e, 0xed, 0x45, 0x94, 0xb0, 0x00, 0x00, 0x0c, 0xde, 0x6d, 0xb4, 0x26, + 0xba, 0x06, 0xa5, 0x30, 0x6c, 0x09, 0xd2, 0x25, 0x56, 0x26, 0x38, 0x06, + 0x5a, 0x25, 0x34, 0x05, 0x4a, 0x26, 0xc7, 0x05, 0x28, 0x26, 0xa2, 0x41, + 0x0f, 0x00, 0x42, 0x30, 0xe9, 0x0b, 0xa6, 0x05, 0xa2, 0x41, 0x19, 0x00, + 0x42, 0x30, 0x21, 0x03, 0x45, 0x05, 0x63, 0x00, 0x80, 0x68, 0x42, 0x00, + 0x80, 0x68, 0x1f, 0xee, 0xc3, 0x90, 0x20, 0x00, 0xa2, 0x90, 0x20, 0x00, + 0xc4, 0x00, 0x58, 0x18, 0xa4, 0x00, 0x58, 0x10, 0x82, 0x90, 0x00, 0x00, + 0xa3, 0x90, 0x00, 0x00, 0xa0, 0x00, 0x18, 0x18, 0x80, 0x00, 0x18, 0x10, + 0xb6, 0x25, 0x48, 0xcc, 0x26, 0x25, 0x42, 0x50, 0x30, 0x97, 0xa0, 0x6b, + 0xc2, 0xfc, 0x00, 0x06, 0x04, 0xb4, 0x59, 0x00, 0x52, 0x26, 0xd6, 0x25, + 0xc6, 0x05, 0xda, 0x26, 0x4a, 0x05, 0xba, 0x25, 0xb9, 0x05, 0xa8, 0x26, + 0xa4, 0x41, 0x0f, 0x00, 0xa2, 0x41, 0x19, 0x00, 0x84, 0x30, 0xe9, 0x0b, + 0x42, 0x30, 0x21, 0x03, 0xc6, 0x05, 0x55, 0x05, 0x63, 0x00, 0x80, 0x68, + 0x42, 0x00, 0x80, 0x68, 0x1f, 0xee, 0xa2, 0x90, 0x20, 0x00, 0x03, 0x91, + 0x20, 0x00, 0x04, 0x01, 0x58, 0x18, 0xa4, 0x00, 0x58, 0x10, 0x82, 0x90, + 0x00, 0x00, 0xa3, 0x90, 0x00, 0x00, 0x80, 0x00, 0x18, 0x10, 0xa0, 0x00, + 0x18, 0x18, 0xb6, 0x25, 0x26, 0x25, 0xe0, 0x00, 0xcc, 0x38, 0x63, 0x50, + 0x04, 0x00, 0xc0, 0x00, 0xcc, 0x38, 0x42, 0x50, 0x04, 0x00, 0xa4, 0x41, + 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, 0xdf, 0x44, 0xd6, 0x44, 0xc0, 0xe9, + 0x44, 0xf8, 0x00, 0x06, 0xbf, 0x45, 0x44, 0x94, 0x31, 0x00, 0x40, 0x30, + 0x88, 0x00, 0xe8, 0xed, 0xa4, 0x41, 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, + 0xc0, 0x6b, 0xc4, 0xfc, 0x00, 0x06, 0x63, 0x50, 0x04, 0x00, 0xe0, 0x00, + 0xcc, 0x38, 0xc0, 0x00, 0xcc, 0x38, 0x42, 0x50, 0x04, 0x00, 0xa4, 0x41, + 0x00, 0xa4, 0x84, 0x50, 0x30, 0x97, 0xdf, 0x44, 0xd6, 0x44, 0xc0, 0xe9, + 0x44, 0xf8, 0x00, 0x06, 0xbf, 0x45, 0xd4, 0x25, 0xd6, 0x05, 0x58, 0x25, + 0x54, 0x05, 0xba, 0x25, 0xbb, 0x05, 0x28, 0x26, 0xa5, 0x41, 0x0f, 0x00, + 0xa2, 0x41, 0x19, 0x00, 0xa5, 0x30, 0xe9, 0x0b, 0x42, 0x30, 0x21, 0x03, + 0xd6, 0x05, 0xa8, 0xcf, 0x45, 0x05, 0xd4, 0xcf, 0x60, 0x30, 0xc8, 0x00, + 0xd4, 0x25, 0x45, 0x90, 0xb2, 0x00, 0x0c, 0x8d, 0xd6, 0x05, 0x63, 0x30, + 0x88, 0x13, 0x34, 0x26, 0x38, 0x06, 0x5b, 0xcf, 0x38, 0x25, 0x40, 0x30, + 0xf8, 0x00, 0xc4, 0xcf, 0x60, 0x30, 0xb8, 0x00, 0x63, 0x30, 0xa0, 0x0f, + 0x38, 0x25, 0x34, 0x26, 0x34, 0x05, 0x38, 0x06, 0xa8, 0x26, 0x4a, 0x26, + 0xa2, 0x41, 0x19, 0x00, 0xc7, 0x05, 0x42, 0x30, 0x21, 0x03, 0xa4, 0x41, + 0x0f, 0x00, 0x55, 0x05, 0x84, 0x30, 0xe9, 0x0b, 0xc6, 0x05, 0x42, 0x00, + 0x80, 0x68, 0xa2, 0x90, 0x20, 0x00, 0x63, 0x00, 0x80, 0x68, 0x54, 0xcf, + 0x1f, 0xee, 0x00, 0x0c, 0xdd, 0x4f, 0xa2, 0x41, 0x03, 0x80, 0x3d, 0x22, + 0x40, 0xd0, 0x42, 0x30, 0x15, 0x8a, 0xe2, 0x45, 0x04, 0x0e, 0x50, 0x60, + 0x03, 0x00, 0x85, 0xed, 0x6c, 0xc8, 0x50, 0x60, 0x00, 0x10, 0x88, 0xed, + 0x09, 0xc8, 0x0a, 0xc8, 0x0b, 0xc8, 0x0d, 0xc8, 0x0e, 0xc8, 0x0f, 0xc8, + 0x1c, 0x8d, 0x68, 0xc8, 0x5c, 0xfc, 0x48, 0x81, 0x83, 0xef, 0x18, 0xef, + 0x46, 0xc8, 0x01, 0xed, 0x45, 0xc8, 0x11, 0x6d, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0xa0, 0x0c, 0x42, 0x30, 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, + 0x08, 0x10, 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, + 0x9c, 0xfc, 0x48, 0x81, 0x3d, 0x22, 0x40, 0x50, 0x12, 0x47, 0x5c, 0xfc, + 0x48, 0x81, 0x83, 0xef, 0x18, 0xef, 0x46, 0xc8, 0x01, 0xed, 0x45, 0xc8, + 0x19, 0x6d, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xa0, 0x0c, 0x42, 0x30, + 0x2b, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x08, 0x0a, 0xa2, 0x41, 0x08, 0x80, + 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, 0x9c, 0xfc, 0x48, 0x81, 0x3d, 0x22, + 0x40, 0x50, 0x12, 0x47, 0xe5, 0x4f, 0xa2, 0x41, 0x09, 0x80, 0xdd, 0x22, + 0x1c, 0xd0, 0x04, 0x16, 0x3d, 0x00, 0x5d, 0x16, 0x48, 0x00, 0x93, 0x4a, + 0x34, 0x4a, 0x42, 0xfc, 0x1c, 0xaf, 0x10, 0x02, 0x00, 0xc8, 0x44, 0xca, + 0x85, 0xca, 0xa4, 0x0e, 0x67, 0x0e, 0xc2, 0x45, 0x10, 0x02, 0x80, 0xc8, + 0xf1, 0x40, 0x2f, 0x00, 0x11, 0x69, 0x2b, 0x2d, 0x62, 0x90, 0x20, 0x00, + 0xe3, 0x40, 0x24, 0x00, 0x74, 0x14, 0x00, 0x00, 0x43, 0x00, 0x50, 0x23, + 0xe4, 0x40, 0x05, 0x00, 0x14, 0x0a, 0x3b, 0x2d, 0x82, 0x00, 0x0c, 0x28, + 0x14, 0x8a, 0x52, 0xb2, 0x04, 0x00, 0xf2, 0x40, 0x0a, 0x00, 0xf3, 0x40, + 0x08, 0x00, 0x95, 0x14, 0x3c, 0x00, 0x94, 0x09, 0x45, 0x05, 0x2b, 0x2d, + 0x62, 0x00, 0x0c, 0x28, 0x94, 0x89, 0x02, 0x02, 0x50, 0x13, 0xe2, 0x40, + 0x04, 0x00, 0x14, 0x09, 0x50, 0x00, 0x0c, 0x28, 0x14, 0x89, 0xdd, 0x22, + 0x1c, 0x50, 0x0e, 0x47, 0x94, 0x09, 0x62, 0x00, 0x0c, 0x28, 0xe3, 0xcf, + 0x94, 0x89, 0x52, 0xb2, 0x04, 0x00, 0x12, 0x94, 0x04, 0x00, 0x54, 0x14, + 0x00, 0x00, 0xb3, 0x40, 0x09, 0x00, 0x42, 0x00, 0x3c, 0x2b, 0x02, 0x02, + 0x50, 0x13, 0xe2, 0x40, 0xea, 0xff, 0xe9, 0xcf, 0x14, 0x1a, 0x00, 0x00, + 0x75, 0x14, 0x3c, 0x00, 0x35, 0x05, 0x2d, 0x2d, 0xf2, 0xcf, 0x54, 0x18, + 0x00, 0x00, 0x00, 0x0c, 0xf1, 0x4f, 0x5c, 0xfc, 0x48, 0x81, 0xe7, 0xcb, + 0x80, 0x30, 0x64, 0x05, 0x44, 0xc8, 0xa2, 0x41, 0x08, 0x80, 0xe0, 0x0c, + 0x01, 0xef, 0x42, 0x30, 0x37, 0x11, 0xe2, 0x45, 0x81, 0xee, 0x9c, 0xfc, + 0x48, 0x81, 0xe7, 0x4b, 0xb9, 0x41, 0x08, 0x80, 0x39, 0x33, 0x1f, 0x17, + 0x99, 0x45, 0x11, 0x4c, 0xe9, 0x4f, 0xa2, 0x41, 0x08, 0x80, 0x77, 0x45, + 0x05, 0x0e, 0x3d, 0x32, 0x16, 0x00, 0x42, 0x30, 0x8b, 0x17, 0x44, 0x0e, + 0x98, 0x86, 0xe2, 0x45, 0x66, 0x0e, 0xa2, 0x41, 0x04, 0x80, 0x42, 0x30, + 0xe8, 0x02, 0xa4, 0x69, 0x63, 0x02, 0x50, 0x1b, 0xa3, 0x40, 0x7f, 0x00, + 0x10, 0xb2, 0x0f, 0x00, 0x10, 0xb2, 0x01, 0x00, 0x12, 0x02, 0x50, 0x81, + 0x70, 0x1c, 0x22, 0x00, 0x83, 0x00, 0xac, 0x38, 0x52, 0x14, 0x0f, 0x00, + 0x7d, 0x14, 0x16, 0x00, 0x03, 0xb4, 0x66, 0x00, 0x25, 0x25, 0xf2, 0x14, + 0x10, 0x00, 0x72, 0x14, 0x11, 0x00, 0xf5, 0x27, 0xb5, 0x25, 0x44, 0x05, + 0x2d, 0x2d, 0xce, 0x07, 0xc6, 0x05, 0xfd, 0x2f, 0xbd, 0x2d, 0x5c, 0x18, + 0x98, 0x81, 0x5c, 0x18, 0x99, 0x81, 0x5c, 0x18, 0x9a, 0x81, 0x5c, 0x18, + 0x9b, 0x81, 0x92, 0x30, 0x2a, 0x00, 0x89, 0x6e, 0x40, 0x09, 0xc2, 0x00, + 0x00, 0xe0, 0x42, 0x00, 0x3c, 0x2b, 0xc6, 0x00, 0x80, 0xe0, 0x42, 0x00, + 0x80, 0x20, 0x50, 0x8b, 0x51, 0x89, 0xa4, 0x4c, 0xb1, 0xb4, 0xf2, 0xff, + 0x40, 0x6e, 0x5d, 0x1d, 0x15, 0x00, 0x3d, 0x1d, 0x14, 0x00, 0x1d, 0x1d, + 0x13, 0x00, 0xdd, 0x1c, 0x12, 0x00, 0xbd, 0x1c, 0x11, 0x00, 0x9d, 0x1c, + 0x10, 0x00, 0xea, 0x00, 0x50, 0x51, 0xe9, 0x00, 0x50, 0x49, 0xe8, 0x00, + 0x50, 0x41, 0x7c, 0x07, 0xfa, 0x06, 0x78, 0x06, 0xb9, 0x41, 0x08, 0x80, + 0x43, 0x01, 0x50, 0xc3, 0x23, 0x01, 0x50, 0x7b, 0x03, 0x01, 0x50, 0x73, + 0xc3, 0x00, 0x50, 0x6b, 0xa3, 0x00, 0x50, 0x63, 0x83, 0x00, 0x50, 0x5b, + 0x59, 0x30, 0xb8, 0x1f, 0x03, 0x03, 0x18, 0x50, 0xe3, 0x01, 0x18, 0x48, + 0xc3, 0x01, 0x18, 0x40, 0xa3, 0x01, 0x18, 0x30, 0x83, 0x01, 0x18, 0x28, + 0x63, 0x01, 0x18, 0x20, 0x42, 0x19, 0x01, 0x00, 0x22, 0x19, 0x02, 0x00, + 0x02, 0x19, 0x03, 0x00, 0x24, 0x8b, 0xa5, 0x8a, 0x26, 0x8a, 0xa7, 0x8b, + 0x79, 0x18, 0xb8, 0x1f, 0x37, 0x45, 0x0c, 0x47, 0x72, 0x00, 0x50, 0x19, + 0xe3, 0x14, 0x11, 0x00, 0x63, 0x14, 0x14, 0x00, 0xf5, 0x27, 0x99, 0xcf, + 0xb5, 0x25, 0x25, 0x6b, 0x66, 0x02, 0x50, 0x9b, 0x13, 0xb4, 0x86, 0xff, + 0x80, 0x0c, 0x50, 0xb0, 0x0f, 0x00, 0x42, 0xb0, 0x01, 0x00, 0x52, 0x00, + 0x50, 0x11, 0x62, 0x1c, 0x24, 0x00, 0x7c, 0xcf, 0x83, 0x00, 0xac, 0x38, + 0xf5, 0x4f, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x30, 0x95, 0x80, 0x44, 0x45, + 0xc2, 0x45, 0x1d, 0xfe, 0x34, 0x00, 0xa3, 0x41, 0x00, 0xa5, 0x63, 0x50, + 0x08, 0x86, 0x30, 0x69, 0xa4, 0x41, 0x4f, 0x00, 0x84, 0x30, 0x00, 0x0e, + 0x40, 0x00, 0x0c, 0xb8, 0xd4, 0x44, 0x30, 0xe9, 0x50, 0x14, 0x89, 0x00, + 0x90, 0x14, 0x88, 0x00, 0xb9, 0x41, 0x03, 0x80, 0x20, 0x25, 0x39, 0x33, + 0x65, 0xab, 0xe2, 0x44, 0x04, 0x45, 0x99, 0x45, 0x0d, 0x4c, 0x00, 0x0c, + 0x9f, 0x45, 0x01, 0xed, 0xa5, 0x41, 0x05, 0x80, 0x45, 0x1c, 0xa0, 0x95, + 0x02, 0x94, 0x4f, 0x00, 0xa2, 0x41, 0x00, 0xa4, 0xa2, 0x41, 0x05, 0x80, + 0x62, 0x1c, 0xa1, 0x95, 0xa2, 0x41, 0x05, 0x80, 0x42, 0x1c, 0xa2, 0x95, + 0xa4, 0x30, 0xd7, 0xff, 0xa5, 0xb0, 0x1e, 0x00, 0xab, 0x8e, 0xa4, 0x90, + 0x47, 0x00, 0x63, 0x30, 0x0a, 0x00, 0x42, 0x30, 0x0b, 0x00, 0x63, 0x00, + 0x3c, 0x2b, 0x42, 0x00, 0x3c, 0x2b, 0x03, 0x40, 0x2c, 0x00, 0x83, 0x0c, + 0x84, 0x00, 0x3c, 0x2b, 0x02, 0x40, 0x2d, 0x00, 0x62, 0x0c, 0xa4, 0x90, + 0x10, 0x00, 0x83, 0xae, 0x43, 0x00, 0x3c, 0x2b, 0x0f, 0xee, 0xa3, 0x41, + 0x00, 0xa4, 0x84, 0x00, 0x3c, 0x2b, 0x63, 0x50, 0xd8, 0x99, 0xa2, 0x90, + 0x10, 0x00, 0x30, 0xea, 0x83, 0xae, 0xa3, 0x41, 0x00, 0xa4, 0x0f, 0xed, + 0x42, 0x00, 0x3c, 0x2b, 0x63, 0x50, 0xd8, 0x9f, 0x30, 0xe9, 0xbf, 0x45, + 0xa5, 0x40, 0x2c, 0x00, 0x63, 0x30, 0x0d, 0x00, 0x42, 0x30, 0x0f, 0x00, + 0x63, 0x00, 0x3c, 0x2b, 0x42, 0x00, 0x3c, 0x2b, 0x43, 0x40, 0xd6, 0xff, + 0x83, 0x0c, 0x80, 0x0c, 0x84, 0x00, 0x3c, 0x2b, 0x42, 0x40, 0xd5, 0xff, + 0x62, 0x0c, 0xd3, 0xcf, 0x60, 0x0c, 0x42, 0x50, 0xd8, 0x99, 0xa0, 0x69, + 0xa6, 0x41, 0x05, 0x80, 0xb7, 0x2d, 0x70, 0x4c, 0x63, 0x00, 0x3c, 0x2b, + 0x66, 0x18, 0xa1, 0x95, 0x42, 0xfc, 0x00, 0x06, 0x01, 0xef, 0xc5, 0x18, + 0xa0, 0x95, 0x27, 0x2d, 0x50, 0x4c, 0x42, 0x00, 0x3c, 0x2b, 0xa5, 0x41, + 0x05, 0x80, 0xa4, 0xcf, 0x45, 0x18, 0xa2, 0x95, 0xa4, 0x30, 0x13, 0x00, + 0xa5, 0xb0, 0x14, 0x00, 0xa5, 0x40, 0x0b, 0x00, 0x84, 0x90, 0xed, 0xff, + 0xe4, 0x40, 0x0e, 0x00, 0x6c, 0x4c, 0x4a, 0x4c, 0x63, 0x00, 0x3c, 0x2b, + 0xa2, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0x6e, 0x4c, 0x4c, 0x4c, 0x63, 0x00, + 0x3c, 0x2b, 0x9b, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0xb4, 0x6d, 0x24, 0x6d, + 0x63, 0x00, 0x3c, 0x2b, 0x94, 0xcf, 0x42, 0x00, 0x3c, 0x2b, 0x00, 0x0c, + 0xa2, 0x41, 0x05, 0x80, 0x42, 0x14, 0x3c, 0x95, 0x02, 0xb4, 0x4c, 0x00, + 0xa4, 0x41, 0x05, 0x80, 0x44, 0x1c, 0xa5, 0x95, 0x1e, 0xad, 0xa5, 0x41, + 0x05, 0x80, 0xa3, 0x41, 0x00, 0xa4, 0x63, 0x50, 0x04, 0x9f, 0x30, 0x69, + 0xa5, 0x41, 0x03, 0x80, 0xa5, 0xfc, 0x84, 0xea, 0x2d, 0x2d, 0x55, 0x05, + 0xa5, 0x41, 0x05, 0x80, 0x45, 0xf8, 0xa8, 0x95, 0x01, 0xed, 0x44, 0x18, + 0xa5, 0x95, 0x43, 0xfc, 0x00, 0xfa, 0xa3, 0x41, 0x05, 0x80, 0x2d, 0x2d, + 0x52, 0x4c, 0x43, 0xf8, 0xac, 0x95, 0xa5, 0x41, 0x05, 0x80, 0x45, 0x1c, + 0xa0, 0x95, 0x26, 0xad, 0xa2, 0x41, 0x00, 0xa4, 0x42, 0x50, 0xd8, 0x99, + 0x20, 0x6a, 0x62, 0xfc, 0x00, 0x06, 0xa6, 0x41, 0x05, 0x80, 0x47, 0x2e, + 0x90, 0x4c, 0xb7, 0x2d, 0x86, 0x18, 0xa1, 0x95, 0x70, 0x4c, 0xa4, 0x41, + 0x05, 0x80, 0x64, 0x18, 0xa2, 0x95, 0x62, 0xfc, 0xfc, 0xff, 0x42, 0xfc, + 0xfc, 0x05, 0xa4, 0x41, 0x05, 0x80, 0xb7, 0x2d, 0x70, 0x4c, 0x27, 0x2d, + 0x50, 0x4c, 0x64, 0x18, 0xa3, 0x95, 0xa3, 0x41, 0x05, 0x80, 0x43, 0x18, + 0xa4, 0x95, 0x01, 0xed, 0x45, 0x18, 0xa0, 0x95, 0xbf, 0x45, 0x00, 0x0c, + 0xf1, 0x4f, 0x5d, 0x14, 0x30, 0x00, 0x46, 0x45, 0x44, 0xc8, 0xa2, 0x41, + 0x01, 0x80, 0x42, 0x30, 0x5d, 0xf0, 0xe2, 0x45, 0x06, 0x0e, 0x17, 0x8c, + 0xa2, 0x41, 0x00, 0xa4, 0x42, 0x50, 0x04, 0x9f, 0xa4, 0x41, 0x05, 0x80, + 0xa0, 0x69, 0x84, 0xfc, 0xa8, 0x95, 0x9f, 0xee, 0x06, 0x45, 0x46, 0x06, + 0x64, 0x90, 0x20, 0x00, 0x64, 0x00, 0x18, 0x28, 0x65, 0x0c, 0x85, 0x90, + 0x00, 0x00, 0x80, 0x00, 0x18, 0x18, 0xa0, 0xe9, 0x08, 0x47, 0xa2, 0x41, + 0x05, 0x80, 0x42, 0xfc, 0xac, 0x95, 0x1f, 0xee, 0x06, 0x45, 0x62, 0x30, + 0x07, 0x00, 0x43, 0x90, 0x20, 0x00, 0x43, 0x00, 0x18, 0x20, 0x64, 0x90, + 0x00, 0x00, 0x44, 0x0c, 0x60, 0x00, 0x18, 0x10, 0xa3, 0x41, 0x00, 0xa4, + 0x63, 0x50, 0x04, 0x99, 0x30, 0xe9, 0x08, 0x47, 0xed, 0x4f, 0x5c, 0xfc, + 0x44, 0x81, 0x66, 0x45, 0x04, 0x0e, 0x42, 0xfc, 0x58, 0x00, 0x82, 0x94, + 0x11, 0x00, 0x25, 0x0e, 0x01, 0xed, 0x44, 0x94, 0x23, 0x00, 0xe0, 0x0c, + 0x5c, 0xfc, 0x48, 0x81, 0x01, 0xef, 0xa0, 0x0c, 0x44, 0xc8, 0xa2, 0x41, + 0x08, 0x80, 0x42, 0x30, 0x37, 0x11, 0xc2, 0x45, 0x80, 0x30, 0x04, 0x0d, + 0xa2, 0x41, 0x08, 0x80, 0x42, 0x30, 0x1f, 0x17, 0xc2, 0x45, 0x9c, 0xfc, + 0x48, 0x81, 0xa2, 0x41, 0x01, 0x80, 0x98, 0x86, 0x42, 0x30, 0x49, 0xf3, + 0xe2, 0x45, 0x00, 0x0c, 0xb9, 0x41, 0x05, 0x80, 0x98, 0x86, 0x39, 0x33, + 0xe5, 0x8a, 0x26, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x5c, 0xfc, 0x48, 0x81, + 0xb2, 0x41, 0x08, 0x80, 0x01, 0xef, 0x44, 0xc8, 0x81, 0xee, 0x52, 0x32, + 0x37, 0x11, 0xd2, 0x45, 0x80, 0x30, 0x04, 0x0d, 0x5c, 0xfc, 0x48, 0x81, + 0x83, 0xef, 0x08, 0xef, 0x81, 0xee, 0x80, 0x30, 0x04, 0x0d, 0xd2, 0x45, + 0x5d, 0xf8, 0x10, 0x00, 0xd5, 0xcf, 0xa2, 0x41, 0x08, 0x80, 0x00, 0x0c, + 0xed, 0x4f, 0xa2, 0x41, 0x01, 0x80, 0x57, 0x45, 0x42, 0x30, 0xdd, 0x02, + 0x25, 0x0e, 0xe2, 0x45, 0x04, 0x0e, 0x98, 0xac, 0xb9, 0x41, 0x08, 0x80, + 0xb1, 0x41, 0x08, 0x80, 0xe0, 0x0c, 0x01, 0xef, 0xa0, 0x0c, 0x80, 0x30, + 0x04, 0x0d, 0x31, 0x32, 0x37, 0x11, 0xd1, 0x45, 0x1d, 0xfa, 0x10, 0x00, + 0x83, 0xef, 0x08, 0xef, 0xa0, 0x0c, 0x80, 0x30, 0x04, 0x0d, 0xd1, 0x45, + 0x1d, 0xfa, 0x10, 0x00, 0xb9, 0x41, 0x08, 0x80, 0x90, 0x0c, 0x39, 0x33, + 0x1f, 0x17, 0x17, 0x45, 0x99, 0x45, 0x15, 0x4c, 0x28, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x23, 0x10, 0x1e, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x21, 0x00, 0x00, 0x00, + 0xca, 0x02, 0x00, 0x00, 0x50, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x12, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x11, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x11, 0x00, 0x00, 0x00, 0xf8, 0x01, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, + 0xf4, 0x01, 0x00, 0x00, 0xe0, 0x01, 0x00, 0x00, 0xf4, 0x01, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, + 0xf6, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xe2, 0x01, 0x00, 0x00, + 0xf5, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, + 0xf6, 0x01, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0xe2, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, + 0xf6, 0x01, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, + 0xe2, 0x01, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x15, 0x00, 0x00, 0x00, + 0xf5, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, 0xf5, 0x00, 0x00, 0x00, + 0x08, 0x00, 0x00, 0x00, 0xe2, 0x01, 0x00, 0x00, 0xe1, 0x00, 0x00, 0x00, + 0xe1, 0x00, 0x00, 0x00, 0x04, 0x00, 0x00, 0x00, 0xf6, 0x01, 0x00, 0x00, + 0xf6, 0x00, 0x00, 0x00, 0x19, 0x00, 0x00, 0x00, 0xe2, 0x00, 0x00, 0x00, + 0x19, 0x00, 0x00, 0x00, 0xf6, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, + 0xe2, 0x00, 0x00, 0x00, 0x08, 0x00, 0x00, 0x00, 0x1a, 0x00, 0x00, 0x00, + 0x49, 0x48, 0x04, 0x80, 0x9f, 0x47, 0x04, 0x80, 0x83, 0x47, 0x04, 0x80, + 0x9f, 0x47, 0x04, 0x80, 0x2b, 0x48, 0x04, 0x80, 0x9f, 0x47, 0x04, 0x80, + 0x83, 0x47, 0x04, 0x80, 0x49, 0x48, 0x04, 0x80, 0x49, 0x48, 0x04, 0x80, + 0x2b, 0x48, 0x04, 0x80, 0x83, 0x47, 0x04, 0x80, 0xa5, 0x47, 0x04, 0x80, + 0xa5, 0x47, 0x04, 0x80, 0xa5, 0x47, 0x04, 0x80, 0x6d, 0x47, 0x04, 0x80, + 0x75, 0x4b, 0x04, 0x80, 0x75, 0x4b, 0x04, 0x80, 0x73, 0x4b, 0x04, 0x80, + 0x0b, 0x4b, 0x04, 0x80, 0x0b, 0x4b, 0x04, 0x80, 0x07, 0x4c, 0x04, 0x80, + 0x73, 0x4b, 0x04, 0x80, 0x0b, 0x4b, 0x04, 0x80, 0x07, 0x4c, 0x04, 0x80, + 0x0b, 0x4b, 0x04, 0x80, 0x73, 0x4b, 0x04, 0x80, 0x09, 0x4b, 0x04, 0x80, + 0x09, 0x4b, 0x04, 0x80, 0x09, 0x4b, 0x04, 0x80, 0xf7, 0x4a, 0x04, 0x80, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, + 0x6d, 0x65, 0x61, 0x73, 0x75, 0x72, 0x65, 0x20, 0x74, 0x65, 0x6d, 0x70, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x20, 0x65, 0x6e, 0x74, 0x65, 0x72, + 0x20, 0x70, 0x6f, 0x77, 0x65, 0x72, 0x20, 0x73, 0x61, 0x76, 0x65, 0x00, + 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, 0x73, 0x77, 0x69, 0x74, + 0x63, 0x68, 0x20, 0x00, 0x63, 0x68, 0x61, 0x6e, 0x6e, 0x65, 0x6c, 0x20, + 0x73, 0x77, 0x69, 0x74, 0x63, 0x68, 0x20, 0x64, 0x6f, 0x6e, 0x65, 0x20, + 0x00, 0x00, 0x00, 0x00, 0x76, 0x69, 0x66, 0x20, 0x63, 0x6f, 0x6e, 0x6e, + 0x65, 0x63, 0x74, 0x65, 0x64, 0x20, 0x65, 0x78, 0x69, 0x74, 0x20, 0x70, + 0x6f, 0x77, 0x65, 0x72, 0x20, 0x73, 0x61, 0x76, 0x65, 0x00, 0x00, 0x00, + 0x44, 0x65, 0x6c, 0x65, 0x74, 0x65, 0x20, 0x54, 0x57, 0x54, 0x00, 0x00, + 0x41, 0x64, 0x64, 0x20, 0x54, 0x57, 0x54, 0x00, 0x63, 0x61, 0x6c, 0x54, + 0x57, 0x54, 0x53, 0x50, 0x20, 0x73, 0x74, 0x61, 0x72, 0x74, 0x00, 0x00, + 0x63, 0x61, 0x6c, 0x54, 0x57, 0x54, 0x53, 0x50, 0x20, 0x45, 0x4e, 0x44, + 0x00, 0x00, 0x00, 0x00, 0x53, 0x6c, 0x65, 0x65, 0x70, 0x20, 0x52, 0x65, + 0x71, 0x20, 0x46, 0x61 +}; + +#endif /* CONFIG_NRF700X_RADIO_TEST */ diff --git a/nrf_wifi/fw_if/umac_if/inc/radio_test/fmac_api.h b/nrf_wifi/fw_if/umac_if/inc/radio_test/fmac_api.h new file mode 100644 index 0000000000..9e5bc53487 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/radio_test/fmac_api.h @@ -0,0 +1,270 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @file + * + * @addtogroup nrf_wifi_api_radio_test FMAC radio test API + * @{ + * + * @brief Header containing API declarations for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_API_H__ +#define __FMAC_API_H__ + +#include + +#include "osal_api.h" +#include "host_rpu_umac_if.h" +#include "host_rpu_data_if.h" +#include "host_rpu_sys_if.h" + +#include "fmac_structs.h" +#include "fmac_cmd.h" +#include "fmac_event.h" +#include "fmac_vif.h" +#include "fmac_bb.h" +#include "fmac_api_common.h" + + +/** + * @brief Initializes the UMAC IF layer. + * + * This function initializes the UMAC IF layer of the RPU WLAN FullMAC driver. + * It does the following: + * + * - Creates and initializes the context for the UMAC IF layer. + * - Initializes the OS abstraction Layer + * - Initializes the HAL layer. + * - Registers the driver to the underlying Operating System. + * + * @return Pointer to the context of the UMAC IF layer. + */ +struct nrf_wifi_fmac_priv *nrf_wifi_fmac_init_rt(void); + + +/** + * @brief Initialize the RPU for radio tests. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param params Parameters necessary for the initialization. + * + * This function is used to send a command to: + * - The RPU firmware to initialize it for radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_radio_test_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params); + +/** + * @brief Start TX tests in radio test mode. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param params Parameters necessary for the TX tests. + * + * This function is used to send a command to: + * - The RPU firmware to start the TX tests in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_radio_test_prog_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params); + +/** + * @brief Start RX tests in radio test mode. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param params Parameters necessary for the RX tests. + * + * This function is used to send a command to: + * - The RPU firmware to start the RX tests in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_radio_test_prog_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params); + + +/** + * @brief Start RF test capture in radio test mode. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param rf_test_type Type of RF test to be performed. + * @param cap_data Pointer to the memory where the RF test capture is to be stored. + * @param num_samples Number of RF test samples to capture. + * @param lna_gain LNA gain value. + * @param bb_gain Baseband gain value. + * + * This function is used to send a command to: + * - The RPU firmware to start the RF test capture in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_test_rx_cap(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + enum nrf_wifi_rf_test rf_test_type, + void *cap_data, + unsigned short int num_samples, + unsigned char lna_gain, + unsigned char bb_gain); + + +/** + * @brief Start/Stop RF TX tone test in radio test mode. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param enable Enable/Disable TX tone test. + * @param tone_freq Desired tone frequency in MHz in steps of 1 MHz from -10 MHz to +10 MHz. + * @param tx_power Desired TX power in the range -16dBm to +24dBm. + * + * This function is used to send a command to: + * - The RPU firmware to start the RF TX tone test in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_test_tx_tone(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char enable, + signed char tone_freq, + signed char tx_power); + + + +/** + * @brief Start/Stop RF DPD test in radio test mode. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param enable Enable/Disable DPD test. + * + * This function is used to send a command to: + * - The RPU firmware to start the RF DPD test in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_test_dpd(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char enable); + + + +/** + * @brief Get temperature in Fahrenheit using temperature sensor. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * + * This function is used to send a command to: + * - The RPU firmware to get the current temperature using the radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_get_temp(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + + + +/** + * @brief Get RF RSSI status. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * + * This function is used to send a command to: + * - The RPU firmware to get RF RSSI status in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_get_rf_rssi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + + +/** + * @brief Set XO adjustment value. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * @param value XO adjustment value. + * + * This function is used to send a command to: + * - The RPU firmware to set XO adjustment value in radio test mode. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_set_xo_val(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char value); + +/** + * @brief Get XO calibrated value. + * @param fmac_dev_ctx Pointer to the UMAC IF context for a RPU WLAN device. + * + * This function is used to send a command to: + * - The RPU firmware wherein the RPU firmware estimates and + * returns optimal XO value. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_rf_test_compute_xo(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + + +/** + * @brief De-initializes the UMAC IF layer. + * @param fpriv Pointer to the context of the UMAC IF layer. + * + * This function de-initializes the UMAC IF layer of the RPU WLAN FullMAC + * driver. It does the following: + * + * - De-initializes the HAL layer. + * - Frees the context for the UMAC IF layer. + * + * @return None + */ +void nrf_wifi_fmac_deinit_rt(struct nrf_wifi_fmac_priv *fpriv); + + +/** + * @brief Removes a RPU instance. + * @param fmac_dev_ctx Pointer to the context of the RPU instance to be removed. + * + * This function handles the removal of an RPU instance at the UMAC IF layer. + * + * @return None. + */ +void nrf_wifi_fmac_dev_rem_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + + +/** + * @brief Initializes a RPU instance. + * @param fmac_dev_ctx Pointer to the context of the RPU instance to be removed. + * @param sleep_type Type of RPU sleep. + * @param phy_calib PHY calibration flags to be passed to the RPU. + * @param op_band Operating band of the RPU. + * @param beamforming Enable/disable Wi-Fi beamforming. + * @param tx_pwr_ctrl TX power control parameters to be passed to the RPU. + * + * This function initializes the firmware of an RPU instance. + * + * @retval NRF_WIFI_STATUS_SUCCESS On Success + * @retval NRF_WIFI_STATUS_FAIL On failure to execute command + */ +enum nrf_wifi_status nrf_wifi_fmac_dev_init_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#if defined(CONFIG_NRF_WIFI_LOW_POWER) || defined(__DOXYGEN__) + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl); + + +/** + * @brief De-initializes a RPU instance. + * @param fmac_dev_ctx Pointer to the context of the RPU instance to be removed. + * + * This function de-initializes the firmware of an RPU instance. + * + * @return None. + */ +void nrf_wifi_fmac_dev_deinit_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx); + +/** + * @} + */ +#endif /* __FMAC_API_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/inc/radio_test/fmac_structs.h b/nrf_wifi/fw_if/umac_if/inc/radio_test/fmac_structs.h new file mode 100644 index 0000000000..c524dc56aa --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/inc/radio_test/fmac_structs.h @@ -0,0 +1,51 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** @file + * + * @addtogroup nrf_wifi_api_radio_test FMAC radio test API + * @{ + * + * TODO: This file is not added doxygen to avoid duplicate warnings. + * + * @brief Header containing declarations for utility functions for + * FMAC IF Layer of the Wi-Fi driver. + */ + +#ifndef __FMAC_STRUCTS_H__ +#define __FMAC_STRUCTS_H__ + +#include + +#include "osal_api.h" +#include "host_rpu_umac_if.h" +#if !defined(__DOXYGEN__) +#include "fmac_structs_common.h" +#endif + +/** + * @brief Structure to hold per device context information for the UMAC IF layer. + * + * This structure maintains the context information necessary for the + * a single instance of an FullMAC based RPU. + */ +struct nrf_wifi_fmac_dev_ctx_rt { + /** Firmware RF test command type. */ + enum nrf_wifi_rf_test rf_test_type; + /** Firmware RF test capability data. */ + void *rf_test_cap_data; + /** Firmware RF test capability data size. */ + unsigned int rf_test_cap_sz; + /** Firmware RF test command is completed. */ + bool radio_cmd_done; + /** Firmware RF test command status. */ + enum nrf_wifi_radio_test_err_status radio_cmd_status; +}; + +/** + * @} + */ +#endif /* __FMAC_STRUCTS_H__ */ diff --git a/nrf_wifi/fw_if/umac_if/src/cmd.c b/nrf_wifi/fw_if/umac_if/src/cmd.c new file mode 100644 index 0000000000..dac5e3db57 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/cmd.c @@ -0,0 +1,527 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing command specific definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "host_rpu_umac_if.h" +#include "hal_api.h" +#include "fmac_structs.h" +#include "fmac_util.h" + +struct host_rpu_msg *umac_cmd_alloc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int type, + int len) +{ + struct host_rpu_msg *umac_cmd = NULL; + + umac_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*umac_cmd) + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to allocate UMAC cmd\n", + __func__); + goto out; + } + + umac_cmd->type = type; + umac_cmd->hdr.len = sizeof(*umac_cmd) + len; + +out: + return umac_cmd; +} + + +enum nrf_wifi_status umac_cmd_cfg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *params, + int len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + + if (!fmac_dev_ctx->fw_init_done) { + struct nrf_wifi_umac_hdr *umac_hdr = NULL; + + umac_hdr = (struct nrf_wifi_umac_hdr *)params; + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC buff config not yet done(%d)\n", + __func__, + umac_hdr->cmd_evnt); + goto out; + } + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_UMAC, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + umac_cmd->msg, + params, + len); + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Command %d sent to RPU\n", + __func__, + ((struct nrf_wifi_umac_hdr *)params)->cmd_evnt); + +out: + return status; +} + + +enum nrf_wifi_status umac_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#ifndef CONFIG_NRF700X_RADIO_TEST + unsigned char *rf_params, + bool rf_params_valid, + struct nrf_wifi_data_config_params *config, +#endif /* !CONFIG_NRF700X_RADIO_TEST */ +#ifdef CONFIG_NRF_WIFI_LOW_POWER + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_sys_init *umac_cmd_data = NULL; + unsigned int len = 0; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_sys_init *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_INIT; + umac_cmd_data->sys_head.len = len; + +#ifndef CONFIG_NRF700X_RADIO_TEST + umac_cmd_data->sys_params.rf_params_valid = rf_params_valid; + + if (rf_params_valid) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + umac_cmd_data->sys_params.rf_params, + rf_params, + NRF_WIFI_RF_PARAMS_SIZE); + } +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + + umac_cmd_data->sys_params.phy_calib = phy_calib; + umac_cmd_data->sys_params.hw_bringup_time = HW_DELAY; + umac_cmd_data->sys_params.sw_bringup_time = SW_DELAY; + umac_cmd_data->sys_params.bcn_time_out = BCN_TIMEOUT; + umac_cmd_data->sys_params.calib_sleep_clk = CALIB_SLEEP_CLOCK_ENABLE; +#ifdef CONFIG_NRF_WIFI_LOW_POWER + umac_cmd_data->sys_params.sleep_enable = sleep_type; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +#ifdef CONFIG_NRF700X_TCP_IP_CHECKSUM_OFFLOAD + umac_cmd_data->tcp_ip_checksum_offload = 1; +#endif /* CONFIG_NRF700X_TCP_IP_CHECKSUM_OFFLOAD */ + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, "RPU LPM type: %s\n", + umac_cmd_data->sys_params.sleep_enable == 2 ? "HW" : + umac_cmd_data->sys_params.sleep_enable == 1 ? "SW" : "DISABLED"); +#ifndef CONFIG_NRF700X_RADIO_TEST + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + umac_cmd_data->rx_buf_pools, + def_priv->rx_buf_pools, + sizeof(umac_cmd_data->rx_buf_pools)); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->data_config_params, + config, + sizeof(umac_cmd_data->data_config_params)); + + umac_cmd_data->temp_vbat_config_params.temp_based_calib_en = NRF_WIFI_TEMP_CALIB_ENABLE; + umac_cmd_data->temp_vbat_config_params.temp_calib_bitmap = NRF_WIFI_DEF_PHY_TEMP_CALIB; + umac_cmd_data->temp_vbat_config_params.vbat_calibp_bitmap = NRF_WIFI_DEF_PHY_VBAT_CALIB; + umac_cmd_data->temp_vbat_config_params.temp_vbat_mon_period = NRF_WIFI_TEMP_CALIB_PERIOD; + umac_cmd_data->temp_vbat_config_params.vth_low = NRF_WIFI_VBAT_LOW; + umac_cmd_data->temp_vbat_config_params.vth_hi = NRF_WIFI_VBAT_HIGH; + umac_cmd_data->temp_vbat_config_params.temp_threshold = NRF_WIFI_TEMP_CALIB_THRESHOLD; + umac_cmd_data->temp_vbat_config_params.vth_very_low = NRF_WIFI_VBAT_VERYLOW; +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + + umac_cmd_data->op_band = op_band; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->tx_pwr_ctrl_params, + tx_pwr_ctrl_params, + sizeof(umac_cmd_data->tx_pwr_ctrl_params)); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + umac_cmd_data->country_code, + CONFIG_NRF700X_REG_DOMAIN, + NRF_WIFI_COUNTRY_CODE_LEN); + +#ifdef CONFIG_NRF700X_RPU_EXTEND_TWT_SP + umac_cmd_data->feature_flags |= TWT_EXTEND_SP_EDCA; +#endif + if (!beamforming) { + umac_cmd_data->disable_beamforming = 1; + } + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); + +out: + return status; +} + + +enum nrf_wifi_status umac_cmd_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_sys_deinit *umac_cmd_data = NULL; + unsigned int len = 0; + + len = sizeof(*umac_cmd_data); + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + umac_cmd_data = (struct nrf_wifi_cmd_sys_deinit *)(umac_cmd->msg); + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_DEINIT; + umac_cmd_data->sys_head.len = len; + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); +out: + return status; +} + + +enum nrf_wifi_status umac_cmd_btcoex(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *cmd, unsigned int cmd_len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_coex_config *umac_cmd_data = NULL; + int len = 0; + + len = sizeof(*umac_cmd_data)+cmd_len; + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_coex_config *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_BTCOEX; + umac_cmd_data->sys_head.len = len; + umac_cmd_data->coex_config_info.len = cmd_len; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + umac_cmd_data->coex_config_info.coex_cmd, + cmd, + cmd_len); + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); +out: + return status; + + +} + +enum nrf_wifi_status umac_cmd_he_ltf_gi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char he_ltf, + unsigned char he_gi, + unsigned char enabled) +{ + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_he_gi_ltf_config *umac_cmd_data = NULL; + int len = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_he_gi_ltf_config *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_HE_GI_LTF_CONFIG; + umac_cmd_data->sys_head.len = len; + + if (enabled) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->he_ltf, + &he_ltf, + sizeof(he_ltf)); + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->he_gi_type, + &he_gi, + sizeof(he_gi)); + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->enable, + &enabled, + sizeof(enabled)); + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); +out: + return status; +} + +#ifdef CONFIG_NRF700X_RADIO_TEST +enum nrf_wifi_status umac_cmd_prog_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_radio_test_init_info *init_params) +{ + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_radio_test_init *umac_cmd_data = NULL; + int len = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_radio_test_init *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RADIO_TEST_INIT; + umac_cmd_data->sys_head.len = len; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->conf, + init_params, + sizeof(umac_cmd_data->conf)); + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); +out: + return status; +} + + +enum nrf_wifi_status umac_cmd_prog_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params) +{ + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_mode_params *umac_cmd_data = NULL; + int len = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_mode_params *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_TX; + umac_cmd_data->sys_head.len = len; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->conf, + params, + sizeof(umac_cmd_data->conf)); + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); + +out: + return status; +} + + +enum nrf_wifi_status umac_cmd_prog_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_rx_radio_test_params *rx_params) +{ + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_rx *umac_cmd_data = NULL; + int len = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_rx *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RX; + umac_cmd_data->sys_head.len = len; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &umac_cmd_data->conf, + rx_params, + sizeof(umac_cmd_data->conf)); + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); + +out: + return status; +} + + +enum nrf_wifi_status umac_cmd_prog_rf_test(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *rf_test_params, + unsigned int rf_test_params_sz) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_rftest *umac_cmd_data = NULL; + int len = 0; + + len = (sizeof(*umac_cmd_data) + rf_test_params_sz); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_rftest *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_RF_TEST; + umac_cmd_data->sys_head.len = len; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + (void *)umac_cmd_data->rf_test_info.rfcmd, + rf_test_params, + rf_test_params_sz); + + umac_cmd_data->rf_test_info.len = rf_test_params_sz; + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); + +out: + return status; +} +#endif /* CONFIG_NRF700X_RADIO_TEST */ + + +enum nrf_wifi_status umac_cmd_prog_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#ifdef CONFIG_NRF700X_RADIO_TEST + int op_mode, +#endif /* CONFIG_NRF700X_RADIO_TEST */ + int stats_type) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_get_stats *umac_cmd_data = NULL; + int len = 0; + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_get_stats *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_GET_STATS; + umac_cmd_data->sys_head.len = len; + umac_cmd_data->stats_type = stats_type; +#ifdef CONFIG_NRF700X_RADIO_TEST + umac_cmd_data->op_mode = op_mode; +#endif /* CONFIG_NRF700X_RADIO_TEST */ + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); + +out: + return status; +} diff --git a/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c b/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c new file mode 100644 index 0000000000..c191af1ff6 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/default/fmac_api.c @@ -0,0 +1,3145 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing API definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "host_rpu_umac_if.h" +#include "fmac_api.h" +#include "hal_api.h" +#include "fmac_structs.h" +#include "fmac_api.h" +#include "fmac_util.h" +#include "fmac_peer.h" +#include "fmac_vif.h" +#include "fmac_tx.h" +#include "fmac_rx.h" +#include "fmac_cmd.h" +#include "fmac_event.h" +#include "fmac_bb.h" +#include "util.h" + + +unsigned char nrf_wifi_fmac_vif_idx_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + unsigned char i = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + for (i = 0; i < MAX_NUM_VIFS; i++) { + if (def_dev_ctx->vif_ctx[i] == NULL) { + break; + } + } + + return i; +} + + +#ifdef CONFIG_NRF700X_DATA_TX +static enum nrf_wifi_status nrf_wifi_fmac_init_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int size = 0; + + fpriv = fmac_dev_ctx->fpriv; + + def_priv = wifi_fmac_priv(fpriv); + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + size = (def_priv->num_tx_tokens * + def_priv->data_config.max_tx_aggregation * + sizeof(struct nrf_wifi_fmac_buf_map_info)); + + def_dev_ctx->tx_buf_info = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + size); + + if (!def_dev_ctx->tx_buf_info) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No space for TX buf info\n", + __func__); + goto out; + } + + status = tx_init(fmac_dev_ctx); + +out: + return status; +} + + +static void nrf_wifi_fmac_deinit_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + fpriv = fmac_dev_ctx->fpriv; + + tx_deinit(fmac_dev_ctx); + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_buf_info); +} + +#endif /* CONFIG_NRF700X_DATA_TX */ + +static enum nrf_wifi_status nrf_wifi_fmac_init_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int size = 0; + unsigned int desc_id = 0; + + fpriv = fmac_dev_ctx->fpriv; + def_priv = wifi_fmac_priv(fpriv); + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + size = (def_priv->num_rx_bufs * sizeof(struct nrf_wifi_fmac_buf_map_info)); + + def_dev_ctx->rx_buf_info = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + size); + + if (!def_dev_ctx->rx_buf_info) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No space for RX buf info\n", + __func__); + goto out; + } + + for (desc_id = 0; desc_id < def_priv->num_rx_bufs; desc_id++) { + status = nrf_wifi_fmac_rx_cmd_send(fmac_dev_ctx, + NRF_WIFI_FMAC_RX_CMD_TYPE_INIT, + desc_id); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_rx_cmd_send(INIT) failed for desc_id = %d\n", + __func__, + desc_id); + goto out; + } + } +#ifdef CONFIG_NRF700X_RX_WQ_ENABLED + def_dev_ctx->rx_tasklet = nrf_wifi_osal_tasklet_alloc(fmac_dev_ctx->fpriv->opriv, + NRF_WIFI_TASKLET_TYPE_RX); + if (!def_dev_ctx->rx_tasklet) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No space for RX tasklet\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + def_dev_ctx->rx_tasklet_event_q = nrf_wifi_utils_q_alloc(fpriv->opriv); + if (!def_dev_ctx->rx_tasklet_event_q) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No space for RX tasklet event queue\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nrf_wifi_osal_tasklet_init(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->rx_tasklet, + nrf_wifi_fmac_rx_tasklet, + (unsigned long)fmac_dev_ctx); +#endif /* CONFIG_NRF700X_RX_WQ_ENABLED */ +out: + return status; +} + + +static enum nrf_wifi_status nrf_wifi_fmac_deinit_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + unsigned int desc_id = 0; + + fpriv = fmac_dev_ctx->fpriv; + def_priv = wifi_fmac_priv(fpriv); + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + +#ifdef CONFIG_NRF700X_RX_WQ_ENABLED + nrf_wifi_osal_tasklet_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->rx_tasklet); + nrf_wifi_utils_q_free(fpriv->opriv, + def_dev_ctx->rx_tasklet_event_q); +#endif /* CONFIG_NRF700X_RX_WQ_ENABLED */ + + for (desc_id = 0; desc_id < def_priv->num_rx_bufs; desc_id++) { + status = nrf_wifi_fmac_rx_cmd_send(fmac_dev_ctx, + NRF_WIFI_FMAC_RX_CMD_TYPE_DEINIT, + desc_id); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_rx_cmd_send(DEINIT) failed for desc_id = %d\n", + __func__, + desc_id); + goto out; + } + } + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->rx_buf_info); + + def_dev_ctx->rx_buf_info = NULL; +out: + return status; +} + + +static enum nrf_wifi_status nrf_wifi_fmac_fw_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *rf_params, + bool rf_params_valid, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl) +{ + unsigned long start_time_us = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + +#ifdef CONFIG_NRF700X_DATA_TX + status = nrf_wifi_fmac_init_tx(fmac_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Init TX failed\n", + __func__); + goto out; + } +#endif /* CONFIG_NRF700X_DATA_TX */ + + status = nrf_wifi_fmac_init_rx(fmac_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Init RX failed\n", + __func__); +#ifdef CONFIG_NRF700X_DATA_TX + nrf_wifi_fmac_deinit_tx(fmac_dev_ctx); +#endif + goto out; + } + + status = umac_cmd_init(fmac_dev_ctx, + rf_params, + rf_params_valid, + &def_priv->data_config, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + phy_calib, + op_band, + beamforming, + tx_pwr_ctrl); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC init failed\n", + __func__); + nrf_wifi_fmac_deinit_rx(fmac_dev_ctx); +#ifdef CONFIG_NRF700X_DATA_TX + nrf_wifi_fmac_deinit_tx(fmac_dev_ctx); +#endif /* CONFIG_NRF700X_DATA_TX */ + goto out; + } + start_time_us = nrf_wifi_osal_time_get_curr_us(fmac_dev_ctx->fpriv->opriv); + while (!fmac_dev_ctx->fw_init_done) { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, 1); +#define MAX_INIT_WAIT (5 * 1000 * 1000) + if (nrf_wifi_osal_time_elapsed_us(fmac_dev_ctx->fpriv->opriv, + start_time_us) >= MAX_INIT_WAIT) { + break; + } + } + + if (!fmac_dev_ctx->fw_init_done) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC init timed out\n", + __func__); + nrf_wifi_fmac_deinit_rx(fmac_dev_ctx); +#ifdef CONFIG_NRF700X_DATA_TX + nrf_wifi_fmac_deinit_tx(fmac_dev_ctx); +#endif /* CONFIG_NRF700X_DATA_TX */ + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + status = NRF_WIFI_STATUS_SUCCESS; + +out: + return status; +} + +static void nrf_wifi_fmac_fw_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + /* TODO: To be activated once UMAC supports deinit */ +#ifdef NOTYET + unsigned long start_time_us = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = umac_cmd_deinit(fmac_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC deinit failed\n", + __func__); + goto out; + } + + start_time_us = nrf_wifi_osal_time_get_curr_us(fmac_dev_ctx->fpriv->opriv); + + while (!fmac_dev_ctx->fw_deinit_done) { +#define MAX_DEINIT_WAIT (5 * 1000 * 1000) + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, 1); + if (nrf_wifi_osal_time_elapsed_us(fmac_dev_ctx->fpriv->opriv, + start_time_us) >= MAX_DEINIT_WAIT) { + break; + } + } + + if (!fmac_dev_ctx->fw_deinit_done) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC deinit timed out\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } +out: +#endif /* NOTYET */ + nrf_wifi_fmac_deinit_rx(fmac_dev_ctx); +#ifdef CONFIG_NRF700X_DATA_TX + nrf_wifi_fmac_deinit_tx(fmac_dev_ctx); +#endif /* CONFIG_NRF700X_DATA_TX */ + +} + +void nrf_wifi_fmac_dev_rem(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + nrf_wifi_hal_dev_rem(fmac_dev_ctx->hal_dev_ctx); + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + fmac_dev_ctx); + fmac_dev_ctx = NULL; +} + + +enum nrf_wifi_status nrf_wifi_fmac_dev_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *rf_params_usr, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params, + struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_otp_info otp_info; + unsigned char rf_params[NRF_WIFI_RF_PARAMS_SIZE]; + int ret = -1; + + if (!fmac_dev_ctx) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid device context\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_dev_init(fmac_dev_ctx->hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_dev_init failed\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &otp_info, + 0xFF, + sizeof(otp_info)); + + status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx, + &otp_info.info, + &otp_info.flags); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Fetching of RPU OTP information failed\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + rf_params, + 0xFF, + sizeof(rf_params)); + + if (rf_params_usr) { + ret = nrf_wifi_utils_hex_str_to_val(fmac_dev_ctx->fpriv->opriv, + rf_params, + sizeof(rf_params), + rf_params_usr); + + if (ret == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: hex_str_to_val failed\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + } else { + status = nrf_wifi_fmac_rf_params_get(fmac_dev_ctx, + rf_params, + tx_pwr_ceil_params); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: RF parameters get failed\n", + __func__); + goto out; + } + } + + status = nrf_wifi_fmac_fw_init(fmac_dev_ctx, + rf_params, + true, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + phy_calib, + op_band, + beamforming, + tx_pwr_ctrl_params); + + if (status == NRF_WIFI_STATUS_FAIL) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_fw_init failed\n", + __func__); + goto out; + } +out: + return status; +} + + +void nrf_wifi_fmac_dev_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + nrf_wifi_fmac_fw_deinit(fmac_dev_ctx); +} + +struct nrf_wifi_fmac_priv *nrf_wifi_fmac_init(struct nrf_wifi_data_config_params *data_config, + struct rx_buf_pool_params *rx_buf_pools, + struct nrf_wifi_fmac_callbk_fns *callbk_fns) +{ + struct nrf_wifi_osal_priv *opriv = NULL; + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_hal_cfg_params hal_cfg_params; + unsigned int pool_idx = 0; + unsigned int desc = 0; + + opriv = nrf_wifi_osal_init(); + + if (!opriv) { + goto out; + } + + fpriv = nrf_wifi_osal_mem_zalloc(opriv, + sizeof(*fpriv) + sizeof(*def_priv)); + + if (!fpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate fpriv\n", + __func__); + goto out; + } + fpriv->opriv = opriv; + + def_priv = wifi_fmac_priv(fpriv); + + nrf_wifi_osal_mem_set(opriv, + &hal_cfg_params, + 0, + sizeof(hal_cfg_params)); + + nrf_wifi_osal_mem_cpy(opriv, + &def_priv->callbk_fns, + callbk_fns, + sizeof(def_priv->callbk_fns)); + + nrf_wifi_osal_mem_cpy(opriv, + &def_priv->data_config, + data_config, + sizeof(def_priv->data_config)); + +#ifdef CONFIG_NRF700X_DATA_TX + def_priv->num_tx_tokens = CONFIG_NRF700X_MAX_TX_TOKENS; + def_priv->num_tx_tokens_per_ac = (def_priv->num_tx_tokens / NRF_WIFI_FMAC_AC_MAX); + def_priv->num_tx_tokens_spare = (def_priv->num_tx_tokens % NRF_WIFI_FMAC_AC_MAX); +#endif /* CONFIG_NRF700X_DATA_TX */ + nrf_wifi_osal_mem_cpy(opriv, + def_priv->rx_buf_pools, + rx_buf_pools, + sizeof(def_priv->rx_buf_pools)); + + for (pool_idx = 0; pool_idx < MAX_NUM_OF_RX_QUEUES; pool_idx++) { + def_priv->rx_desc[pool_idx] = desc; + + desc += def_priv->rx_buf_pools[pool_idx].num_bufs; + } + + def_priv->num_rx_bufs = desc; + + hal_cfg_params.rx_buf_headroom_sz = RX_BUF_HEADROOM; + hal_cfg_params.tx_buf_headroom_sz = TX_BUF_HEADROOM; +#ifdef CONFIG_NRF700X_DATA_TX + hal_cfg_params.max_tx_frms = (def_priv->num_tx_tokens * + def_priv->data_config.max_tx_aggregation); +#endif /* CONFIG_NRF700X_DATA_TX */ + + for (pool_idx = 0; pool_idx < MAX_NUM_OF_RX_QUEUES; pool_idx++) { + hal_cfg_params.rx_buf_pool[pool_idx].num_bufs = + def_priv->rx_buf_pools[pool_idx].num_bufs; + hal_cfg_params.rx_buf_pool[pool_idx].buf_sz = + def_priv->rx_buf_pools[pool_idx].buf_sz + RX_BUF_HEADROOM; + } + + hal_cfg_params.max_tx_frm_sz = CONFIG_NRF700X_TX_MAX_DATA_SIZE + TX_BUF_HEADROOM; + + hal_cfg_params.max_cmd_size = MAX_NRF_WIFI_UMAC_CMD_SIZE; + hal_cfg_params.max_event_size = MAX_EVENT_POOL_LEN; + + fpriv->hpriv = nrf_wifi_hal_init(opriv, + &hal_cfg_params, + &nrf_wifi_fmac_event_callback); + + if (!fpriv->hpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to do HAL init\n", + __func__); + nrf_wifi_osal_mem_free(opriv, + fpriv); + fpriv = NULL; + def_priv = NULL; + nrf_wifi_osal_deinit(opriv); + opriv = NULL; + goto out; + } +out: + return fpriv; +} + + +void nrf_wifi_fmac_deinit(struct nrf_wifi_fmac_priv *fpriv) +{ + struct nrf_wifi_osal_priv *opriv = NULL; + + opriv = fpriv->opriv; + + nrf_wifi_hal_deinit(fpriv->hpriv); + + nrf_wifi_osal_mem_free(opriv, + fpriv); + + nrf_wifi_osal_deinit(opriv); +} + +enum nrf_wifi_status nrf_wifi_fmac_scan(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_scan_info *scan_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_scan *scan_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + int channel_info_len = (sizeof(struct nrf_wifi_channel) * + scan_info->scan_params.num_scan_channels); + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (def_dev_ctx->vif_ctx[if_idx]->if_type == NRF_WIFI_IFTYPE_AP) { + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "%s: Scan operation not supported in AP mode\n", + __func__); + goto out; + } + + scan_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + (sizeof(*scan_cmd) + channel_info_len)); + + if (!scan_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + scan_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_TRIGGER_SCAN; + scan_cmd->umac_hdr.ids.wdev_id = if_idx; + scan_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &scan_cmd->info, + scan_info, + (sizeof(scan_cmd->info) + channel_info_len)); + + status = umac_cmd_cfg(fmac_dev_ctx, + scan_cmd, + sizeof(*scan_cmd) + channel_info_len); +out: + if (scan_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + scan_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_abort_scan(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_abort_scan *scan_abort_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (def_dev_ctx->vif_ctx[if_idx]->if_type == NRF_WIFI_IFTYPE_AP) { + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "%s: Scan operation not supported in AP mode\n", + __func__); + goto out; + } + + scan_abort_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*scan_abort_cmd)); + + if (!scan_abort_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + scan_abort_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_ABORT_SCAN; + scan_abort_cmd->umac_hdr.ids.wdev_id = if_idx; + scan_abort_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + scan_abort_cmd, + sizeof(*scan_abort_cmd)); +out: + if (scan_abort_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + scan_abort_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_scan_res_get(void *dev_ctx, + unsigned char vif_idx, + int scan_type) + +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_get_scan_results *scan_res_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (def_dev_ctx->vif_ctx[vif_idx]->if_type == NRF_WIFI_IFTYPE_AP) { + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "%s: Scan operation not supported in AP mode\n", + __func__); + goto out; + } + + scan_res_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*scan_res_cmd)); + + if (!scan_res_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + scan_res_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_SCAN_RESULTS; + scan_res_cmd->umac_hdr.ids.wdev_id = vif_idx; + scan_res_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + scan_res_cmd->scan_reason = scan_type; + + status = umac_cmd_cfg(fmac_dev_ctx, + scan_res_cmd, + sizeof(*scan_res_cmd)); +out: + if (scan_res_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + scan_res_cmd); + } + + return status; +} + +#ifdef CONFIG_NRF700X_STA_MODE +enum nrf_wifi_status nrf_wifi_fmac_auth(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_auth_info *auth_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_auth *auth_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + auth_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*auth_cmd)); + + if (!auth_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + auth_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_AUTHENTICATE; + auth_cmd->umac_hdr.ids.wdev_id = if_idx; + auth_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &auth_cmd->info, + auth_info, + sizeof(auth_cmd->info)); + + if (auth_info->frequency != 0) { + auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_FREQ_VALID; + } + + if (auth_info->ssid.nrf_wifi_ssid_len > 0) { + auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_SSID_VALID; + } + + if (auth_info->key_info.key.nrf_wifi_key_len > 0) { + auth_cmd->info.key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID; + auth_cmd->info.key_info.valid_fields |= NRF_WIFI_KEY_VALID; + auth_cmd->info.key_info.valid_fields |= NRF_WIFI_CIPHER_SUITE_VALID; + + auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_KEY_INFO_VALID; + } + + if (auth_info->sae.sae_data_len > 0) { + auth_cmd->valid_fields |= NRF_WIFI_CMD_AUTHENTICATE_SAE_VALID; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + auth_cmd, + sizeof(*auth_cmd)); +out: + if (auth_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + auth_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_deauth(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_disconn_info *deauth_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_disconn *deauth_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + deauth_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*deauth_cmd)); + + if (!deauth_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + deauth_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEAUTHENTICATE; + deauth_cmd->umac_hdr.ids.wdev_id = if_idx; + deauth_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &deauth_cmd->info, + deauth_info, + sizeof(deauth_cmd->info)); + + if (!nrf_wifi_util_is_arr_zero(deauth_info->mac_addr, + sizeof(deauth_info->mac_addr))) { + deauth_cmd->valid_fields |= NRF_WIFI_CMD_MLME_MAC_ADDR_VALID; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + deauth_cmd, + sizeof(*deauth_cmd)); + +out: + if (deauth_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + deauth_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_assoc(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_assoc_info *assoc_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_assoc *assoc_cmd = NULL; + struct nrf_wifi_connect_common_info *connect_common_info = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + vif_ctx->bssid, + assoc_info->nrf_wifi_bssid, + NRF_WIFI_ETH_ADDR_LEN); + + assoc_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*assoc_cmd)); + + if (!assoc_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + assoc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_ASSOCIATE; + assoc_cmd->umac_hdr.ids.wdev_id = if_idx; + assoc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + connect_common_info = &assoc_cmd->connect_common_info; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + connect_common_info->mac_addr, + assoc_info->nrf_wifi_bssid, + NRF_WIFI_ETH_ADDR_LEN); + + if (!nrf_wifi_util_is_arr_zero(connect_common_info->mac_addr, + sizeof(connect_common_info->mac_addr))) { + connect_common_info->valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_MAC_ADDR_VALID; + } + + if (assoc_info->ssid.nrf_wifi_ssid_len > 0) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &connect_common_info->ssid, + &assoc_info->ssid, + sizeof(connect_common_info->ssid)); + + connect_common_info->valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_SSID_VALID; + } + + connect_common_info->frequency = assoc_info->center_frequency; + connect_common_info->valid_fields |= NRF_WIFI_CONNECT_COMMON_INFO_FREQ_VALID; + + if (assoc_info->wpa_ie.ie_len > 0) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &connect_common_info->wpa_ie, + &assoc_info->wpa_ie, + sizeof(connect_common_info->wpa_ie)); + + connect_common_info->valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_WPA_IE_VALID; + } + + connect_common_info->use_mfp = assoc_info->use_mfp; + connect_common_info->valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_USE_MFP_VALID; + + connect_common_info->nrf_wifi_flags |= + NRF_WIFI_CMD_CONNECT_COMMON_INFO_USE_RRM; + + connect_common_info->control_port = + assoc_info->control_port; + + if (assoc_info->prev_bssid_flag) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + connect_common_info->prev_bssid, + assoc_info->prev_bssid, + NRF_WIFI_ETH_ADDR_LEN); + connect_common_info->nrf_wifi_flags |= NRF_WIFI_CONNECT_COMMON_INFO_PREV_BSSID; + } + + if (assoc_info->bss_max_idle_time) { + connect_common_info->maxidle_insec = assoc_info->bss_max_idle_time; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + assoc_cmd, + sizeof(*assoc_cmd)); +out: + if (assoc_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + assoc_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_disassoc(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_disconn_info *disassoc_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_disconn *disassoc_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + disassoc_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*disassoc_cmd)); + + if (!disassoc_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + disassoc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEAUTHENTICATE; + disassoc_cmd->umac_hdr.ids.wdev_id = if_idx; + disassoc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &disassoc_cmd->info, + disassoc_info, + sizeof(disassoc_cmd->info)); + + if (!nrf_wifi_util_is_arr_zero(disassoc_info->mac_addr, + sizeof(disassoc_info->mac_addr))) { + disassoc_cmd->valid_fields |= NRF_WIFI_CMD_MLME_MAC_ADDR_VALID; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + disassoc_cmd, + sizeof(*disassoc_cmd)); + +out: + if (disassoc_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + disassoc_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_add_key(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_key_info *key_info, + const char *mac_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_key *key_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + int peer_id = -1; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + key_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*key_cmd)); + + if (!key_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + key_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_NEW_KEY; + key_cmd->umac_hdr.ids.wdev_id = if_idx; + key_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &key_cmd->key_info, + key_info, + sizeof(key_cmd->key_info)); + + if (mac_addr) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + key_cmd->mac_addr, + mac_addr, + NRF_WIFI_ETH_ADDR_LEN); + + key_cmd->valid_fields |= NRF_WIFI_CMD_KEY_MAC_ADDR_VALID; + } + + if (key_info->key_type == NRF_WIFI_KEYTYPE_GROUP) { + vif_ctx->groupwise_cipher = key_info->cipher_suite; + } else if (key_info->key_type == NRF_WIFI_KEYTYPE_PAIRWISE) { + peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, + mac_addr); + + if (peer_id == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid peer\n", + __func__); + goto out; + } + + def_dev_ctx->tx_config.peers[peer_id].pairwise_cipher = key_info->cipher_suite; + } else { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid key type %d\n", + __func__, + key_info->key_type); + goto out; + } + + if (key_info->key.nrf_wifi_key_len > 0) { + key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_VALID; + key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID; + } + + if (key_info->seq.nrf_wifi_seq_len > 0) { + key_cmd->key_info.valid_fields |= NRF_WIFI_SEQ_VALID; + } + + key_cmd->key_info.valid_fields |= NRF_WIFI_CIPHER_SUITE_VALID; + key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_TYPE_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + key_cmd, + sizeof(*key_cmd)); + +out: + if (key_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + key_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_del_key(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_key_info *key_info, + const char *mac_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_key *key_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + key_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*key_cmd)); + + if (!key_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + key_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEL_KEY; + key_cmd->umac_hdr.ids.wdev_id = if_idx; + key_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &key_cmd->key_info, + key_info, + sizeof(key_cmd->key_info)); + + if (mac_addr) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + key_cmd->mac_addr, + mac_addr, + NRF_WIFI_ETH_ADDR_LEN); + + key_cmd->valid_fields |= NRF_WIFI_CMD_KEY_MAC_ADDR_VALID; + } + + key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID; + key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_TYPE_VALID; + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + if (key_info->key_type == NRF_WIFI_KEYTYPE_GROUP) { + vif_ctx->groupwise_cipher = 0; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + key_cmd, + sizeof(*key_cmd)); + +out: + if (key_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + key_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_key(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_key_info *key_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_key *set_key_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_key_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_key_cmd)); + + if (!set_key_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_key_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_KEY; + set_key_cmd->umac_hdr.ids.wdev_id = if_idx; + set_key_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &set_key_cmd->key_info, + key_info, + sizeof(set_key_cmd->key_info)); + + set_key_cmd->key_info.valid_fields |= NRF_WIFI_KEY_IDX_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + set_key_cmd, + sizeof(*set_key_cmd)); + +out: + if (set_key_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_key_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_chg_sta(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_chg_sta_info *chg_sta_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_chg_sta *chg_sta_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + chg_sta_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*chg_sta_cmd)); + + if (!chg_sta_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + chg_sta_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_STATION; + chg_sta_cmd->umac_hdr.ids.wdev_id = if_idx; + chg_sta_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &chg_sta_cmd->info, + chg_sta_info, + sizeof(chg_sta_cmd->info)); + + if (chg_sta_info->aid) { + chg_sta_cmd->valid_fields |= + NRF_WIFI_CMD_SET_STATION_AID_VALID; + } + + + if (chg_sta_info->supported_channels.supported_channels_len > 0) { + chg_sta_cmd->valid_fields |= + NRF_WIFI_CMD_SET_STATION_SUPPORTED_CHANNELS_VALID; + } + + if (chg_sta_info->supported_oper_classes.supported_oper_classes_len > 0) { + chg_sta_cmd->valid_fields |= + NRF_WIFI_CMD_SET_STATION_SUPPORTED_OPER_CLASSES_VALID; + } + + chg_sta_cmd->valid_fields |= NRF_WIFI_CMD_SET_STATION_STA_FLAGS2_VALID; + + if (chg_sta_info->opmode_notif) { + chg_sta_cmd->valid_fields |= + NRF_WIFI_CMD_SET_STATION_OPMODE_NOTIF_VALID; + } + + if (chg_sta_info->wme_max_sp) { + chg_sta_cmd->valid_fields |= + NRF_WIFI_CMD_SET_STATION_STA_WME_MAX_SP_VALID; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + chg_sta_cmd, + sizeof(*chg_sta_cmd)); + +out: + if (chg_sta_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + chg_sta_cmd); + } + + return status; +} + +#ifdef CONFIG_NRF700X_AP_MODE +enum nrf_wifi_status nrf_wifi_fmac_set_bss(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_bss_info *bss_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_bss *set_bss_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_bss_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_bss_cmd)); + + if (!set_bss_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_bss_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_BSS; + set_bss_cmd->umac_hdr.ids.wdev_id = if_idx; + set_bss_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &set_bss_cmd->bss_info, + bss_info, + sizeof(set_bss_cmd->bss_info)); + + set_bss_cmd->valid_fields = NRF_WIFI_CMD_SET_BSS_CTS_VALID | + NRF_WIFI_CMD_SET_BSS_PREAMBLE_VALID | + NRF_WIFI_CMD_SET_BSS_SLOT_VALID | + NRF_WIFI_CMD_SET_BSS_HT_OPMODE_VALID | + NRF_WIFI_CMD_SET_BSS_AP_ISOLATE_VALID; + + if ((bss_info->p2p_go_ctwindow > 0) && + (bss_info->p2p_go_ctwindow < 127)) { + set_bss_cmd->valid_fields |= + (NRF_WIFI_CMD_SET_BSS_P2P_CTWINDOW_VALID | + NRF_WIFI_CMD_SET_BSS_P2P_OPPPS_VALID); + } + + status = umac_cmd_cfg(fmac_dev_ctx, + set_bss_cmd, + sizeof(*set_bss_cmd)); + +out: + if (set_bss_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_bss_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_chg_bcn(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_set_beacon_info *data) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_beacon *set_bcn_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_bcn_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_bcn_cmd)); + + if (!set_bcn_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + set_bcn_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_BEACON; + set_bcn_cmd->umac_hdr.ids.wdev_id = if_idx; + set_bcn_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &set_bcn_cmd->info, + data, + sizeof(set_bcn_cmd->info)); + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Sending command to rpu\n", + __func__); + + status = umac_cmd_cfg(fmac_dev_ctx, + set_bcn_cmd, + sizeof(*set_bcn_cmd)); + +out: + if (set_bcn_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_bcn_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_start_ap(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_start_ap_info *ap_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_start_ap *start_ap_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_umac_set_wiphy_info *wiphy_info = NULL; + + fmac_dev_ctx = dev_ctx; + + start_ap_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*start_ap_cmd)); + + if (!start_ap_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + start_ap_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_START_AP; + start_ap_cmd->umac_hdr.ids.wdev_id = if_idx; + start_ap_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &start_ap_cmd->info, + ap_info, + sizeof(start_ap_cmd->info)); + + start_ap_cmd->valid_fields |= + NRF_WIFI_CMD_BEACON_INFO_BEACON_INTERVAL_VALID | + NRF_WIFI_CMD_BEACON_INFO_VERSIONS_VALID | + NRF_WIFI_CMD_BEACON_INFO_CIPHER_SUITE_GROUP_VALID; + + start_ap_cmd->info.freq_params.valid_fields |= + NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID; + + start_ap_cmd->info.connect_common_info.valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_WPA_VERSIONS_VALID; + + if (ap_info->connect_common_info.num_cipher_suites_pairwise > 0) { + start_ap_cmd->info.connect_common_info.valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_CIPHER_SUITES_PAIRWISE_VALID; + } + + if (ap_info->connect_common_info.num_akm_suites > 0) { + start_ap_cmd->info.connect_common_info.valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_AKM_SUITES_VALID; + } + + if (ap_info->connect_common_info.control_port_ether_type) { + start_ap_cmd->info.connect_common_info.valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_CONTROL_PORT_ETHER_TYPE; + } + + if (ap_info->connect_common_info.control_port_no_encrypt) { + start_ap_cmd->info.connect_common_info.valid_fields |= + NRF_WIFI_CONNECT_COMMON_INFO_CONTROL_PORT_NO_ENCRYPT; + } + + if ((ap_info->p2p_go_ctwindow > 0) && + (ap_info->p2p_go_ctwindow < 127)) { + start_ap_cmd->valid_fields |= + NRF_WIFI_CMD_BEACON_INFO_P2P_CTWINDOW_VALID; + start_ap_cmd->valid_fields |= + NRF_WIFI_CMD_BEACON_INFO_P2P_OPPPS_VALID; + } + + wiphy_info = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*wiphy_info)); + + if (!wiphy_info) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + wiphy_info->freq_params.frequency = ap_info->freq_params.frequency; + + wiphy_info->freq_params.channel_width = ap_info->freq_params.channel_width; + + wiphy_info->freq_params.center_frequency1 = ap_info->freq_params.center_frequency1; + wiphy_info->freq_params.center_frequency2 = ap_info->freq_params.center_frequency2; + + wiphy_info->freq_params.channel_type = ap_info->freq_params.channel_type; + + status = nrf_wifi_fmac_set_wiphy_params(fmac_dev_ctx, + if_idx, + wiphy_info); + + if (status == NRF_WIFI_STATUS_FAIL) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_set_wiphy_params failes\n", + __func__); + goto out; + } + + nrf_wifi_fmac_peers_flush(fmac_dev_ctx, if_idx); + + status = umac_cmd_cfg(fmac_dev_ctx, + start_ap_cmd, + sizeof(*start_ap_cmd)); + +out: + if (wiphy_info) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + wiphy_info); + } + + if (start_ap_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + start_ap_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_stop_ap(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_stop_ap *stop_ap_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + stop_ap_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*stop_ap_cmd)); + + if (!stop_ap_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + stop_ap_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_STOP_AP; + stop_ap_cmd->umac_hdr.ids.wdev_id = if_idx; + stop_ap_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_fmac_peers_flush(fmac_dev_ctx, if_idx); + + status = umac_cmd_cfg(fmac_dev_ctx, + stop_ap_cmd, + sizeof(*stop_ap_cmd)); + +out: + if (stop_ap_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + stop_ap_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_del_sta(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_del_sta_info *del_sta_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_del_sta *del_sta_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + del_sta_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*del_sta_cmd)); + + if (!del_sta_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + del_sta_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEL_STATION; + del_sta_cmd->umac_hdr.ids.wdev_id = if_idx; + del_sta_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &del_sta_cmd->info, + del_sta_info, + sizeof(del_sta_cmd->info)); + + if (!nrf_wifi_util_is_arr_zero(del_sta_info->mac_addr, + sizeof(del_sta_info->mac_addr))) { + del_sta_cmd->valid_fields |= NRF_WIFI_CMD_DEL_STATION_MAC_ADDR_VALID; + } + + if (del_sta_info->mgmt_subtype) { + del_sta_cmd->valid_fields |= + NRF_WIFI_CMD_DEL_STATION_MGMT_SUBTYPE_VALID; + } + + if (del_sta_info->reason_code) { + del_sta_cmd->valid_fields |= + NRF_WIFI_CMD_DEL_STATION_REASON_CODE_VALID; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + del_sta_cmd, + sizeof(*del_sta_cmd)); + +out: + if (del_sta_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + del_sta_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_add_sta(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_add_sta_info *add_sta_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_add_sta *add_sta_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + add_sta_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*add_sta_cmd)); + + if (!add_sta_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + add_sta_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_NEW_STATION; + add_sta_cmd->umac_hdr.ids.wdev_id = if_idx; + add_sta_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &add_sta_cmd->info, + add_sta_info, + sizeof(add_sta_cmd->info)); + + if (add_sta_info->aid) { + add_sta_cmd->valid_fields |= NRF_WIFI_CMD_NEW_STATION_AID_VALID; + } + + if (add_sta_info->sta_capability) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_STA_CAPABILITY_VALID; + } + + add_sta_cmd->valid_fields |= NRF_WIFI_CMD_NEW_STATION_LISTEN_INTERVAL_VALID; + + if (add_sta_info->supp_rates.nrf_wifi_num_rates > 0) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_SUPP_RATES_VALID; + } + + if (add_sta_info->ext_capability.ext_capability_len > 0) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_EXT_CAPABILITY_VALID; + } + + if (add_sta_info->supported_channels.supported_channels_len > 0) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_SUPPORTED_CHANNELS_VALID; + } + + if (add_sta_info->supported_oper_classes.supported_oper_classes_len > 0) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_SUPPORTED_OPER_CLASSES_VALID; + } + + add_sta_cmd->valid_fields |= NRF_WIFI_CMD_NEW_STATION_STA_FLAGS2_VALID; + + if (!nrf_wifi_util_is_arr_zero(add_sta_info->ht_capability, + sizeof(add_sta_info->ht_capability))) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_HT_CAPABILITY_VALID; + } + + if (!nrf_wifi_util_is_arr_zero(add_sta_info->vht_capability, + sizeof(add_sta_info->vht_capability))) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_VHT_CAPABILITY_VALID; + } + + if (add_sta_info->opmode_notif) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_OPMODE_NOTIF_VALID; + } + + if (add_sta_info->wme_uapsd_queues) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_STA_WME_UAPSD_QUEUES_VALID; + } + + if (add_sta_info->wme_max_sp) { + add_sta_cmd->valid_fields |= + NRF_WIFI_CMD_NEW_STATION_STA_WME_MAX_SP_VALID; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + add_sta_cmd, + sizeof(*add_sta_cmd)); + +out: + if (add_sta_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + add_sta_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_mgmt_frame_reg(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_mgmt_frame_info *frame_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_mgmt_frame_reg *frame_reg_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + frame_reg_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*frame_reg_cmd)); + + if (!frame_reg_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + frame_reg_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REGISTER_FRAME; + frame_reg_cmd->umac_hdr.ids.wdev_id = if_idx; + frame_reg_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &frame_reg_cmd->info, + frame_info, + sizeof(frame_reg_cmd->info)); + + status = umac_cmd_cfg(fmac_dev_ctx, + frame_reg_cmd, + sizeof(*frame_reg_cmd)); + +out: + if (frame_reg_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + frame_reg_cmd); + } + + return status; +} + +#endif /* CONFIG_NRF700X_AP_MODE */ + +#ifdef CONFIG_NRF700X_P2P_MODE +enum nrf_wifi_status nrf_wifi_fmac_p2p_dev_start(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_cmd_start_p2p *start_p2p_dev_cmd = NULL; + const struct nrf_wifi_osal_ops *osal_ops = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + osal_ops = fmac_dev_ctx->fpriv->opriv->ops; + + start_p2p_dev_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*start_p2p_dev_cmd)); + + if (!start_p2p_dev_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + start_p2p_dev_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_START_P2P_DEVICE; + start_p2p_dev_cmd->umac_hdr.ids.wdev_id = if_idx; + start_p2p_dev_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + start_p2p_dev_cmd, + sizeof(*start_p2p_dev_cmd)); + +out: + if (start_p2p_dev_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + start_p2p_dev_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_p2p_dev_stop(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_stop_p2p_dev *stop_p2p_dev_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + stop_p2p_dev_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*stop_p2p_dev_cmd)); + + if (!stop_p2p_dev_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + stop_p2p_dev_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_STOP_P2P_DEVICE; + stop_p2p_dev_cmd->umac_hdr.ids.wdev_id = if_idx; + stop_p2p_dev_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + stop_p2p_dev_cmd, + sizeof(*stop_p2p_dev_cmd)); +out: + if (stop_p2p_dev_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + stop_p2p_dev_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_p2p_roc_start(void *dev_ctx, + unsigned char if_idx, + struct remain_on_channel_info *roc_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_remain_on_channel *roc_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + roc_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(struct nrf_wifi_umac_cmd_remain_on_channel)); + + if (!roc_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + roc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REMAIN_ON_CHANNEL; + roc_cmd->umac_hdr.ids.wdev_id = if_idx; + roc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &roc_cmd->info, + roc_info, + sizeof(roc_cmd->info)); + + if (roc_info->dur != 0) { + roc_cmd->valid_fields |= NRF_WIFI_CMD_ROC_DURATION_VALID; + } + + roc_cmd->info.nrf_wifi_freq_params.valid_fields = NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID; + roc_cmd->valid_fields |= NRF_WIFI_CMD_ROC_FREQ_PARAMS_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + roc_cmd, + sizeof(*roc_cmd)); + +out: + if (roc_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + roc_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_p2p_roc_stop(void *dev_ctx, + unsigned char if_idx, + unsigned long long cookie) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_cancel_remain_on_channel *cancel_roc_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + cancel_roc_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cancel_roc_cmd)); + + if (!cancel_roc_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + cancel_roc_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CANCEL_REMAIN_ON_CHANNEL; + cancel_roc_cmd->umac_hdr.ids.wdev_id = if_idx; + cancel_roc_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + cancel_roc_cmd->cookie = cookie; + cancel_roc_cmd->valid_fields |= NRF_WIFI_CMD_CANCEL_ROC_COOKIE_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + cancel_roc_cmd, + sizeof(*cancel_roc_cmd)); +out: + if (cancel_roc_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cancel_roc_cmd); + } + + return status; +} + +#endif /* CONFIG_NRF700X_P2P_MODE */ +#endif /* CONFIG_NRF700X_STA_MODE */ + +enum nrf_wifi_status nrf_wifi_fmac_mgmt_tx(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_mgmt_tx_info *mgmt_tx_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_mgmt_tx *mgmt_tx_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + mgmt_tx_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*mgmt_tx_cmd)); + + if (!mgmt_tx_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + mgmt_tx_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_FRAME; + mgmt_tx_cmd->umac_hdr.ids.wdev_id = if_idx; + mgmt_tx_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &mgmt_tx_cmd->info, + mgmt_tx_info, + sizeof(mgmt_tx_cmd->info)); + + mgmt_tx_cmd->valid_fields |= (NRF_WIFI_CMD_FRAME_FREQ_VALID | + NRF_WIFI_CMD_FRAME_DURATION_VALID | + NRF_WIFI_CMD_SET_FRAME_FREQ_PARAMS_VALID); + + mgmt_tx_cmd->info.freq_params.valid_fields |= + (NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID | + NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID); + + status = umac_cmd_cfg(fmac_dev_ctx, + mgmt_tx_cmd, + sizeof(*mgmt_tx_cmd)); + +out: + if (mgmt_tx_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + mgmt_tx_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_mac_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *addr) +{ + unsigned char vif_idx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + vif_idx = nrf_wifi_fmac_vif_idx_get(fmac_dev_ctx); + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (vif_idx == MAX_NUM_VIFS) { + return NRF_WIFI_STATUS_FAIL; + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + addr, + def_dev_ctx->vif_ctx[vif_idx]->mac_addr, + NRF_WIFI_ETH_ADDR_LEN); + + if (((unsigned short)addr[5] + vif_idx) > 0xff) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: MAC Address rollover!!\n", + __func__); + } + + addr[5] += vif_idx; + + return NRF_WIFI_STATUS_SUCCESS; +} + + +unsigned char nrf_wifi_fmac_add_vif(void *dev_ctx, + void *os_vif_ctx, + struct nrf_wifi_umac_add_vif_info *vif_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_add_vif *add_vif_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + unsigned char vif_idx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + switch (vif_info->iftype) { + case NRF_WIFI_IFTYPE_STATION: + case NRF_WIFI_IFTYPE_P2P_CLIENT: + case NRF_WIFI_IFTYPE_AP: + case NRF_WIFI_IFTYPE_P2P_GO: + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: VIF type not supported\n", + __func__); + goto err; + } + + if (nrf_wifi_fmac_vif_check_if_limit(fmac_dev_ctx, + vif_info->iftype)) { + goto err; + } + + vif_ctx = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*vif_ctx)); + + if (!vif_ctx) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory for VIF ctx\n", + __func__); + goto err; + } + + vif_ctx->fmac_dev_ctx = fmac_dev_ctx; + vif_ctx->os_vif_ctx = os_vif_ctx; + vif_ctx->if_type = vif_info->iftype; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + vif_ctx->mac_addr, + vif_info->mac_addr, + sizeof(vif_ctx->mac_addr)); + + vif_idx = nrf_wifi_fmac_vif_idx_get(fmac_dev_ctx); + + if (vif_idx == MAX_NUM_VIFS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to add additional VIF\n", + __func__); + goto err; + } + + /* We don't need to send a command to the RPU for the default interface, + * since the FW is adding that interface by default. We just need to + * send commands for non-default interfaces + */ + if (vif_idx != 0) { + add_vif_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*add_vif_cmd)); + + if (!add_vif_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory for cmd\n", + __func__); + goto err; + } + + add_vif_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_NEW_INTERFACE; + add_vif_cmd->umac_hdr.ids.wdev_id = vif_idx; + add_vif_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &add_vif_cmd->info, + vif_info, + sizeof(add_vif_cmd->info)); + + add_vif_cmd->valid_fields |= NRF_WIFI_CMD_NEW_INTERFACE_IFTYPE_VALID; + add_vif_cmd->valid_fields |= NRF_WIFI_CMD_NEW_INTERFACE_IFNAME_VALID; + add_vif_cmd->valid_fields |= NRF_WIFI_CMD_NEW_INTERFACE_MAC_ADDR_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + add_vif_cmd, + sizeof(*add_vif_cmd)); + + if (status == NRF_WIFI_STATUS_FAIL) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: NRF_WIFI_UMAC_CMD_NEW_INTERFACE failed\n", + __func__); + goto err; + } + + } + + def_dev_ctx->vif_ctx[vif_idx] = vif_ctx; + + nrf_wifi_fmac_vif_incr_if_type(fmac_dev_ctx, + vif_ctx->if_type); + + goto out; +err: + if (vif_ctx) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + vif_ctx); + } + + vif_idx = MAX_NUM_VIFS; + +out: + if (add_vif_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + add_vif_cmd); + } + + return vif_idx; +} + + +enum nrf_wifi_status nrf_wifi_fmac_del_vif(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_umac_cmd_del_vif *del_vif_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + switch (def_dev_ctx->vif_ctx[if_idx]->if_type) { + case NRF_WIFI_IFTYPE_STATION: + case NRF_WIFI_IFTYPE_P2P_CLIENT: + case NRF_WIFI_IFTYPE_AP: + case NRF_WIFI_IFTYPE_P2P_GO: + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: VIF type not supported\n", + __func__); + goto out; + } + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + if (!vif_ctx) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: VIF ctx does not exist\n", + __func__); + goto out; + } + + /* We should not send a command to the RPU for the default interface, + * since the FW is adding that interface by default. We just need to + * send commands for non-default interfaces + */ + if (if_idx != 0) { + del_vif_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*del_vif_cmd)); + + if (!del_vif_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory for cmd\n", + __func__); + goto out; + } + + del_vif_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_DEL_INTERFACE; + del_vif_cmd->umac_hdr.ids.wdev_id = if_idx; + del_vif_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + del_vif_cmd, + sizeof(*del_vif_cmd)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: NRF_WIFI_UMAC_CMD_DEL_INTERFACE failed\n", + __func__); + goto out; + } + } else { + status = NRF_WIFI_STATUS_SUCCESS; + } + + nrf_wifi_fmac_vif_decr_if_type(fmac_dev_ctx, vif_ctx->if_type); + +out: + if (del_vif_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + del_vif_cmd); + } + + if (vif_ctx) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + vif_ctx); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_chg_vif(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_chg_vif_attr_info *vif_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_chg_vif_attr *chg_vif_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + switch (vif_info->iftype) { + case NRF_WIFI_IFTYPE_STATION: + case NRF_WIFI_IFTYPE_P2P_CLIENT: + case NRF_WIFI_IFTYPE_AP: + case NRF_WIFI_IFTYPE_P2P_GO: + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: VIF type not supported\n", __func__); + goto out; + } + + if (nrf_wifi_fmac_vif_check_if_limit(fmac_dev_ctx, + vif_info->iftype)) { + goto out; + } + + chg_vif_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*chg_vif_cmd)); + + if (!chg_vif_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + chg_vif_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_INTERFACE; + chg_vif_cmd->umac_hdr.ids.wdev_id = if_idx; + chg_vif_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &chg_vif_cmd->info, + vif_info, + sizeof(chg_vif_cmd->info)); + + chg_vif_cmd->valid_fields |= NRF_WIFI_SET_INTERFACE_IFTYPE_VALID; + chg_vif_cmd->valid_fields |= NRF_WIFI_SET_INTERFACE_USE_4ADDR_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + chg_vif_cmd, + sizeof(*chg_vif_cmd)); +out: + if (chg_vif_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + chg_vif_cmd); + } + + return status; +} + + +#define RPU_CMD_TIMEOUT_MS 10000 +enum nrf_wifi_status nrf_wifi_fmac_chg_vif_state(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_chg_vif_state_info *vif_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_chg_vif_state *chg_vif_state_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + unsigned int count = RPU_CMD_TIMEOUT_MS; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + chg_vif_state_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*chg_vif_state_cmd)); + + if (!chg_vif_state_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + chg_vif_state_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_IFFLAGS; + chg_vif_state_cmd->umac_hdr.ids.wdev_id = if_idx; + chg_vif_state_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &chg_vif_state_cmd->info, + vif_info, + sizeof(chg_vif_state_cmd->info)); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + vif_ctx->ifflags = false; + + status = umac_cmd_cfg(fmac_dev_ctx, + chg_vif_state_cmd, + sizeof(*chg_vif_state_cmd)); + + while (!vif_ctx->ifflags && (--count > 0)) + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, 1); + + if (count == 0) { + status = NRF_WIFI_STATUS_FAIL; + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: RPU is unresponsive for %d sec\n", + __func__, RPU_CMD_TIMEOUT_MS / 1000); + goto out; + } +#ifdef CONFIG_NRF700X_AP_MODE + if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) { + if (vif_info->state == 1) { + def_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = MAX_PEERS; + def_dev_ctx->tx_config.peers[MAX_PEERS].if_idx = if_idx; + } else if (vif_info->state == 0) { + def_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = -1; + def_dev_ctx->tx_config.peers[MAX_PEERS].if_idx = if_idx; + } + } +#endif /* CONFIG_NRF700X_AP_MODE */ +out: + if (chg_vif_state_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + chg_vif_state_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_vif_macaddr(void *dev_ctx, + unsigned char if_idx, + unsigned char *mac_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_umac_cmd_change_macaddr *cmd = NULL; + + if (!dev_ctx) { + goto out; + } + + if (!mac_addr) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid MAC address\n", + __func__); + goto out; + } + + fmac_dev_ctx = dev_ctx; + + cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cmd)); + + if (!cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate cmd\n", + __func__); + goto out; + } + + cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CHANGE_MACADDR; + cmd->umac_hdr.ids.wdev_id = if_idx; + cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + cmd->macaddr_info.mac_addr, + mac_addr, + sizeof(cmd->macaddr_info.mac_addr)); + + status = umac_cmd_cfg(fmac_dev_ctx, + cmd, + sizeof(*cmd)); +out: + if (cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_set_wiphy_params(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_set_wiphy_info *wiphy_info) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_umac_cmd_set_wiphy *set_wiphy_cmd = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + int freq_params_valid = 0; + + if (!dev_ctx) { + goto out; + } + + fmac_dev_ctx = dev_ctx; + + if (!wiphy_info) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: wiphy_info: Invalid memory\n", + __func__); + goto out; + } + + set_wiphy_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_wiphy_cmd)); + + if (!set_wiphy_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_wiphy_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_WIPHY; + set_wiphy_cmd->umac_hdr.ids.wdev_id = if_idx; + set_wiphy_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + if (wiphy_info->freq_params.frequency) { + freq_params_valid = 1; + wiphy_info->freq_params.valid_fields |= + NRF_WIFI_SET_FREQ_PARAMS_FREQ_VALID; + } + + if (wiphy_info->freq_params.channel_width) { + freq_params_valid = 1; + wiphy_info->freq_params.valid_fields |= + NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_WIDTH_VALID; + } + + if (wiphy_info->freq_params.center_frequency1) { + freq_params_valid = 1; + wiphy_info->freq_params.valid_fields |= + NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ1_VALID; + } + + if (wiphy_info->freq_params.center_frequency2) { + freq_params_valid = 1; + wiphy_info->freq_params.valid_fields |= + NRF_WIFI_SET_FREQ_PARAMS_CENTER_FREQ2_VALID; + } + + if (wiphy_info->freq_params.channel_type) { + freq_params_valid = 1; + wiphy_info->freq_params.valid_fields |= + NRF_WIFI_SET_FREQ_PARAMS_CHANNEL_TYPE_VALID; + } + + if (freq_params_valid) { + set_wiphy_cmd->valid_fields |= + NRF_WIFI_CMD_SET_WIPHY_FREQ_PARAMS_VALID; + } + + if (wiphy_info->rts_threshold) { + set_wiphy_cmd->valid_fields |= + NRF_WIFI_CMD_SET_WIPHY_RTS_THRESHOLD_VALID; + } + + if (wiphy_info->frag_threshold) { + set_wiphy_cmd->valid_fields |= + NRF_WIFI_CMD_SET_WIPHY_FRAG_THRESHOLD_VALID; + } + + if (wiphy_info->retry_long) { + set_wiphy_cmd->valid_fields |= + NRF_WIFI_CMD_SET_WIPHY_RETRY_LONG_VALID; + } + + if (wiphy_info->retry_short) { + set_wiphy_cmd->valid_fields |= + NRF_WIFI_CMD_SET_WIPHY_RETRY_SHORT_VALID; + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &set_wiphy_cmd->info, + wiphy_info, + sizeof(set_wiphy_cmd->info)); + + status = umac_cmd_cfg(fmac_dev_ctx, + set_wiphy_cmd, + sizeof(*set_wiphy_cmd)); +out: + if (set_wiphy_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_wiphy_cmd); + } + + return status; +} + +#ifdef CONFIG_NRF700X_STA_MODE +enum nrf_wifi_status nrf_wifi_fmac_get_tx_power(void *dev_ctx, + unsigned int if_idx) +{ + + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_get_tx_power *cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cmd)); + + if (!cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_TX_POWER; + cmd->umac_hdr.ids.wdev_id = if_idx; + cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, cmd, sizeof(*cmd)); + +out: + if (cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_get_channel(void *dev_ctx, + unsigned int if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_get_channel *cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cmd)); + + if (!cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_CHANNEL; + cmd->umac_hdr.ids.wdev_id = if_idx; + cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + cmd, + sizeof(*cmd)); +out: + if (cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_get_station(void *dev_ctx, + unsigned int if_idx, + unsigned char *mac) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_get_sta *cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cmd)); + + if (!cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_STATION; + cmd->umac_hdr.ids.wdev_id = if_idx; + cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + cmd->info.mac_addr, + mac, + NRF_WIFI_ETH_ADDR_LEN); + + status = umac_cmd_cfg(fmac_dev_ctx, + cmd, + sizeof(*cmd)); +out: + if (cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_get_interface(void *dev_ctx, + unsigned int if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_cmd_get_interface *cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + if (!dev_ctx || if_idx > MAX_NUM_VIFS) { + goto out; + } + fmac_dev_ctx = dev_ctx; + + cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cmd)); + + if (!cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_INTERFACE; + cmd->umac_hdr.ids.wdev_id = if_idx; + cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + cmd, + sizeof(*cmd)); +out: + if (cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_qos_map(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_qos_map_info *qos_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_qos_map *set_qos_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_qos_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_qos_cmd)); + + if (!set_qos_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_qos_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_QOS_MAP; + set_qos_cmd->umac_hdr.ids.wdev_id = if_idx; + set_qos_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + if (qos_info->qos_map_info_len) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &set_qos_cmd->info.qos_map_info, + qos_info->qos_map_info, + qos_info->qos_map_info_len); + + set_qos_cmd->info.qos_map_info_len = + qos_info->qos_map_info_len; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + set_qos_cmd, + sizeof(*set_qos_cmd)); +out: + if (set_qos_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_qos_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_power_save(void *dev_ctx, + unsigned char if_idx, + bool state) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_power_save *set_ps_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_ps_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_ps_cmd)); + + if (!set_ps_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + set_ps_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_POWER_SAVE; + set_ps_cmd->umac_hdr.ids.wdev_id = if_idx; + set_ps_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + set_ps_cmd->info.ps_state = state; + + status = umac_cmd_cfg(fmac_dev_ctx, + set_ps_cmd, + sizeof(*set_ps_cmd)); +out: + if (set_ps_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_ps_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_uapsd_queue(void *dev_ctx, + unsigned char if_idx, + unsigned int uapsd_queue) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_config_uapsd *set_uapsdq_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + if (!dev_ctx) { + goto out; + } + + set_uapsdq_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_uapsdq_cmd)); + if (!set_uapsdq_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_uapsdq_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_UAPSD; + set_uapsdq_cmd->umac_hdr.ids.wdev_id = if_idx; + set_uapsdq_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + set_uapsdq_cmd->info.uapsd_queue = uapsd_queue; + + status = umac_cmd_cfg(fmac_dev_ctx, + set_uapsdq_cmd, + sizeof(*set_uapsdq_cmd)); +out: + if (set_uapsdq_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_uapsdq_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_power_save_timeout(void *dev_ctx, + unsigned char if_idx, + int ps_timeout) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_power_save_timeout *set_ps_timeout_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_ps_timeout_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_ps_timeout_cmd)); + + if (!set_ps_timeout_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + set_ps_timeout_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_POWER_SAVE_TIMEOUT; + set_ps_timeout_cmd->umac_hdr.ids.wdev_id = if_idx; + set_ps_timeout_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + set_ps_timeout_cmd->timeout = ps_timeout; + + status = umac_cmd_cfg(fmac_dev_ctx, + set_ps_timeout_cmd, + sizeof(*set_ps_timeout_cmd)); +out: + if (set_ps_timeout_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_ps_timeout_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_get_wiphy(void *dev_ctx, unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_cmd_get_wiphy *get_wiphy = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + if (!dev_ctx || (if_idx >= MAX_NUM_VIFS)) { + goto out; + } + + get_wiphy = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*get_wiphy)); + + if (!get_wiphy) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + get_wiphy->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_WIPHY; + get_wiphy->umac_hdr.ids.wdev_id = if_idx; + get_wiphy->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + get_wiphy, + sizeof(*get_wiphy)); +out: + if (get_wiphy) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + get_wiphy); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_register_frame(void *dev_ctx, unsigned char if_idx, + struct nrf_wifi_umac_mgmt_frame_info *frame_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_mgmt_frame_reg *frame_reg_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + if (!dev_ctx || (if_idx >= MAX_NUM_VIFS) || !frame_info) { + goto out; + } + + frame_reg_cmd = + nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, sizeof(*frame_reg_cmd)); + + if (!frame_reg_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + frame_reg_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REGISTER_FRAME; + frame_reg_cmd->umac_hdr.ids.wdev_id = if_idx; + frame_reg_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &frame_reg_cmd->info, frame_info, sizeof(frame_reg_cmd->info)); + + status = umac_cmd_cfg(fmac_dev_ctx, frame_reg_cmd, sizeof(*frame_reg_cmd)); +out: + if (frame_reg_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, frame_reg_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_twt_setup(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_config_twt_info *twt_params) +{ + + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_config_twt *twt_setup_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + if (!dev_ctx || !twt_params) { + goto out; + } + + fmac_dev_ctx = dev_ctx; + + twt_setup_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*twt_setup_cmd)); + + if (!twt_setup_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &twt_setup_cmd->info, + twt_params, + sizeof(twt_setup_cmd->info)); + + twt_setup_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_TWT; + twt_setup_cmd->umac_hdr.ids.wdev_id = if_idx; + twt_setup_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + twt_setup_cmd, + sizeof(*twt_setup_cmd)); +out: + if (twt_setup_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + twt_setup_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_twt_teardown(void *dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_config_twt_info *twt_params) +{ + + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_teardown_twt *twt_teardown_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + if (!dev_ctx || !twt_params) { + goto out; + } + + fmac_dev_ctx = dev_ctx; + + twt_teardown_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*twt_teardown_cmd)); + + if (!twt_teardown_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &twt_teardown_cmd->info, + twt_params, + sizeof(twt_teardown_cmd->info)); + + twt_teardown_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_TEARDOWN_TWT; + twt_teardown_cmd->umac_hdr.ids.wdev_id = if_idx; + twt_teardown_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + twt_teardown_cmd, + sizeof(*twt_teardown_cmd)); +out: + if (twt_teardown_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + twt_teardown_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_set_mcast_addr(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char if_idx, + struct nrf_wifi_umac_mcast_cfg *mcast_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_mcast_filter *set_mcast_cmd = NULL; + + set_mcast_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_mcast_cmd)); + + if (!set_mcast_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_mcast_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_MCAST_FILTER; + set_mcast_cmd->umac_hdr.ids.wdev_id = if_idx; + set_mcast_cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &set_mcast_cmd->info, + mcast_info, + sizeof(*mcast_info)); + + status = umac_cmd_cfg(fmac_dev_ctx, + set_mcast_cmd, + sizeof(*set_mcast_cmd)); +out: + + if (set_mcast_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_mcast_cmd); + } + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_get_conn_info(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_conn_info *cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*cmd)); + + if (!cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_CONNECTION_INFO; + cmd->umac_hdr.ids.wdev_id = if_idx; + cmd->umac_hdr.ids.valid_fields |= NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + cmd, + sizeof(*cmd)); +out: + if (cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_get_power_save_info(void *dev_ctx, + unsigned char if_idx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_get_power_save_info *get_ps_info_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + get_ps_info_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*get_ps_info_cmd)); + + if (!get_ps_info_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + get_ps_info_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_POWER_SAVE_INFO; + get_ps_info_cmd->umac_hdr.ids.wdev_id = if_idx; + get_ps_info_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + + status = umac_cmd_cfg(fmac_dev_ctx, + get_ps_info_cmd, + sizeof(*get_ps_info_cmd)); +out: + if (get_ps_info_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + get_ps_info_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_set_listen_interval(void *dev_ctx, + unsigned char if_idx, + unsigned short listen_interval) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_set_listen_interval *set_listen_interval_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_listen_interval_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_listen_interval_cmd)); + + if (!set_listen_interval_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + set_listen_interval_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_SET_LISTEN_INTERVAL; + set_listen_interval_cmd->umac_hdr.ids.wdev_id = if_idx; + set_listen_interval_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + set_listen_interval_cmd->listen_interval = listen_interval; + + status = umac_cmd_cfg(fmac_dev_ctx, + set_listen_interval_cmd, + sizeof(*set_listen_interval_cmd)); +out: + if (set_listen_interval_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_listen_interval_cmd); + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_ps_wakeup_mode(void *dev_ctx, + unsigned char if_idx, + bool ps_wakeup_mode) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_config_extended_ps *set_ps_wakeup_mode_cmd = NULL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + set_ps_wakeup_mode_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_ps_wakeup_mode_cmd)); + + if (!set_ps_wakeup_mode_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", __func__); + goto out; + } + + set_ps_wakeup_mode_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_CONFIG_EXTENDED_PS; + set_ps_wakeup_mode_cmd->umac_hdr.ids.wdev_id = if_idx; + set_ps_wakeup_mode_cmd->umac_hdr.ids.valid_fields |= + NRF_WIFI_INDEX_IDS_WDEV_ID_VALID; + set_ps_wakeup_mode_cmd->enable_extended_ps = ps_wakeup_mode; + + status = umac_cmd_cfg(fmac_dev_ctx, + set_ps_wakeup_mode_cmd, + sizeof(*set_ps_wakeup_mode_cmd)); +out: + if (set_ps_wakeup_mode_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_ps_wakeup_mode_cmd); + } + + return status; +} +#endif /* CONFIG_NRF700X_STA_MODE */ diff --git a/nrf_wifi/fw_if/umac_if/src/event.c b/nrf_wifi/fw_if/umac_if/src/event.c new file mode 100644 index 0000000000..c33abb8791 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/event.c @@ -0,0 +1,957 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing event specific definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "queue.h" +#include "host_rpu_umac_if.h" +#include "hal_mem.h" +#include "fmac_rx.h" +#include "fmac_tx.h" +#include "fmac_peer.h" +#include "fmac_cmd.h" +#include "fmac_ap.h" +#include "fmac_util.h" + +#ifdef CONFIG_NRF700X_DATA_TX +static enum nrf_wifi_status +nrf_wifi_fmac_if_carr_state_event_proc(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *umac_head, + enum nrf_wifi_fmac_if_carr_state carr_state) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + unsigned char if_idx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + if (!fmac_dev_ctx || !umac_head) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + + goto out; + } + + if (!def_priv->callbk_fns.if_carr_state_chg_callbk_fn) { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: No callback handler registered\n", + __func__); + + status = NRF_WIFI_STATUS_SUCCESS; + goto out; + } + + if_idx = ((struct nrf_wifi_data_carrier_state *)umac_head)->wdev_id; + + if (if_idx >= MAX_NUM_VIFS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid wdev_id recd from UMAC %d\n", + __func__, + if_idx); + goto out; + } + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + status = def_priv->callbk_fns.if_carr_state_chg_callbk_fn(vif_ctx->os_vif_ctx, + carr_state); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Interface carrier state change callback function failed for VIF idx = %d\n", + __func__, + if_idx); + goto out; + } +out: + return status; +} +#endif /* CONFIG_NRF700X_DATA_TX */ + +#ifdef CONFIG_NRF700X_STA_MODE +static void umac_event_connect(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *event_data) +{ + unsigned char if_index = 0; + int peer_id = -1; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_umac_event_new_station *event = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + event = (struct nrf_wifi_umac_event_new_station *)event_data; + + if_index = event->umac_hdr.ids.wdev_id; + + vif_ctx = def_dev_ctx->vif_ctx[if_index]; + if (if_index >= MAX_NUM_VIFS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid wdev_id recd from UMAC %d\n", + __func__, + if_index); + return; + } + + if (event->umac_hdr.cmd_evnt == NRF_WIFI_UMAC_EVENT_NEW_STATION) { + if (vif_ctx->if_type == 2) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + vif_ctx->bssid, + event->mac_addr, + NRF_WIFI_ETH_ADDR_LEN); + } + peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, event->mac_addr); + + if (peer_id == -1) { + peer_id = nrf_wifi_fmac_peer_add(fmac_dev_ctx, + if_index, + event->mac_addr, + event->is_sta_legacy, + event->wme); + + if (peer_id == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s:Can't add new station.\n", + __func__); + return; + } + } + } else if (event->umac_hdr.cmd_evnt == NRF_WIFI_UMAC_EVENT_DEL_STATION) { + peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, event->mac_addr); + if (peer_id != -1) { + nrf_wifi_fmac_peer_remove(fmac_dev_ctx, + if_index, + peer_id); + } + } + + return; + +} +#endif /* CONFIG_NRF700X_STA_MODE */ + +#ifndef CONFIG_NRF700X_RADIO_TEST +static enum nrf_wifi_status umac_event_ctrl_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *event_data, + unsigned int event_len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS; + struct nrf_wifi_umac_hdr *umac_hdr = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_callbk_fns *callbk_fns = NULL; + struct nrf_wifi_umac_event_vif_state *evnt_vif_state = NULL; + unsigned char if_id = 0; + unsigned int event_num = 0; + bool more_res = false; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + if (!fmac_dev_ctx || !event_data) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!def_priv || !def_dev_ctx) { + goto out; + } + + umac_hdr = event_data; + if_id = umac_hdr->ids.wdev_id; + event_num = umac_hdr->cmd_evnt; + + if (if_id >= MAX_NUM_VIFS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid wdev_id recd from UMAC %d\n", + __func__, + if_id); + + goto out; + } + + vif_ctx = def_dev_ctx->vif_ctx[if_id]; + callbk_fns = &def_priv->callbk_fns; + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Event %d received from UMAC\n", + __func__, + event_num); + + switch (umac_hdr->cmd_evnt) { + case NRF_WIFI_UMAC_EVENT_TRIGGER_SCAN_START: + if (callbk_fns->scan_start_callbk_fn) + callbk_fns->scan_start_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_SCAN_DONE: + if (callbk_fns->scan_done_callbk_fn) + callbk_fns->scan_done_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_SCAN_ABORTED: + if (callbk_fns->scan_abort_callbk_fn) + callbk_fns->scan_abort_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_SCAN_DISPLAY_RESULT: + if (umac_hdr->seq != 0) + more_res = true; + + if (callbk_fns->disp_scan_res_callbk_fn) + callbk_fns->disp_scan_res_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len, + more_res); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_IFFLAGS_STATUS: + evnt_vif_state = (struct nrf_wifi_umac_event_vif_state *)event_data; + + if (evnt_vif_state->status < 0) + goto out; + + vif_ctx->ifflags = true; + break; +#ifdef CONFIG_NRF700X_STA_MODE + case NRF_WIFI_UMAC_EVENT_TWT_SLEEP: + if (callbk_fns->twt_sleep_callbk_fn) + callbk_fns->twt_sleep_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_SCAN_RESULT: + if (umac_hdr->seq != 0) + more_res = true; + + if (callbk_fns->scan_res_callbk_fn) + callbk_fns->scan_res_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len, + more_res); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_AUTHENTICATE: + if (callbk_fns->auth_resp_callbk_fn) + callbk_fns->auth_resp_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_ASSOCIATE: + if (callbk_fns->assoc_resp_callbk_fn) + callbk_fns->assoc_resp_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_DEAUTHENTICATE: + if (callbk_fns->deauth_callbk_fn) + callbk_fns->deauth_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_DISASSOCIATE: + if (callbk_fns->disassoc_callbk_fn) + callbk_fns->disassoc_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_FRAME: + if (callbk_fns->mgmt_rx_callbk_fn) + callbk_fns->mgmt_rx_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_GET_TX_POWER: + if (callbk_fns->tx_pwr_get_callbk_fn) + callbk_fns->tx_pwr_get_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_GET_CHANNEL: + if (callbk_fns->chnl_get_callbk_fn) + callbk_fns->chnl_get_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_GET_STATION: + if (callbk_fns->get_station_callbk_fn) + callbk_fns->get_station_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_NEW_INTERFACE: + if (callbk_fns->get_interface_callbk_fn) + callbk_fns->get_interface_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_COOKIE_RESP: + if (callbk_fns->cookie_rsp_callbk_fn) + callbk_fns->cookie_rsp_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_FRAME_TX_STATUS: + if (callbk_fns->mgmt_tx_status) + callbk_fns->mgmt_tx_status(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_UNPROT_DEAUTHENTICATE: + case NRF_WIFI_UMAC_EVENT_UNPROT_DISASSOCIATE: + if (callbk_fns->unprot_mlme_mgmt_rx_callbk_fn) + callbk_fns->unprot_mlme_mgmt_rx_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_SET_INTERFACE: + if (callbk_fns->set_if_callbk_fn) + callbk_fns->set_if_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_CONFIG_TWT: + if (callbk_fns->twt_config_callbk_fn) + callbk_fns->twt_config_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_TEARDOWN_TWT: + if (callbk_fns->twt_teardown_callbk_fn) + callbk_fns->twt_teardown_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_NEW_WIPHY: + if (callbk_fns->event_get_wiphy) + callbk_fns->event_get_wiphy(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_CMD_STATUS: + case NRF_WIFI_UMAC_EVENT_BEACON_HINT: + case NRF_WIFI_UMAC_EVENT_CONNECT: + case NRF_WIFI_UMAC_EVENT_DISCONNECT: + /* Nothing to be done */ + break; + case NRF_WIFI_UMAC_EVENT_GET_REG: + if (callbk_fns->event_get_reg) + callbk_fns->event_get_reg(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_GET_POWER_SAVE_INFO: + if (callbk_fns->event_get_ps_info) + callbk_fns->event_get_ps_info(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; +#ifdef CONFIG_NRF700X_STA_MODE + case NRF_WIFI_UMAC_EVENT_NEW_STATION: + case NRF_WIFI_UMAC_EVENT_DEL_STATION: + umac_event_connect(fmac_dev_ctx, + event_data); + break; +#endif /* CONFIG_NRF700X_STA_MODE */ +#ifdef CONFIG_NRF700X_P2P_MODE + case NRF_WIFI_UMAC_EVENT_REMAIN_ON_CHANNEL: + if (callbk_fns->roc_callbk_fn) + callbk_fns->roc_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_CANCEL_REMAIN_ON_CHANNEL: + if (callbk_fns->roc_cancel_callbk_fn) + callbk_fns->roc_cancel_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; +#endif /* CONFIG_NRF700X_P2P_MODE */ + case NRF_WIFI_UMAC_EVENT_GET_CONNECTION_INFO: + if (callbk_fns->get_conn_info_callbk_fn) + callbk_fns->get_conn_info_callbk_fn(vif_ctx->os_vif_ctx, + event_data, + event_len); + else + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + case NRF_WIFI_UMAC_EVENT_REG_CHANGE: + /* TODO: Inform the user space about the regulatory change */ + break; +#endif /* CONFIG_NRF700X_STA_MODE */ + default: + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: No callback registered for event %d\n", + __func__, + umac_hdr->cmd_evnt); + break; + } + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Event %d processed\n", + __func__, + event_num); + +out: + return status; +} + +static enum nrf_wifi_status +nrf_wifi_fmac_data_event_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *umac_head) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS; + int event = -1; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!fmac_dev_ctx) { + goto out; + } + + if (!umac_head) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + event = ((struct nrf_wifi_umac_head *)umac_head)->cmd; + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Event %d received from UMAC\n", + __func__, + event); + + switch (event) { + case NRF_WIFI_CMD_RX_BUFF: +#ifdef CONFIG_NRF700X_RX_DONE_WQ_ENABLED + struct nrf_wifi_rx_buff *config = nrf_wifi_osal_mem_zalloc( + fmac_dev_ctx->fpriv->opriv, + sizeof(struct nrf_wifi_rx_buff)); + if (!config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to allocate memory (RX)\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + break; + } + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + config, + umac_head, + sizeof(struct nrf_wifi_rx_buff)); + status = nrf_wifi_utils_q_enqueue(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->rx_config.rx_tasklet_event_q, + config); + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to enqueue RX buffer\n", + __func__); + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + config); + break; + } + nrf_wifi_osal_tasklet_schedule(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->rx_tasklet); +#else + status = nrf_wifi_fmac_rx_event_process(fmac_dev_ctx, + umac_head); +#endif /* CONFIG_NRF700X_RX_DONE_WQ_ENABLED */ + break; +#ifdef CONFIG_NRF700X_DATA_TX + case NRF_WIFI_CMD_TX_BUFF_DONE: +#ifdef CONFIG_NRF700X_TX_DONE_WQ_ENABLED + struct nrf_wifi_tx_buff_done *config = nrf_wifi_osal_mem_zalloc( + fmac_dev_ctx->fpriv->opriv, + sizeof(struct nrf_wifi_tx_buff_done)); + if (!config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to allocate memory (TX)\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + break; + } + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + config, + umac_head, + sizeof(struct nrf_wifi_tx_buff_done)); + status = nrf_wifi_utils_q_enqueue(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_done_tasklet_event_q, + config); + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to enqueue TX buffer\n", + __func__); + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + config); + break; + } + nrf_wifi_osal_tasklet_schedule(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_done_tasklet); +#else + status = nrf_wifi_fmac_tx_done_event_process(fmac_dev_ctx, + umac_head); +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ + break; + case NRF_WIFI_CMD_CARRIER_ON: + status = nrf_wifi_fmac_if_carr_state_event_proc(fmac_dev_ctx, + umac_head, + NRF_WIFI_FMAC_IF_CARR_STATE_ON); + break; + case NRF_WIFI_CMD_CARRIER_OFF: + status = nrf_wifi_fmac_if_carr_state_event_proc(fmac_dev_ctx, + umac_head, + NRF_WIFI_FMAC_IF_CARR_STATE_OFF); + break; +#endif /* CONFIG_NRF700X_DATA_TX */ +#ifdef CONFIG_NRF700X_AP_MODE + case NRF_WIFI_CMD_PM_MODE: + status = sap_client_update_pmmode(fmac_dev_ctx, + umac_head); + break; + case NRF_WIFI_CMD_PS_GET_FRAMES: + status = sap_client_ps_get_frames(fmac_dev_ctx, + umac_head); + break; +#endif /* CONFIG_NRF700X_AP_MODE */ + default: + break; + } + +out: + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed for event = %d\n", + __func__, + event); + } + + return status; +} + + +static enum nrf_wifi_status +nrf_wifi_fmac_data_events_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct host_rpu_msg *rpu_msg) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned char *umac_head = NULL; + int host_rpu_length_left = 0; + + if (!fmac_dev_ctx || !rpu_msg) { + goto out; + } + + umac_head = (unsigned char *)rpu_msg->msg; + host_rpu_length_left = rpu_msg->hdr.len - sizeof(struct host_rpu_msg); + + while (host_rpu_length_left > 0) { + status = nrf_wifi_fmac_data_event_process(fmac_dev_ctx, + umac_head); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_process_data_event failed\n", + __func__); + goto out; + } + + host_rpu_length_left -= ((struct nrf_wifi_umac_head *)umac_head)->len; + umac_head += ((struct nrf_wifi_umac_head *)umac_head)->len; + } +out: + return status; +} +#else /* CONFIG_NRF700X_RADIO_TEST */ +static enum nrf_wifi_status umac_event_rf_test_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *event) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_event_rftest *rf_test_event = NULL; + struct nrf_wifi_temperature_params rf_test_get_temperature; + struct nrf_wifi_rf_get_rf_rssi rf_get_rf_rssi; + struct nrf_wifi_rf_test_xo_calib xo_calib_params; + struct nrf_wifi_rf_get_xo_value rf_get_xo_value_params; + struct nrf_wifi_fmac_dev_ctx_rt *def_dev_ctx; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!event) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + rf_test_event = ((struct nrf_wifi_event_rftest *)event); + + if (rf_test_event->rf_test_info.rfevent[0] != def_dev_ctx->rf_test_type) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid event type (%d) recd for RF test type (%d)\n", + __func__, + rf_test_event->rf_test_info.rfevent[0], + def_dev_ctx->rf_test_type); + goto out; + } + + switch (rf_test_event->rf_test_info.rfevent[0]) { + case NRF_WIFI_RF_TEST_EVENT_RX_ADC_CAP: + case NRF_WIFI_RF_TEST_EVENT_RX_STAT_PKT_CAP: + case NRF_WIFI_RF_TEST_EVENT_RX_DYN_PKT_CAP: + status = hal_rpu_mem_read(fmac_dev_ctx->hal_dev_ctx, + def_dev_ctx->rf_test_cap_data, + RPU_MEM_RF_TEST_CAP_BASE, + def_dev_ctx->rf_test_cap_sz); + + break; + case NRF_WIFI_RF_TEST_EVENT_TX_TONE_START: + case NRF_WIFI_RF_TEST_EVENT_DPD_ENABLE: + break; + + case NRF_WIFI_RF_TEST_GET_TEMPERATURE: + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, &rf_test_get_temperature, + (const unsigned char *)&rf_test_event->rf_test_info.rfevent[0], + sizeof(rf_test_get_temperature)); + + if (rf_test_get_temperature.readTemperatureStatus) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "Temperature reading failed\n"); + } else { + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "The temperature is = %d degree celsius\n", + rf_test_get_temperature.temperature); + } + break; + case NRF_WIFI_RF_TEST_EVENT_RF_RSSI: + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, &rf_get_rf_rssi, + (const unsigned char *)&rf_test_event->rf_test_info.rfevent[0], + sizeof(rf_get_rf_rssi)); + + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "RF RSSI value is = %d\n", + rf_get_rf_rssi.agc_status_val); + break; + case NRF_WIFI_RF_TEST_EVENT_XO_CALIB: + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, &xo_calib_params, + (const unsigned char *)&rf_test_event->rf_test_info.rfevent[0], + sizeof(xo_calib_params)); + + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "XO value configured is = %d\n", + xo_calib_params.xo_val); + break; + case NRF_WIFI_RF_TEST_XO_TUNE: + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, &rf_get_xo_value_params, + (const unsigned char *)&rf_test_event->rf_test_info.rfevent[0], + sizeof(rf_get_xo_value_params)); + + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "Best XO value is = %d\n", + rf_get_xo_value_params.xo_value); + break; + default: + break; + } + + def_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + status = NRF_WIFI_STATUS_SUCCESS; + +out: + return status; +} + + +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + + +static enum nrf_wifi_status umac_event_stats_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *event) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_event_stats *stats = NULL; + + if (!event) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + if (!fmac_dev_ctx->stats_req) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Stats recd when req was not sent!\n", + __func__); + goto out; + } + + stats = ((struct nrf_wifi_umac_event_stats *)event); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + fmac_dev_ctx->fw_stats, + &stats->fw, + sizeof(*fmac_dev_ctx->fw_stats)); + + fmac_dev_ctx->stats_req = false; + + status = NRF_WIFI_STATUS_SUCCESS; + +out: + return status; +} + + +static enum nrf_wifi_status umac_process_sys_events(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct host_rpu_msg *rpu_msg) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned char *sys_head = NULL; +#ifdef CONFIG_NRF700X_RADIO_TEST + struct nrf_wifi_fmac_dev_ctx_rt *def_dev_ctx; + struct nrf_wifi_umac_event_err_status *umac_status; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); +#endif /* CONFIG_NRF700X_RADIO_TEST */ + + if (!fmac_dev_ctx || !rpu_msg) { + return status; + } + + sys_head = (unsigned char *)rpu_msg->msg; + + switch (((struct nrf_wifi_sys_head *)sys_head)->cmd_event) { + case NRF_WIFI_EVENT_STATS: + status = umac_event_stats_process(fmac_dev_ctx, + sys_head); + break; + case NRF_WIFI_EVENT_INIT_DONE: + fmac_dev_ctx->fw_init_done = 1; + status = NRF_WIFI_STATUS_SUCCESS; + break; + case NRF_WIFI_EVENT_DEINIT_DONE: + fmac_dev_ctx->fw_deinit_done = 1; + status = NRF_WIFI_STATUS_SUCCESS; + break; +#ifdef CONFIG_NRF700X_RADIO_TEST + case NRF_WIFI_EVENT_RF_TEST: + status = umac_event_rf_test_process(fmac_dev_ctx, + sys_head); + break; + case NRF_WIFI_EVENT_RADIOCMD_STATUS: + umac_status = ((struct nrf_wifi_umac_event_err_status *)sys_head); + def_dev_ctx->radio_cmd_status = umac_status->status; + def_dev_ctx->radio_cmd_done = true; + status = NRF_WIFI_STATUS_SUCCESS; + break; +#endif /* CONFIG_NRF700X_RADIO_TEST */ + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unknown event recd: %d\n", + __func__, + ((struct nrf_wifi_sys_head *)sys_head)->cmd_event); + break; + } + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_event_callback(void *mac_dev_ctx, + void *rpu_event_data, + unsigned int rpu_event_len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct host_rpu_msg *rpu_msg = NULL; + struct nrf_wifi_umac_hdr *umac_hdr = NULL; + unsigned int umac_msg_len = 0; + int umac_msg_type = NRF_WIFI_UMAC_EVENT_UNSPECIFIED; + + fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)mac_dev_ctx; + + rpu_msg = (struct host_rpu_msg *)rpu_event_data; + umac_hdr = (struct nrf_wifi_umac_hdr *)rpu_msg->msg; + umac_msg_len = rpu_msg->hdr.len; + umac_msg_type = umac_hdr->cmd_evnt; + + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Event type %d recd\n", + __func__, + rpu_msg->type); + + switch (rpu_msg->type) { +#ifndef CONFIG_NRF700X_RADIO_TEST + case NRF_WIFI_HOST_RPU_MSG_TYPE_DATA: + status = nrf_wifi_fmac_data_events_process(fmac_dev_ctx, + rpu_msg); + break; + case NRF_WIFI_HOST_RPU_MSG_TYPE_UMAC: + status = umac_event_ctrl_process(fmac_dev_ctx, + rpu_msg->msg, + rpu_msg->hdr.len); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_event_ctrl_process failed\n", + __func__); + goto out; + } + break; +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + case NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM: + status = umac_process_sys_events(fmac_dev_ctx, + rpu_msg); + break; + default: + goto out; + } + +out: + return status; +} diff --git a/nrf_wifi/fw_if/umac_if/src/fmac_ap.c b/nrf_wifi/fw_if/umac_if/src/fmac_ap.c new file mode 100644 index 0000000000..38660e8d85 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/fmac_ap.c @@ -0,0 +1,154 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing SoftAP specific definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "fmac_ap.h" +#include "fmac_peer.h" +#include "queue.h" +#include "fmac_tx.h" +#include "fmac_util.h" + +enum nrf_wifi_status sap_client_ps_get_frames(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_sap_ps_get_frames *config) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct peers_info *peer = NULL; + void *wakeup_client_q = NULL; + int id = -1; + int ac = 0; + int desc = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + if (!fmac_dev_ctx || !config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid params\n", + __func__); + goto out; + } + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + nrf_wifi_osal_spinlock_take(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, config->mac_addr); + + if (id == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid Peer_ID, Mac Addr =%pM\n", + __func__, + config->mac_addr); + + nrf_wifi_osal_spinlock_rel(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + goto out; + } + + + peer = &def_dev_ctx->tx_config.peers[id]; + peer->ps_token_count = config->num_frames; + + wakeup_client_q = def_dev_ctx->tx_config.wakeup_client_q; + + if (wakeup_client_q) { + nrf_wifi_utils_q_enqueue(fmac_dev_ctx->fpriv->opriv, + wakeup_client_q, + peer); + } + + for (ac = NRF_WIFI_FMAC_AC_VO; ac >= 0; --ac) { + desc = tx_desc_get(fmac_dev_ctx, ac); + + if (desc < def_priv->num_tx_tokens) { + tx_pending_process(fmac_dev_ctx, desc, ac); + } + } + + nrf_wifi_osal_spinlock_rel(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +enum nrf_wifi_status sap_client_update_pmmode(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_sap_client_pwrsave *config) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct peers_info *peer = NULL; + void *wakeup_client_q = NULL; + int id = -1; + int ac = 0; + int desc = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + if (!fmac_dev_ctx || !config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid params\n", + __func__); + goto out; + } + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + nrf_wifi_osal_spinlock_take(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, + config->mac_addr); + + if (id == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid Peer_ID, Mac address = %pM\n", + __func__, + config->mac_addr); + + nrf_wifi_osal_spinlock_rel(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + goto out; + } + + + peer = &def_dev_ctx->tx_config.peers[id]; + peer->ps_state = config->sta_ps_state; + + if (peer->ps_state == NRF_WIFI_CLIENT_ACTIVE) { + wakeup_client_q = def_dev_ctx->tx_config.wakeup_client_q; + + if (wakeup_client_q) { + nrf_wifi_utils_q_enqueue(fmac_dev_ctx->fpriv->opriv, + wakeup_client_q, + peer); + } + + for (ac = NRF_WIFI_FMAC_AC_VO; ac >= 0; --ac) { + desc = tx_desc_get(fmac_dev_ctx, ac); + + if (desc < def_priv->num_tx_tokens) { + tx_pending_process(fmac_dev_ctx, desc, ac); + } + } + } + + nrf_wifi_osal_spinlock_rel(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + status = NRF_WIFI_STATUS_SUCCESS; + +out: + return status; +} diff --git a/nrf_wifi/fw_if/umac_if/src/fmac_api_common.c b/nrf_wifi/fw_if/umac_if/src/fmac_api_common.c new file mode 100644 index 0000000000..5dbad20827 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/fmac_api_common.c @@ -0,0 +1,754 @@ +/* + * Copyright (c) 2023 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing API definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "host_rpu_umac_if.h" +#include "fmac_api.h" +#include "hal_api.h" +#include "fmac_structs.h" +#include "fmac_api.h" +#include "fmac_util.h" +#include "fmac_peer.h" +#include "fmac_vif.h" +#include "fmac_tx.h" +#include "fmac_rx.h" +#include "fmac_cmd.h" +#include "fmac_event.h" +#include "fmac_bb.h" +#include "util.h" + +enum nrf_wifi_status nrf_wifi_fmac_fw_load(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_fmac_fw_info *fmac_fw) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + /* Load the LMAC patches if available */ + if ((fmac_fw->lmac_patch_pri.data) && (fmac_fw->lmac_patch_pri.size)) { + status = nrf_wifi_hal_proc_reset(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_LMAC); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC processor reset failed\n", + __func__); + + goto out; + } + + /* Load the LMAC patches */ + status = nrf_wifi_hal_fw_patch_load(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_LMAC, + fmac_fw->lmac_patch_pri.data, + fmac_fw->lmac_patch_pri.size, + fmac_fw->lmac_patch_sec.data, + fmac_fw->lmac_patch_sec.size); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC patch load failed\n", + __func__); + goto out; + } else { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC patches loaded\n", + __func__); + } + + status = nrf_wifi_hal_fw_patch_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_LMAC, + true); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to boot LMAC with patch\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_fw_chk_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_LMAC); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC ROM boot check failed\n", + __func__); + goto out; + } else { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC boot check passed\n", + __func__); + } + } else { + status = nrf_wifi_hal_fw_patch_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_LMAC, + false); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC ROM boot failed\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_fw_chk_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_LMAC); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC ROM boot check failed\n", + __func__); + goto out; + } else { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: LMAC boot check passed\n", + __func__); + } + } + + /* Load the UMAC patches if available */ + if ((fmac_fw->umac_patch_pri.data) && (fmac_fw->umac_patch_pri.size)) { + status = nrf_wifi_hal_proc_reset(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_UMAC); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC processor reset failed\n", + __func__); + + goto out; + } + + /* Load the UMAC patches */ + status = nrf_wifi_hal_fw_patch_load(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_UMAC, + fmac_fw->umac_patch_pri.data, + fmac_fw->umac_patch_pri.size, + fmac_fw->umac_patch_sec.data, + fmac_fw->umac_patch_sec.size); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC patch load failed\n", + __func__); + goto out; + } else { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC patches loaded\n", + __func__); + } + + status = nrf_wifi_hal_fw_patch_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_UMAC, + true); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to boot UMAC with patch\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_fw_chk_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_UMAC); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC ROM boot check failed\n", + __func__); + goto out; + } else { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC boot check passed\n", + __func__); + } + } else { + status = nrf_wifi_hal_fw_patch_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_UMAC, + false); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC ROM boot failed\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_fw_chk_boot(fmac_dev_ctx->hal_dev_ctx, + RPU_PROC_TYPE_MCU_UMAC); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC ROM boot check failed\n", + __func__); + goto out; + } else { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC boot check passed\n", + __func__); + } + } + + fmac_dev_ctx->fw_boot_done = true; + +out: + return status; +} + + +struct nrf_wifi_fmac_dev_ctx *nrf_wifi_fmac_dev_add(struct nrf_wifi_fmac_priv *fpriv, + void *os_dev_ctx) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; +#ifndef CONFIG_NRF700X_RADIO_TEST + struct nrf_wifi_fmac_dev_ctx_def *fmac_dev_priv = NULL; +#else + struct nrf_wifi_fmac_dev_ctx_rt *fmac_dev_priv = NULL; +#endif +#ifdef CONFIG_NRF700X_DATA_TX + struct nrf_wifi_fmac_priv_def *def_priv = NULL; +#endif /* CONFIG_NRF700X_DATA_TX */ + + if (!fpriv || !os_dev_ctx) { + return NULL; + } + + fmac_dev_ctx = nrf_wifi_osal_mem_zalloc(fpriv->opriv, + sizeof(*fmac_dev_ctx) + sizeof(*fmac_dev_priv)); + + if (!fmac_dev_ctx) { + nrf_wifi_osal_log_err(fpriv->opriv, + "%s: Unable to allocate fmac_dev_ctx\n", + __func__); + goto out; + } + + fmac_dev_ctx->fpriv = fpriv; + fmac_dev_ctx->os_dev_ctx = os_dev_ctx; + + fmac_dev_ctx->hal_dev_ctx = nrf_wifi_hal_dev_add(fpriv->hpriv, + fmac_dev_ctx); + + if (!fmac_dev_ctx->hal_dev_ctx) { + nrf_wifi_osal_log_err(fpriv->opriv, + "%s: nrf_wifi_hal_dev_add failed\n", + __func__); + + nrf_wifi_osal_mem_free(fpriv->opriv, + fmac_dev_ctx); + fmac_dev_ctx = NULL; + goto out; + } +#ifdef CONFIG_NRF700X_DATA_TX + + def_priv = wifi_fmac_priv(fpriv); + fpriv->hpriv->cfg_params.max_ampdu_len_per_token = def_priv->max_ampdu_len_per_token; +#endif /* CONFIG_NRF700X_DATA_TX */ +out: + return fmac_dev_ctx; +} + +enum nrf_wifi_status nrf_wifi_fmac_stats_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + enum rpu_op_mode op_mode, + struct rpu_op_stats *stats) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned char count = 0; + int stats_type; +#ifndef CONFIG_NRF700X_RADIO_TEST + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; +#endif /* CONFIG_NRF700X_RADIO_TEST */ + + #ifdef CONFIG_NRF700X_RADIO_TEST + stats_type = RPU_STATS_TYPE_PHY; + #else + stats_type = RPU_STATS_TYPE_ALL; + #endif /* CONFIG_NRF700X_RADIO_TEST */ + + + if ((stats_type == RPU_STATS_TYPE_ALL) || + (stats_type == RPU_STATS_TYPE_UMAC) || + (stats_type == RPU_STATS_TYPE_LMAC) || + (stats_type == RPU_STATS_TYPE_PHY)) { + if (fmac_dev_ctx->stats_req == true) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Stats request already pending\n", + __func__); + goto out; + } + + fmac_dev_ctx->stats_req = true; + fmac_dev_ctx->fw_stats = &stats->fw; + + status = umac_cmd_prog_stats_get(fmac_dev_ctx, + #ifdef CONFIG_NRF700X_RADIO_TEST + op_mode, + #endif /* CONFIG_NRF700X_RADIO_TEST */ + stats_type); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 1); + count++; + } while ((fmac_dev_ctx->stats_req == true) && + (count < NRF_WIFI_FMAC_STATS_RECV_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_STATS_RECV_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + goto out; + } + } + + +#ifndef CONFIG_NRF700X_RADIO_TEST + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + if ((stats_type == RPU_STATS_TYPE_ALL) || + (stats_type == RPU_STATS_TYPE_HOST)) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &stats->host, + &def_dev_ctx->host_stats, + sizeof(def_dev_ctx->host_stats)); + } +#endif + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_ver_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int *fw_ver) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = hal_rpu_mem_read(fmac_dev_ctx->hal_dev_ctx, + fw_ver, + RPU_MEM_UMAC_VER, + sizeof(*fw_ver)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to read UMAC ver\n", + __func__); + goto out; + } + +out: + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_conf_ltf_gi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char he_ltf, + unsigned char he_gi, + unsigned char enabled) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = umac_cmd_he_ltf_gi(fmac_dev_ctx, he_ltf, he_gi, enabled); + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_conf_btcoex(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *cmd, unsigned int cmd_len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = umac_cmd_btcoex(fmac_dev_ctx, cmd, cmd_len); + + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_otp_mac_addr_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char vif_idx, + unsigned char *mac_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_otp_info otp_info; + unsigned char *otp_mac_addr = NULL; + unsigned int otp_mac_addr_flag_mask = 0; + + if (!fmac_dev_ctx || !mac_addr || (vif_idx >= MAX_NUM_VIFS)) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &otp_info, + 0xFF, + sizeof(otp_info)); + + status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx, + &otp_info.info, + &otp_info.flags); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Fetching of RPU OTP information failed\n", + __func__); + goto out; + } + + if (vif_idx == 0) { + otp_mac_addr = (unsigned char *)otp_info.info.mac_address0; + otp_mac_addr_flag_mask = (~MAC0_ADDR_FLAG_MASK); + + } else if (vif_idx == 1) { + otp_mac_addr = (unsigned char *)otp_info.info.mac_address1; + otp_mac_addr_flag_mask = (~MAC1_ADDR_FLAG_MASK); + } + + /* Check if a valid MAC address has been programmed in the OTP */ + + if (otp_info.flags & otp_mac_addr_flag_mask) { + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "%s: MAC addr not programmed in OTP\n", + __func__); + + } else { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + mac_addr, + otp_mac_addr, + NRF_WIFI_ETH_ADDR_LEN); + + if (!nrf_wifi_utils_is_mac_addr_valid(fmac_dev_ctx->fpriv->opriv, + (const char *)mac_addr)) { + nrf_wifi_osal_log_info(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid OTP MAC addr: %02X%02X%02X%02X%02X%02X\n", + __func__, + (*(mac_addr + 0)), + (*(mac_addr + 1)), + (*(mac_addr + 2)), + (*(mac_addr + 3)), + (*(mac_addr + 4)), + (*(mac_addr + 5))); + + } + } +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rf_params_get( + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char *rf_params, + struct nrf_wifi_tx_pwr_ceil_params *tx_pwr_ceil_params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_otp_info otp_info; + unsigned int ft_prog_ver; + int ret = -1; +#if defined(CONFIG_BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP) || \ + defined(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP) || \ + defined(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP) + unsigned char backoff_2g_dsss = 0, backoff_2g_ofdm = 0; + unsigned char backoff_5g_lowband = 0, backoff_5g_midband = 0, backoff_5g_highband = 0; +#endif + + if (!fmac_dev_ctx || !rf_params) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &otp_info, + 0xFF, + sizeof(otp_info)); + + status = nrf_wifi_hal_otp_info_get(fmac_dev_ctx->hal_dev_ctx, + &otp_info.info, + &otp_info.flags); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Fetching of RPU OTP information failed\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_otp_ft_prog_ver_get(fmac_dev_ctx->hal_dev_ctx, + &ft_prog_ver); + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Fetching of FT program version failed\n", + __func__); + goto out; + } + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + rf_params, + 0xFF, + NRF_WIFI_RF_PARAMS_SIZE); + + ret = nrf_wifi_utils_hex_str_to_val(fmac_dev_ctx->fpriv->opriv, + rf_params, + NRF_WIFI_RF_PARAMS_SIZE, + NRF_WIFI_DEF_RF_PARAMS); + + if (ret == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Initialization of RF params with default values failed\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + if (!(otp_info.flags & (~CALIB_XO_FLAG_MASK))) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_X0], + (char *)otp_info.info.calib + OTP_OFF_CALIB_XO, + OTP_SZ_CALIB_XO); + + } + + ft_prog_ver = (ft_prog_ver & FT_PROG_VER_MASK) >> 16; + +#if defined(CONFIG_BOARD_NRF7002DK_NRF7001_NRF5340_CPUAPP) || \ + defined(CONFIG_BOARD_NRF7002DK_NRF5340_CPUAPP) || \ + defined(CONFIG_BOARD_NRF5340DK_NRF5340_CPUAPP) + if (tx_pwr_ceil_params->rf_tx_pwr_ceil_params_override) { + if (ft_prog_ver == FT_PROG_VER1) { + backoff_2g_dsss = FT_PROG_VER1_2G_DSSS_TXCEIL_BKOFF; + backoff_2g_ofdm = FT_PROG_VER1_2G_OFDM_TXCEIL_BKOFF; + backoff_5g_lowband = FT_PROG_VER1_5G_LOW_OFDM_TXCEIL_BKOFF; + backoff_5g_midband = FT_PROG_VER1_5G_MID_OFDM_TXCEIL_BKOFF; + backoff_5g_highband = FT_PROG_VER1_5G_HIGH_OFDM_TXCEIL_BKOFF; + } else if (ft_prog_ver == FT_PROG_VER2) { + backoff_2g_dsss = FT_PROG_VER2_2G_DSSS_TXCEIL_BKOFF; + backoff_2g_ofdm = FT_PROG_VER2_2G_OFDM_TXCEIL_BKOFF; + backoff_5g_lowband = FT_PROG_VER2_5G_LOW_OFDM_TXCEIL_BKOFF; + backoff_5g_midband = FT_PROG_VER2_5G_MID_OFDM_TXCEIL_BKOFF; + backoff_5g_highband = FT_PROG_VER2_5G_HIGH_OFDM_TXCEIL_BKOFF; + } else if (ft_prog_ver == FT_PROG_VER3) { + backoff_2g_dsss = FT_PROG_VER3_2G_DSSS_TXCEIL_BKOFF; + backoff_2g_ofdm = FT_PROG_VER3_2G_OFDM_TXCEIL_BKOFF; + backoff_5g_lowband = FT_PROG_VER3_5G_LOW_OFDM_TXCEIL_BKOFF; + backoff_5g_midband = FT_PROG_VER3_5G_MID_OFDM_TXCEIL_BKOFF; + backoff_5g_highband = FT_PROG_VER3_5G_HIGH_OFDM_TXCEIL_BKOFF; + } + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR2G] = + tx_pwr_ceil_params->max_pwr_2g_dsss-backoff_2g_dsss; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR2GM0M7] = + tx_pwr_ceil_params->max_pwr_2g_mcs7-backoff_2g_ofdm; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR2GM0M7 + 1] = + tx_pwr_ceil_params->max_pwr_2g_mcs0-backoff_2g_ofdm; + + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM7] = + tx_pwr_ceil_params->max_pwr_5g_low_mcs7-backoff_5g_lowband; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM7 + 1] = + tx_pwr_ceil_params->max_pwr_5g_mid_mcs7-backoff_5g_midband; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM7 + 2] = + tx_pwr_ceil_params->max_pwr_5g_high_mcs7-backoff_5g_highband; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM0] = + tx_pwr_ceil_params->max_pwr_5g_low_mcs0-backoff_5g_lowband; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM0 + 1] = + tx_pwr_ceil_params->max_pwr_5g_mid_mcs0-backoff_5g_midband; + rf_params[NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM0 + 2] = + tx_pwr_ceil_params->max_pwr_5g_high_mcs0-backoff_5g_highband; + } +#endif + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_reg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_fmac_reg_info *reg_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_cmd_req_set_reg *set_reg_cmd = NULL; + + if (!fmac_dev_ctx || !reg_info) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + set_reg_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*set_reg_cmd)); + + if (!set_reg_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto out; + } + + set_reg_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_REQ_SET_REG; + set_reg_cmd->umac_hdr.ids.valid_fields = 0; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + set_reg_cmd->nrf_wifi_alpha2, + reg_info->alpha2, + NRF_WIFI_COUNTRY_CODE_LEN); + + set_reg_cmd->valid_fields = NRF_WIFI_CMD_REQ_SET_REG_ALPHA2_VALID; + + /* New feature in rev B patch */ + if (reg_info->force) { + set_reg_cmd->valid_fields |= NRF_WIFI_CMD_REQ_SET_REG_USER_REG_FORCE; + } + + status = umac_cmd_cfg(fmac_dev_ctx, + set_reg_cmd, + sizeof(*set_reg_cmd)); +out: + if (set_reg_cmd) { + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + set_reg_cmd); + } + + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_get_reg(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_fmac_reg_info *reg_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_umac_cmd_get_reg *get_reg_cmd = NULL; + unsigned int count = 0; + + if (!fmac_dev_ctx || !reg_info) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto err; + } + + get_reg_cmd = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + sizeof(*get_reg_cmd)); + + if (!get_reg_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate memory\n", + __func__); + goto err; + } + + get_reg_cmd->umac_hdr.cmd_evnt = NRF_WIFI_UMAC_CMD_GET_REG; + get_reg_cmd->umac_hdr.ids.valid_fields = 0; + + status = umac_cmd_cfg(fmac_dev_ctx, + get_reg_cmd, + sizeof(*get_reg_cmd)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to get regulatory information\n", __func__); + goto err; + } + + fmac_dev_ctx->alpha2_valid = false; + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + } while (count++ < 100 && !fmac_dev_ctx->alpha2_valid); + + if (!fmac_dev_ctx->alpha2_valid) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to get regulatory information\n", + __func__); + goto err; + } + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + reg_info->alpha2, + fmac_dev_ctx->alpha2, + sizeof(reg_info->alpha2)); + + return NRF_WIFI_STATUS_SUCCESS; +err: + return NRF_WIFI_STATUS_FAIL; +} + +#ifdef CONFIG_NRF700X_UTIL +enum nrf_wifi_status nrf_wifi_fmac_set_tx_rate(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char rate_flag, + int data_rate) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + struct nrf_wifi_cmd_fix_tx_rate *umac_cmd_data = NULL; + int len = 0; + + len = sizeof(*umac_cmd_data); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_SYSTEM, + len); + + if (!umac_cmd) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_alloc failed\n", + __func__); + goto out; + } + + umac_cmd_data = (struct nrf_wifi_cmd_fix_tx_rate *)(umac_cmd->msg); + + umac_cmd_data->sys_head.cmd_event = NRF_WIFI_CMD_TX_FIX_DATA_RATE; + umac_cmd_data->sys_head.len = len; + + umac_cmd_data->rate_flags = rate_flag; + umac_cmd_data->fixed_rate = data_rate; + + status = nrf_wifi_hal_ctrl_cmd_send(fmac_dev_ctx->hal_dev_ctx, + umac_cmd, + (sizeof(*umac_cmd) + len)); +out: + return status; +} + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +enum nrf_wifi_status nrf_wifi_fmac_get_host_rpu_ps_ctrl_state(void *dev_ctx, + int *rpu_ps_ctrl_state) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + + if (!fmac_dev_ctx || !rpu_ps_ctrl_state) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + + status = nrf_wifi_hal_get_rpu_ps_state(fmac_dev_ctx->hal_dev_ctx, + rpu_ps_ctrl_state); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Fetching of RPU PS state failed\n", + __func__); + goto out; + } +out: + return status; +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +#endif /* CONFIG_NRF700X_UTIL */ diff --git a/nrf_wifi/fw_if/umac_if/src/fmac_peer.c b/nrf_wifi/fw_if/umac_if/src/fmac_peer.c new file mode 100644 index 0000000000..cb4d0af7b4 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/fmac_peer.c @@ -0,0 +1,162 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing peer handling specific definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "hal_mem.h" +#include "fmac_peer.h" +#include "host_rpu_umac_if.h" +#include "fmac_util.h" + +int nrf_wifi_fmac_peer_get_id(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + const unsigned char *mac_addr) +{ + int i; + struct peers_info *peer; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (nrf_wifi_util_is_multicast_addr(mac_addr)) { + return MAX_PEERS; + } + + for (i = 0; i < MAX_PEERS; i++) { + peer = &def_dev_ctx->tx_config.peers[i]; + if (peer->peer_id == -1) { + continue; + } + + if ((nrf_wifi_util_ether_addr_equal(mac_addr, + (void *)peer->ra_addr))) { + return peer->peer_id; + } + } + return -1; +} + +int nrf_wifi_fmac_peer_add(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char if_idx, + const unsigned char *mac_addr, + unsigned char is_legacy, + unsigned char qos_supported) +{ + int i; + struct peers_info *peer; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + if (nrf_wifi_util_is_multicast_addr(mac_addr) + && (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP)) { + + def_dev_ctx->tx_config.peers[MAX_PEERS].if_idx = if_idx; + def_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = MAX_PEERS; + def_dev_ctx->tx_config.peers[MAX_PEERS].is_legacy = 1; + + + return MAX_PEERS; + } + + for (i = 0; i < MAX_PEERS; i++) { + peer = &def_dev_ctx->tx_config.peers[i]; + + if (peer->peer_id == -1) { + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + peer->ra_addr, + mac_addr, + NRF_WIFI_ETH_ADDR_LEN); + peer->if_idx = if_idx; + peer->peer_id = i; + peer->is_legacy = is_legacy; + peer->qos_supported = qos_supported; + if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) { + hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx, + (RPU_MEM_UMAC_PEND_Q_BMP + + sizeof(struct sap_pend_frames_bitmap) * i), + peer->ra_addr, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + } + return i; + } + } + + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed !! No Space Available", + __func__); + + return -1; +} + + +void nrf_wifi_fmac_peer_remove(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char if_idx, + int peer_id) +{ + struct peers_info *peer; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + peer = &def_dev_ctx->tx_config.peers[peer_id]; + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + peer, + 0x0, + sizeof(struct peers_info)); + peer->peer_id = -1; + + if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) { + hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx, + (RPU_MEM_UMAC_PEND_Q_BMP + + (sizeof(struct sap_pend_frames_bitmap) * peer_id)), + peer->ra_addr, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + } +} + + +void nrf_wifi_fmac_peers_flush(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char if_idx) +{ + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + unsigned int i = 0; + struct peers_info *peer = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + def_dev_ctx->tx_config.peers[MAX_PEERS].peer_id = -1; + + for (i = 0; i < MAX_PEERS; i++) { + peer = &def_dev_ctx->tx_config.peers[i]; + if (peer->if_idx == if_idx) { + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + peer, + 0x0, + sizeof(struct peers_info)); + peer->peer_id = -1; + + if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP) { + hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx, + (RPU_MEM_UMAC_PEND_Q_BMP + + sizeof(struct sap_pend_frames_bitmap) * i), + peer->ra_addr, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + } + } + } +} diff --git a/nrf_wifi/fw_if/umac_if/src/fmac_util.c b/nrf_wifi/fw_if/umac_if/src/fmac_util.c new file mode 100644 index 0000000000..a56c31bd5a --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/fmac_util.c @@ -0,0 +1,367 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing utility function definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "osal_api.h" +#include "fmac_api_common.h" +#include "fmac_util.h" +#include "host_rpu_umac_if.h" + +bool nrf_wifi_util_is_multicast_addr(const unsigned char *addr) +{ + return (0x01 & *addr); +} + + +bool nrf_wifi_util_is_unicast_addr(const unsigned char *addr) +{ + return !nrf_wifi_util_is_multicast_addr(addr); +} + + +bool nrf_wifi_util_ether_addr_equal(const unsigned char *addr_1, + const unsigned char *addr_2) +{ + const unsigned short *a = (const unsigned short *)addr_1; + const unsigned short *b = (const unsigned short *)addr_2; + + return ((a[0] ^ b[0]) | (a[1] ^ b[1]) | (a[2] ^ b[2])) == 0; +} + + +#ifdef CONFIG_NRF700X_STA_MODE +unsigned short nrf_wifi_util_rx_get_eth_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + unsigned char *payload = NULL; + + payload = (unsigned char *)nwb; + + return payload[6] << 8 | payload[7]; +} + + +unsigned short nrf_wifi_util_tx_get_eth_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + unsigned char *payload = NULL; + + payload = (unsigned char *)nwb; + + return payload[12] << 8 | payload[13]; +} + + +int nrf_wifi_util_get_skip_header_bytes(unsigned short eth_type) +{ + /* Ethernet-II snap header (RFC1042 for most EtherTypes) */ + unsigned char llc_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00}; + /* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */ + static unsigned char aarp_ipx_header[] = {0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8}; + int skip_header_bytes = 0; + + skip_header_bytes = sizeof(eth_type); + + if (eth_type == NRF_WIFI_FMAC_ETH_P_AARP || + eth_type == NRF_WIFI_FMAC_ETH_P_IPX) { + skip_header_bytes += sizeof(aarp_ipx_header); + } else if (eth_type >= NRF_WIFI_FMAC_ETH_P_802_3_MIN) { + skip_header_bytes += sizeof(llc_header); + } + + return skip_header_bytes; +} + + +void nrf_wifi_util_convert_to_eth(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb, + struct nrf_wifi_fmac_ieee80211_hdr *hdr, + unsigned short eth_type) +{ + + struct nrf_wifi_fmac_eth_hdr *ehdr = NULL; + unsigned int len = 0; + + len = nrf_wifi_osal_nbuf_data_size(fmac_dev_ctx->fpriv->opriv, + nwb); + + ehdr = (struct nrf_wifi_fmac_eth_hdr *) + nrf_wifi_osal_nbuf_data_push(fmac_dev_ctx->fpriv->opriv, + nwb, + sizeof(struct nrf_wifi_fmac_eth_hdr)); + + switch (hdr->fc & (NRF_WIFI_FCTL_TODS | NRF_WIFI_FCTL_FROMDS)) { + case (NRF_WIFI_FCTL_TODS | NRF_WIFI_FCTL_FROMDS): + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->src, + hdr->addr_4, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->dst, + hdr->addr_1, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + break; + case (NRF_WIFI_FCTL_FROMDS): + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->src, + hdr->addr_3, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->dst, + hdr->addr_1, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + break; + case (NRF_WIFI_FCTL_TODS): + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->src, + hdr->addr_2, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->dst, + hdr->addr_3, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + break; + default: + /* Both FROM and TO DS bit is zero*/ + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->src, + hdr->addr_2, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->dst, + hdr->addr_1, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + + } + + if (eth_type >= NRF_WIFI_FMAC_ETH_P_802_3_MIN) { + ehdr->proto = ((eth_type >> 8) | (eth_type << 8)); + } else { + ehdr->proto = len; + } +} + + +void nrf_wifi_util_rx_convert_amsdu_to_eth(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + struct nrf_wifi_fmac_eth_hdr *ehdr = NULL; + struct nrf_wifi_fmac_amsdu_hdr amsdu_hdr; + unsigned int len = 0; + unsigned short eth_type = 0; + void *nwb_data = NULL; + unsigned char amsdu_hdr_len = 0; + + amsdu_hdr_len = sizeof(struct nrf_wifi_fmac_amsdu_hdr); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &amsdu_hdr, + nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb), + amsdu_hdr_len); + + nwb_data = (unsigned char *)nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb) + amsdu_hdr_len; + + eth_type = nrf_wifi_util_rx_get_eth_type(fmac_dev_ctx, + nwb_data); + + nrf_wifi_osal_nbuf_data_pull(fmac_dev_ctx->fpriv->opriv, + nwb, + (amsdu_hdr_len + + nrf_wifi_util_get_skip_header_bytes(eth_type))); + + len = nrf_wifi_osal_nbuf_data_size(fmac_dev_ctx->fpriv->opriv, + nwb); + + ehdr = (struct nrf_wifi_fmac_eth_hdr *) + nrf_wifi_osal_nbuf_data_push(fmac_dev_ctx->fpriv->opriv, + nwb, + sizeof(struct nrf_wifi_fmac_eth_hdr)); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->src, + amsdu_hdr.src, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + ehdr->dst, + amsdu_hdr.dst, + NRF_WIFI_FMAC_ETH_ADDR_LEN); + + if (eth_type >= NRF_WIFI_FMAC_ETH_P_802_3_MIN) { + ehdr->proto = ((eth_type >> 8) | (eth_type << 8)); + } else { + ehdr->proto = len; + } +} + + +int nrf_wifi_util_get_tid(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + unsigned short ether_type = 0; + int priority = 0; + unsigned short vlan_tci = 0; + unsigned char vlan_priority = 0; + unsigned int mpls_hdr = 0; + unsigned char mpls_tc_qos = 0; + unsigned char tos = 0; + unsigned char dscp = 0; + unsigned short ipv6_hdr = 0; + void *nwb_data = NULL; + + nwb_data = nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb); + + ether_type = nrf_wifi_util_tx_get_eth_type(fmac_dev_ctx, + nwb_data); + + nwb_data = (unsigned char *)nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb) + NRF_WIFI_FMAC_ETH_HDR_LEN; + + switch (ether_type & NRF_WIFI_FMAC_ETH_TYPE_MASK) { + /* If VLAN 802.1Q (0x8100) || + * 802.1AD(0x88A8) FRAME calculate priority accordingly + */ + case NRF_WIFI_FMAC_ETH_P_8021Q: + case NRF_WIFI_FMAC_ETH_P_8021AD: + vlan_tci = (((unsigned char *)nwb_data)[4] << 8) | + (((unsigned char *)nwb_data)[5]); + vlan_priority = ((vlan_tci & NRF_WIFI_FMAC_VLAN_PRIO_MASK) + >> NRF_WIFI_FMAC_VLAN_PRIO_SHIFT); + priority = vlan_priority; + break; + /* If MPLS MC(0x8840) / UC(0x8847) frame calculate priority + * accordingly + */ + case NRF_WIFI_FMAC_ETH_P_MPLS_UC: + case NRF_WIFI_FMAC_ETH_P_MPLS_MC: + mpls_hdr = (((unsigned char *)nwb_data)[0] << 24) | + (((unsigned char *)nwb_data)[1] << 16) | + (((unsigned char *)nwb_data)[2] << 8) | + (((unsigned char *)nwb_data)[3]); + mpls_tc_qos = (mpls_hdr & (NRF_WIFI_FMAC_MPLS_LS_TC_MASK) + >> NRF_WIFI_FMAC_MPLS_LS_TC_SHIFT); + priority = mpls_tc_qos; + break; + /* If IP (0x0800) frame calculate priority accordingly */ + case NRF_WIFI_FMAC_ETH_P_IP: + /*get the tos filed*//*DA+SA+ETH+(VER+IHL)*/ + tos = (((unsigned char *)nwb_data)[1]); + /*get the dscp value */ + dscp = (tos & 0xfc); + priority = dscp >> 5; + break; + case NRF_WIFI_FMAC_ETH_P_IPV6: + /* Get the TOS filled DA+SA+ETH */ + ipv6_hdr = (((unsigned char *)nwb_data)[0] << 8) | + ((unsigned char *)nwb_data)[1]; + dscp = (((ipv6_hdr & NRF_WIFI_FMAC_IPV6_TOS_MASK) + >> NRF_WIFI_FMAC_IPV6_TOS_SHIFT) & 0xfc); + priority = dscp >> 5; + break; + /* If Media Independent (0x8917) + * frame calculate priority accordingly. + */ + case NRF_WIFI_FMAC_ETH_P_80221: + /* 802.21 is always network control traffic */ + priority = 0x07; + break; + default: + priority = 0; + } + + return priority; +} + + +int nrf_wifi_util_get_vif_indx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + const unsigned char *mac_addr) +{ + int i = 0; + int vif_index = -1; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + for (i = 0; i < MAX_PEERS; i++) { + if (!nrf_wifi_util_ether_addr_equal(def_dev_ctx->tx_config.peers[i].ra_addr, + mac_addr)) { + vif_index = def_dev_ctx->tx_config.peers[i].if_idx; + break; + } + } + + if (vif_index == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid vif_index = %d", + __func__, + vif_index); + } + + return vif_index; +} + + +unsigned char *nrf_wifi_util_get_dest(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + return nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb); +} + + +unsigned char *nrf_wifi_util_get_ra(struct nrf_wifi_fmac_vif_ctx *vif, + void *nwb) +{ + if (vif->if_type == NRF_WIFI_IFTYPE_STATION) { + return vif->bssid; + } + + return nrf_wifi_osal_nbuf_data_get(vif->fmac_dev_ctx->fpriv->opriv, + nwb); +} + + +unsigned char *nrf_wifi_util_get_src(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + return (unsigned char *)nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb) + NRF_WIFI_FMAC_ETH_ADDR_LEN; +} + +#endif /* CONFIG_NRF700X_STA_MODE */ + + +bool nrf_wifi_util_is_arr_zero(unsigned char *arr, + unsigned int arr_sz) +{ + unsigned int i = 0; + + for (i = 0; i < arr_sz; i++) { + if (arr[i] != 0) { + return false; + } + } + + return true; +} + +void *wifi_fmac_priv(struct nrf_wifi_fmac_priv *def) +{ + return &def->priv; +} + +void *wifi_dev_priv(struct nrf_wifi_fmac_dev_ctx *def) +{ + return &def->priv; +} diff --git a/nrf_wifi/fw_if/umac_if/src/fmac_vif.c b/nrf_wifi/fw_if/umac_if/src/fmac_vif.c new file mode 100644 index 0000000000..771316128f --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/fmac_vif.c @@ -0,0 +1,157 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing VIF handling specific definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "fmac_vif.h" +#include "host_rpu_umac_if.h" +#include "fmac_util.h" + + +int nrf_wifi_fmac_vif_check_if_limit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_type) +{ + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + switch (if_type) { + case NRF_WIFI_IFTYPE_STATION: + case NRF_WIFI_IFTYPE_P2P_CLIENT: + if (def_dev_ctx->num_sta >= MAX_NUM_STAS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Maximum STA Interface type exceeded\n", + __func__); + return -1; + } + break; + case NRF_WIFI_IFTYPE_AP: + case NRF_WIFI_IFTYPE_P2P_GO: + if (def_dev_ctx->num_ap >= MAX_NUM_APS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Maximum AP Interface type exceeded\n", + __func__); + return -1; + } + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Interface type not supported\n", + __func__); + return -1; + } + + return 0; +} + + +void nrf_wifi_fmac_vif_incr_if_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_type) +{ + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + switch (if_type) { + case NRF_WIFI_IFTYPE_STATION: + case NRF_WIFI_IFTYPE_P2P_CLIENT: + def_dev_ctx->num_sta++; + break; + case NRF_WIFI_IFTYPE_AP: + case NRF_WIFI_IFTYPE_P2P_GO: + def_dev_ctx->num_ap++; + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s:Unsupported VIF type\n", + __func__); + } +} + + +void nrf_wifi_fmac_vif_decr_if_type(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_type) +{ + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + switch (if_type) { + case NRF_WIFI_IFTYPE_STATION: + case NRF_WIFI_IFTYPE_P2P_CLIENT: + def_dev_ctx->num_sta--; + break; + case NRF_WIFI_IFTYPE_AP: + case NRF_WIFI_IFTYPE_P2P_GO: + def_dev_ctx->num_ap--; + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s:Unsupported VIF type\n", + __func__); + } +} + + +void nrf_wifi_fmac_vif_clear_ctx(void *dev_ctx, + unsigned char if_idx) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + vif_ctx); + def_dev_ctx->vif_ctx[if_idx] = NULL; +} + + +void nrf_wifi_fmac_vif_update_if_type(void *dev_ctx, + unsigned char if_idx, + int if_type) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + vif_ctx = def_dev_ctx->vif_ctx[if_idx]; + + nrf_wifi_fmac_vif_decr_if_type(fmac_dev_ctx, + vif_ctx->if_type); + + nrf_wifi_fmac_vif_incr_if_type(fmac_dev_ctx, + if_type); + + vif_ctx->if_type = if_type; +} + +unsigned int nrf_wifi_fmac_get_num_vifs(void *dev_ctx) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = dev_ctx; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!fmac_dev_ctx) { + /* Don't return error here, as FMAC might be initialized based + * the number of VIFs. + */ + return 0; + } + + return def_dev_ctx->num_sta + def_dev_ctx->num_ap; +} diff --git a/nrf_wifi/fw_if/umac_if/src/radio_test/fmac_api.c b/nrf_wifi/fw_if/umac_if/src/radio_test/fmac_api.c new file mode 100644 index 0000000000..02b2999e9b --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/radio_test/fmac_api.c @@ -0,0 +1,776 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing API definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "host_rpu_umac_if.h" +#include "fmac_api.h" +#include "hal_api.h" +#include "fmac_structs.h" +#include "fmac_api.h" +#include "fmac_util.h" +#include "fmac_peer.h" +#include "fmac_vif.h" +#include "fmac_tx.h" +#include "fmac_rx.h" +#include "fmac_cmd.h" +#include "fmac_event.h" +#include "fmac_bb.h" +#include "util.h" + +#define RADIO_CMD_STATUS_TIMEOUT 5000 + + + +static enum nrf_wifi_status nrf_wifi_fmac_fw_init_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl) +{ + unsigned long start_time_us = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = umac_cmd_init(fmac_dev_ctx, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + phy_calib, + op_band, + beamforming, + tx_pwr_ctrl); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC init failed\n", + __func__); + goto out; + } + start_time_us = nrf_wifi_osal_time_get_curr_us(fmac_dev_ctx->fpriv->opriv); + while (!fmac_dev_ctx->fw_init_done) { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, 1); +#define MAX_INIT_WAIT (5 * 1000 * 1000) + if (nrf_wifi_osal_time_elapsed_us(fmac_dev_ctx->fpriv->opriv, + start_time_us) >= MAX_INIT_WAIT) { + break; + } + } + + if (!fmac_dev_ctx->fw_init_done) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: UMAC init timed out\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + status = NRF_WIFI_STATUS_SUCCESS; + +out: + return status; +} + +static void nrf_wifi_fmac_fw_deinit_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ +} + +void nrf_wifi_fmac_dev_rem_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + nrf_wifi_hal_dev_rem(fmac_dev_ctx->hal_dev_ctx); + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + fmac_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_fmac_dev_init_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + int sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + unsigned int phy_calib, + enum op_band op_band, + bool beamforming, + struct nrf_wifi_tx_pwr_ctrl_params *tx_pwr_ctrl_params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!fmac_dev_ctx) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid device context\n", + __func__); + goto out; + } + + status = nrf_wifi_hal_dev_init(fmac_dev_ctx->hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_dev_init failed\n", + __func__); + goto out; + } + + + status = nrf_wifi_fmac_fw_init_rt(fmac_dev_ctx, +#ifdef CONFIG_NRF_WIFI_LOW_POWER + sleep_type, +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + phy_calib, + op_band, + beamforming, + tx_pwr_ctrl_params); + + if (status == NRF_WIFI_STATUS_FAIL) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_fw_init failed\n", + __func__); + goto out; + } +out: + return status; +} + +void nrf_wifi_fmac_dev_deinit_rt(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + nrf_wifi_fmac_fw_deinit_rt(fmac_dev_ctx); +} + +struct nrf_wifi_fmac_priv *nrf_wifi_fmac_init_rt(void) +{ + struct nrf_wifi_osal_priv *opriv = NULL; + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_hal_cfg_params hal_cfg_params; + + opriv = nrf_wifi_osal_init(); + + if (!opriv) { + goto out; + } + + fpriv = nrf_wifi_osal_mem_zalloc(opriv, + sizeof(*fpriv)); + + if (!fpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate fpriv\n", + __func__); + goto out; + } + + fpriv->opriv = opriv; + + nrf_wifi_osal_mem_set(opriv, + &hal_cfg_params, + 0, + sizeof(hal_cfg_params)); + + + hal_cfg_params.max_cmd_size = MAX_NRF_WIFI_UMAC_CMD_SIZE; + hal_cfg_params.max_event_size = MAX_EVENT_POOL_LEN; + + fpriv->hpriv = nrf_wifi_hal_init(opriv, + &hal_cfg_params, + &nrf_wifi_fmac_event_callback); + + if (!fpriv->hpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to do HAL init\n", + __func__); + nrf_wifi_osal_mem_free(opriv, + fpriv); + fpriv = NULL; + nrf_wifi_osal_deinit(opriv); + opriv = NULL; + goto out; + } +out: + return fpriv; +} + + +void nrf_wifi_fmac_deinit_rt(struct nrf_wifi_fmac_priv *fpriv) +{ + struct nrf_wifi_osal_priv *opriv = NULL; + + opriv = fpriv->opriv; + + nrf_wifi_hal_deinit(fpriv->hpriv); + + nrf_wifi_osal_mem_free(opriv, + fpriv); + + nrf_wifi_osal_deinit(opriv); +} + +enum nrf_wifi_status wait_for_radio_cmd_status(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int timeout) +{ + unsigned int count = 0; + enum nrf_wifi_radio_test_err_status radio_cmd_status; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 1); + count++; + } while ((!rt_dev_ctx->radio_cmd_done) && + (count < timeout)); + + if (count == timeout) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out (%d secs)\n", + __func__, + timeout / 1000); + goto out; + } + + radio_cmd_status = rt_dev_ctx->radio_cmd_status; + + if (radio_cmd_status != NRF_WIFI_UMAC_CMD_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Radio test command failed with status %d\n", + __func__, + radio_cmd_status); + goto out; + } + return NRF_WIFI_STATUS_SUCCESS; + +out: + return NRF_WIFI_STATUS_FAIL; +} + +enum nrf_wifi_status nrf_wifi_fmac_radio_test_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_radio_test_init_info init_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &init_params, + 0, + sizeof(init_params)); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + init_params.rf_params, + params->rf_params, + NRF_WIFI_RF_PARAMS_SIZE); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &init_params.chan, + ¶ms->chan, + sizeof(init_params.chan)); + + init_params.phy_threshold = params->phy_threshold; + init_params.phy_calib = params->phy_calib; + + rt_dev_ctx->radio_cmd_done = false; + status = umac_cmd_prog_init(fmac_dev_ctx, + &init_params); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to init radio test\n", + __func__); + goto out; + } + + status = wait_for_radio_cmd_status(fmac_dev_ctx, + RADIO_CMD_STATUS_TIMEOUT); + if (status != NRF_WIFI_STATUS_SUCCESS) { + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_radio_test_prog_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + rt_dev_ctx->radio_cmd_done = false; + status = umac_cmd_prog_tx(fmac_dev_ctx, + params); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to program radio test TX\n", + __func__); + goto out; + } + + status = wait_for_radio_cmd_status(fmac_dev_ctx, + RADIO_CMD_STATUS_TIMEOUT); + if (status != NRF_WIFI_STATUS_SUCCESS) { + goto out; + } +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_radio_test_prog_rx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct rpu_conf_params *params) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct rpu_conf_rx_radio_test_params rx_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rx_params, + 0, + sizeof(rx_params)); + + rx_params.nss = params->nss; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + rx_params.rf_params, + params->rf_params, + NRF_WIFI_RF_PARAMS_SIZE); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &rx_params.chan, + ¶ms->chan, + sizeof(rx_params.chan)); + + rx_params.phy_threshold = params->phy_threshold; + rx_params.phy_calib = params->phy_calib; + rx_params.rx = params->rx; + + rt_dev_ctx->radio_cmd_done = false; + status = umac_cmd_prog_rx(fmac_dev_ctx, + &rx_params); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to program radio test RX\n", + __func__); + goto out; + } + + status = wait_for_radio_cmd_status(fmac_dev_ctx, + RADIO_CMD_STATUS_TIMEOUT); + if (status != NRF_WIFI_STATUS_SUCCESS) { + goto out; + } +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rf_test_rx_cap(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + enum nrf_wifi_rf_test rf_test_type, + void *cap_data, + unsigned short int num_samples, + unsigned char lna_gain, + unsigned char bb_gain) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_rf_test_capture_params rf_test_cap_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rf_test_cap_params, + 0, + sizeof(rf_test_cap_params)); + + rf_test_cap_params.test = rf_test_type; + rf_test_cap_params.cap_len = num_samples; + rf_test_cap_params.lna_gain = lna_gain; + rf_test_cap_params.bb_gain = bb_gain; + + rt_dev_ctx->rf_test_type = rf_test_type; + rt_dev_ctx->rf_test_cap_data = cap_data; + rt_dev_ctx->rf_test_cap_sz = (num_samples * 3); + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &rf_test_cap_params, + sizeof(rf_test_cap_params)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_rf_test_cap failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rf_test_tx_tone(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char enable, + signed char tone_freq, + signed char tx_power) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_rf_test_tx_params rf_test_tx_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rf_test_tx_params, + 0, + sizeof(rf_test_tx_params)); + + rf_test_tx_params.test = NRF_WIFI_RF_TEST_TX_TONE; + rf_test_tx_params.tone_freq = tone_freq; + rf_test_tx_params.tx_pow = tx_power; + rf_test_tx_params.enabled = enable; + + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_TX_TONE; + rt_dev_ctx->rf_test_cap_data = NULL; + rt_dev_ctx->rf_test_cap_sz = 0; + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &rf_test_tx_params, + sizeof(rf_test_tx_params)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_rf_test_tx_tone failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rf_test_dpd(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char enable) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_rf_test_dpd_params rf_test_dpd_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rf_test_dpd_params, + 0, + sizeof(rf_test_dpd_params)); + + rf_test_dpd_params.test = NRF_WIFI_RF_TEST_DPD; + rf_test_dpd_params.enabled = enable; + + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_DPD; + rt_dev_ctx->rf_test_cap_data = NULL; + rt_dev_ctx->rf_test_cap_sz = 0; + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &rf_test_dpd_params, + sizeof(rf_test_dpd_params)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_rf_test_dpd failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rf_get_temp(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_temperature_params rf_test_get_temperature; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rf_test_get_temperature, + 0, + sizeof(rf_test_get_temperature)); + + rf_test_get_temperature.test = NRF_WIFI_RF_TEST_GET_TEMPERATURE; + + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_GET_TEMPERATURE; + rt_dev_ctx->rf_test_cap_data = NULL; + rt_dev_ctx->rf_test_cap_sz = 0; + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &rf_test_get_temperature, + sizeof(rf_test_get_temperature)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_rf_get_temperature failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} + +enum nrf_wifi_status nrf_wifi_fmac_rf_get_rf_rssi(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_rf_get_rf_rssi rf_get_rf_rssi_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rf_get_rf_rssi_params, + 0, + sizeof(rf_get_rf_rssi_params)); + + rf_get_rf_rssi_params.test = NRF_WIFI_RF_TEST_RF_RSSI; + rf_get_rf_rssi_params.lna_gain = 3; + rf_get_rf_rssi_params.bb_gain = 10; + + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_RF_RSSI; + rt_dev_ctx->rf_test_cap_data = NULL; + rt_dev_ctx->rf_test_cap_sz = 0; + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &rf_get_rf_rssi_params, + sizeof(rf_get_rf_rssi_params)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_rf_get_rf_rssi failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_set_xo_val(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char value) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_rf_test_xo_calib nrf_wifi_rf_test_xo_calib_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &nrf_wifi_rf_test_xo_calib_params, + 0, + sizeof(nrf_wifi_rf_test_xo_calib_params)); + + nrf_wifi_rf_test_xo_calib_params.test = NRF_WIFI_RF_TEST_XO_CALIB; + nrf_wifi_rf_test_xo_calib_params.xo_val = value; + + + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_XO_CALIB; + rt_dev_ctx->rf_test_cap_data = NULL; + rt_dev_ctx->rf_test_cap_sz = 0; + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &nrf_wifi_rf_test_xo_calib_params, + sizeof(nrf_wifi_rf_test_xo_calib_params)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_set_xo_val failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rf_test_compute_xo(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_rf_get_xo_value rf_get_xo_value_params; + struct nrf_wifi_fmac_dev_ctx_rt *rt_dev_ctx = NULL; + unsigned int count = 0; + + rt_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rf_get_xo_value_params, + 0, + sizeof(rf_get_xo_value_params)); + + rf_get_xo_value_params.test = NRF_WIFI_RF_TEST_XO_TUNE; + + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_XO_TUNE; + rt_dev_ctx->rf_test_cap_data = NULL; + rt_dev_ctx->rf_test_cap_sz = 0; + + status = umac_cmd_prog_rf_test(fmac_dev_ctx, + &rf_get_xo_value_params, + sizeof(rf_get_xo_value_params)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: umac_cmd_prog_rf_get_xo_value failed\n", + __func__); + + goto out; + } + + do { + nrf_wifi_osal_sleep_ms(fmac_dev_ctx->fpriv->opriv, + 100); + count++; + } while ((rt_dev_ctx->rf_test_type != NRF_WIFI_RF_TEST_MAX) && + (count < NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT)); + + if (count == NRF_WIFI_FMAC_RF_TEST_EVNT_TIMEOUT) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Timed out\n", + __func__); + rt_dev_ctx->rf_test_type = NRF_WIFI_RF_TEST_MAX; + rt_dev_ctx->rf_test_cap_data = NULL; + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + +out: + return status; +} diff --git a/nrf_wifi/fw_if/umac_if/src/rx.c b/nrf_wifi/fw_if/umac_if/src/rx.c new file mode 100644 index 0000000000..732aebe8e8 --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/rx.c @@ -0,0 +1,376 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing RX data path specific function definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "hal_api.h" +#include "fmac_rx.h" +#include "fmac_util.h" + + +static enum nrf_wifi_status +nrf_wifi_fmac_map_desc_to_pool(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc_id, + struct nrf_wifi_fmac_rx_pool_map_info *pool_info) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + unsigned int pool_id = 0; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + for (pool_id = 0; pool_id < MAX_NUM_OF_RX_QUEUES; pool_id++) { + if ((desc_id >= def_priv->rx_desc[pool_id]) && + (desc_id < (def_priv->rx_desc[pool_id] + + def_priv->rx_buf_pools[pool_id].num_bufs))) { + pool_info->pool_id = pool_id; + pool_info->buf_id = (desc_id - def_priv->rx_desc[pool_id]); + status = NRF_WIFI_STATUS_SUCCESS; + goto out; + } + } +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_fmac_rx_cmd_send(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + enum nrf_wifi_fmac_rx_cmd_type cmd_type, + unsigned int desc_id) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_buf_map_info *rx_buf_info = NULL; + struct host_rpu_rx_buf_info rx_cmd; + struct nrf_wifi_fmac_rx_pool_map_info pool_info; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + unsigned long nwb = 0; + unsigned long nwb_data = 0; + unsigned long phy_addr = 0; + unsigned int buf_len = 0; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + status = nrf_wifi_fmac_map_desc_to_pool(fmac_dev_ctx, + desc_id, + &pool_info); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_map_desc_to_pool failed\n", + __func__); + goto out; + } + + rx_buf_info = &def_dev_ctx->rx_buf_info[desc_id]; + + buf_len = def_priv->rx_buf_pools[pool_info.pool_id].buf_sz + RX_BUF_HEADROOM; + + if (cmd_type == NRF_WIFI_FMAC_RX_CMD_TYPE_INIT) { + if (rx_buf_info->mapped) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Init RX command called for already mapped RX buffer(%d)\n", + __func__, + desc_id); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nwb = (unsigned long)nrf_wifi_osal_nbuf_alloc(fmac_dev_ctx->fpriv->opriv, + buf_len); + + if (!nwb) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No space for allocating RX buffer\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nwb_data = (unsigned long)nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + (void *)nwb); + + *(unsigned int *)(nwb_data) = desc_id; + + phy_addr = nrf_wifi_hal_buf_map_rx(fmac_dev_ctx->hal_dev_ctx, + nwb_data, + buf_len, + pool_info.pool_id, + pool_info.buf_id); + + if (!phy_addr) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_buf_map_rx failed\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + rx_buf_info->nwb = nwb; + rx_buf_info->mapped = true; + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &rx_cmd, + 0x0, + sizeof(rx_cmd)); + + rx_cmd.addr = (unsigned int)phy_addr; + + status = nrf_wifi_hal_data_cmd_send(fmac_dev_ctx->hal_dev_ctx, + NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX, + &rx_cmd, + sizeof(rx_cmd), + desc_id, + pool_info.pool_id); + } else if (cmd_type == NRF_WIFI_FMAC_RX_CMD_TYPE_DEINIT) { + /* TODO: Need to initialize a command and send it to LMAC + * when LMAC is capable of handling deinit command + */ + if (!rx_buf_info->mapped) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Deinit RX command called for unmapped RX buffer(%d)\n", + __func__, + desc_id); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nwb_data = nrf_wifi_hal_buf_unmap_rx(fmac_dev_ctx->hal_dev_ctx, + 0, + pool_info.pool_id, + pool_info.buf_id); + + if (!nwb_data) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_buf_unmap_rx failed\n", + __func__); + goto out; + } + + nrf_wifi_osal_nbuf_free(fmac_dev_ctx->fpriv->opriv, + (void *)rx_buf_info->nwb); + rx_buf_info->nwb = 0; + rx_buf_info->mapped = false; + status = NRF_WIFI_STATUS_SUCCESS; + } else { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unknown cmd_type (%d)\n", + __func__, + cmd_type); + goto out; + } +out: + return status; +} + + +#ifdef CONFIG_NRF700X_RX_WQ_ENABLED +void nrf_wifi_fmac_rx_tasklet(void *data) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)data; + struct nrf_wifi_rx_buff *config = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + config = (struct nrf_wifi_rx_buff *)nrf_wifi_utils_q_dequeue( + fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->rx_tasklet_event_q); + + if (!config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: No RX config available\n", + __func__); + goto out; + } + + status = nrf_wifi_fmac_rx_event_process(fmac_dev_ctx, + config); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_rx_event_process failed\n", + __func__); + goto out; + } +out: + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + config); +} +#endif /* CONFIG_NRF700X_RX_WQ_ENABLED */ + +enum nrf_wifi_status nrf_wifi_fmac_rx_event_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_rx_buff *config) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + struct nrf_wifi_fmac_buf_map_info *rx_buf_info = NULL; + struct nrf_wifi_fmac_rx_pool_map_info pool_info; + void *nwb = NULL; + void *nwb_data = NULL; + unsigned int num_pkts = 0; + unsigned int desc_id = 0; + unsigned int i = 0; + unsigned int pkt_len = 0; +#ifdef CONFIG_NRF700X_STA_MODE + struct nrf_wifi_fmac_ieee80211_hdr hdr; + unsigned short eth_type = 0; + unsigned int size = 0; +#endif /* CONFIG_NRF700X_STA_MODE */ + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + vif_ctx = def_dev_ctx->vif_ctx[config->wdev_id]; + +#ifdef CONFIG_NRF700X_STA_MODE + def_priv->callbk_fns.process_rssi_from_rx(vif_ctx->os_vif_ctx, + config->signal); +#endif /* CONFIG_NRF700X_STA_MODE */ + num_pkts = config->rx_pkt_cnt; + + for (i = 0; i < num_pkts; i++) { + desc_id = config->rx_buff_info[i].descriptor_id; + pkt_len = config->rx_buff_info[i].rx_pkt_len; + + if (desc_id >= def_priv->num_rx_bufs) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid desc_id %d\n", + __func__, + desc_id); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + status = nrf_wifi_fmac_map_desc_to_pool(fmac_dev_ctx, + desc_id, + &pool_info); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_map_desc_to_pool failed\n", + __func__); + goto out; + } + + nwb_data = (void *)nrf_wifi_hal_buf_unmap_rx(fmac_dev_ctx->hal_dev_ctx, + pkt_len, + pool_info.pool_id, + pool_info.buf_id); + + if (!nwb_data) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_buf_unmap_rx failed\n", + __func__); + goto out; + } + + rx_buf_info = &def_dev_ctx->rx_buf_info[desc_id]; + nwb = (void *)rx_buf_info->nwb; + + nrf_wifi_osal_nbuf_data_put(fmac_dev_ctx->fpriv->opriv, + nwb, + pkt_len + RX_BUF_HEADROOM); + nrf_wifi_osal_nbuf_data_pull(fmac_dev_ctx->fpriv->opriv, + nwb, + RX_BUF_HEADROOM); + nwb_data = nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb); + + rx_buf_info->nwb = 0; + rx_buf_info->mapped = false; + + if (config->rx_pkt_type == NRF_WIFI_RX_PKT_DATA) { +#ifdef CONFIG_NRF700X_STA_MODE + switch (config->rx_buff_info[i].pkt_type) { + case PKT_TYPE_MPDU: + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + &hdr, + nwb_data, + sizeof(struct nrf_wifi_fmac_ieee80211_hdr)); + + eth_type = nrf_wifi_util_rx_get_eth_type(fmac_dev_ctx, + ((char *)nwb_data + + config->mac_header_len)); + + size = config->mac_header_len + + nrf_wifi_util_get_skip_header_bytes(eth_type); + + /* Remove hdr len and llc header/length */ + nrf_wifi_osal_nbuf_data_pull(fmac_dev_ctx->fpriv->opriv, + nwb, + size); + + nrf_wifi_util_convert_to_eth(fmac_dev_ctx, + nwb, + &hdr, + eth_type); + break; + case PKT_TYPE_MSDU_WITH_MAC: + nrf_wifi_osal_nbuf_data_pull(fmac_dev_ctx->fpriv->opriv, + nwb, + config->mac_header_len); + + nrf_wifi_util_rx_convert_amsdu_to_eth(fmac_dev_ctx, + nwb); + break; + case PKT_TYPE_MSDU: + nrf_wifi_util_rx_convert_amsdu_to_eth(fmac_dev_ctx, + nwb); + break; + default: + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid pkt_type=%d\n", + __func__, + (config->rx_buff_info[i].pkt_type)); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + def_priv->callbk_fns.rx_frm_callbk_fn(vif_ctx->os_vif_ctx, + nwb); +#endif /* CONFIG_NRF700X_STA_MODE */ + } else if (config->rx_pkt_type == NRF_WIFI_RX_PKT_BCN_PRB_RSP) { +#ifdef CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS + def_priv->callbk_fns.rx_bcn_prb_resp_callbk_fn( + vif_ctx->os_vif_ctx, + nwb, + config->frequency, + config->signal); +#endif /* CONFIG_WIFI_MGMT_RAW_SCAN_RESULTS */ + nrf_wifi_osal_nbuf_free(fmac_dev_ctx->fpriv->opriv, + nwb); + } else { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid frame type recd %d\n", + __func__, + config->rx_pkt_type); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + status = nrf_wifi_fmac_rx_cmd_send(fmac_dev_ctx, + NRF_WIFI_FMAC_RX_CMD_TYPE_INIT, + desc_id); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_fmac_rx_cmd_send failed\n", + __func__); + goto out; + } + } +out: + return status; +} diff --git a/nrf_wifi/fw_if/umac_if/src/tx.c b/nrf_wifi/fw_if/umac_if/src/tx.c new file mode 100644 index 0000000000..f477dd21cf --- /dev/null +++ b/nrf_wifi/fw_if/umac_if/src/tx.c @@ -0,0 +1,1587 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing TX data path specific function definitions for the + * FMAC IF Layer of the Wi-Fi driver. + */ + +#include "list.h" +#include "queue.h" +#include "hal_api.h" +#include "fmac_tx.h" +#include "fmac_api.h" +#include "fmac_peer.h" +#include "hal_mem.h" +#include "fmac_util.h" + +static bool is_twt_emergency_pkt(struct nrf_wifi_osal_priv *opriv, void *nwb) +{ + unsigned char priority = nrf_wifi_osal_nbuf_get_priority(opriv, nwb); + + return priority == NRF_WIFI_AC_TWT_PRIORITY_EMERGENCY; +} + +/* Can be extended for other cases as well */ +static bool can_xmit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb) +{ + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + return is_twt_emergency_pkt(fmac_dev_ctx->fpriv->opriv, nwb) || + def_dev_ctx->twt_sleep_status == NRF_WIFI_FMAC_TWT_STATE_AWAKE; +} + +/* Set the coresponding bit of access category. + * First 4 bits(0 to 3) represenst first spare desc access cateogories + * Second 4 bits(4 to 7) represenst second spare desc access cateogories and so on + */ +static void set_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc, + int tx_done_q) +{ + unsigned short spare_desc_indx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + nrf_wifi_osal_assert(fmac_dev_ctx->fpriv->opriv, + def_priv->num_tx_tokens_per_ac, + 0, + NRF_WIFI_ASSERT_NOT_EQUAL_TO, + "num_tx_tokens_per_ac is zero"); + + spare_desc_indx = (desc % (def_priv->num_tx_tokens_per_ac * + NRF_WIFI_FMAC_AC_MAX)); + + def_dev_ctx->tx_config.spare_desc_queue_map |= + (1 << ((spare_desc_indx * SPARE_DESC_Q_MAP_SIZE) + tx_done_q)); +} + + +/* Clear the coresponding bit of access category. + * First 4 bits(0 to 3) represenst first spare desc access cateogories + * Second 4 bits(4 to 7) represenst second spare desc access cateogories and so on + */ +static void clear_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc, + int tx_done_q) +{ + unsigned short spare_desc_indx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + nrf_wifi_osal_assert(fmac_dev_ctx->fpriv->opriv, + def_priv->num_tx_tokens_per_ac, + 0, + NRF_WIFI_ASSERT_NOT_EQUAL_TO, + "num_tx_tokens_per_ac is zero"); + + spare_desc_indx = (desc % (def_priv->num_tx_tokens_per_ac * + NRF_WIFI_FMAC_AC_MAX)); + + def_dev_ctx->tx_config.spare_desc_queue_map &= + ~(1 << ((spare_desc_indx * SPARE_DESC_Q_MAP_SIZE) + tx_done_q)); +} + +/*Get the spare descriptor queue map */ +static unsigned short get_spare_desc_q_map(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc) +{ + unsigned short spare_desc_indx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + spare_desc_indx = (desc % (def_priv->num_tx_tokens_per_ac * + NRF_WIFI_FMAC_AC_MAX)); + + return (def_dev_ctx->tx_config.spare_desc_queue_map >> (spare_desc_indx * + SPARE_DESC_Q_MAP_SIZE)) & 0x000F; +} + + +int pending_frames_count(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int peer_id) +{ + int count = 0; + int ac = 0; + void *queue = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + for (ac = NRF_WIFI_FMAC_AC_VO; ac >= 0; --ac) { + queue = def_dev_ctx->tx_config.data_pending_txq[peer_id][ac]; + count += nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, queue); + } + + return count; +} + + +enum nrf_wifi_status update_pend_q_bmp(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int ac, + int peer_id) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + void *pend_pkt_q = NULL; + int len = 0; + unsigned char vif_id = 0; + unsigned char *bmp = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!fmac_dev_ctx) { + goto out; + } + + vif_id = def_dev_ctx->tx_config.peers[peer_id].if_idx; + vif_ctx = def_dev_ctx->vif_ctx[vif_id]; + + if (vif_ctx->if_type == NRF_WIFI_IFTYPE_AP && + peer_id < MAX_PEERS) { + bmp = &def_dev_ctx->tx_config.peers[peer_id].pend_q_bmp; + pend_pkt_q = def_dev_ctx->tx_config.data_pending_txq[peer_id][ac]; + + len = nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, pend_pkt_q); + + if (len == 0) { + *bmp = *bmp & ~(1 << ac); + } else { + *bmp = *bmp | (1 << ac); + } + + status = hal_rpu_mem_write(fmac_dev_ctx->hal_dev_ctx, + (RPU_MEM_UMAC_PEND_Q_BMP + + (sizeof(struct sap_pend_frames_bitmap) * peer_id) + + NRF_WIFI_FMAC_ETH_ADDR_LEN), + bmp, + sizeof(unsigned char)); + } else { + status = NRF_WIFI_STATUS_SUCCESS; + } +out: + return status; +} + + +void tx_desc_free(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc, + int queue) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + int bit = -1; + int pool_id = -1; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + fpriv = fmac_dev_ctx->fpriv; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fpriv); + + bit = (desc % TX_DESC_BUCKET_BOUND); + pool_id = (desc / TX_DESC_BUCKET_BOUND); + + if (!(def_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] & (1 << bit))) { + return; + } + + def_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] &= (~(1 << bit)); + + def_dev_ctx->tx_config.outstanding_descs[queue]--; + + if (desc >= (def_priv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX)) { + clear_spare_desc_q_map(fmac_dev_ctx, desc, queue); + } + +} + + +unsigned int tx_desc_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int queue) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + unsigned int cnt = 0; + int curr_bit = 0; + unsigned int desc = 0; + int pool_id = 0; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + fpriv = fmac_dev_ctx->fpriv; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fpriv); + + desc = def_priv->num_tx_tokens; + + /* First search for a reserved desc */ + + for (cnt = 0; cnt < def_priv->num_tx_tokens_per_ac; cnt++) { + curr_bit = ((queue + (NRF_WIFI_FMAC_AC_MAX * cnt))); + curr_bit = ((queue + (NRF_WIFI_FMAC_AC_MAX * cnt)) % TX_DESC_BUCKET_BOUND); + pool_id = ((queue + (NRF_WIFI_FMAC_AC_MAX * cnt)) / TX_DESC_BUCKET_BOUND); + + if ((((def_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] >> + curr_bit)) & 1)) { + continue; + } else { + def_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] |= + (1 << curr_bit); + desc = queue + (NRF_WIFI_FMAC_AC_MAX * cnt); + def_dev_ctx->tx_config.outstanding_descs[queue]++; + break; + } + } + + /* If reserved desc is not found search for a spare desc + * (only for non beacon queues) + */ + if (cnt == def_priv->num_tx_tokens_per_ac) { + for (desc = def_priv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX; + desc < def_priv->num_tx_tokens; + desc++) { + curr_bit = (desc % TX_DESC_BUCKET_BOUND); + pool_id = (desc / TX_DESC_BUCKET_BOUND); + + if ((def_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] >> curr_bit) & 1) { + continue; + } else { + def_dev_ctx->tx_config.buf_pool_bmp_p[pool_id] |= + (1 << curr_bit); + def_dev_ctx->tx_config.outstanding_descs[queue]++; + /* Keep a note which queue has been assigned the + * spare desc. Need for processing of TX_DONE + * event as queue number is not being provided + * by UMAC. + * First nibble epresent first spare desc + * (B3B2B1B0: VO-VI-BE-BK) + * Second nibble represent second spare desc + * (B7B6B5B4 : V0-VI-BE-BK) + * Third nibble represent second spare desc + * (B11B10B9B8 : V0-VI-BE-BK) + * Fourth nibble represent second spare desc + * (B15B14B13B12 : V0-VI-BE-BK) + */ + set_spare_desc_q_map(fmac_dev_ctx, desc, queue); + break; + } + } + } + + + return desc; +} + + +int tx_aggr_check(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *first_nwb, + int ac, + int peer) +{ + void *nwb = NULL; + void *pending_pkt_queue = NULL; + bool aggr = true; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (def_dev_ctx->tx_config.peers[peer].is_legacy) { + return false; + } + + pending_pkt_queue = def_dev_ctx->tx_config.data_pending_txq[peer][ac]; + + if (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pending_pkt_queue) == 0) { + return false; + } + + nwb = nrf_wifi_utils_q_peek(fmac_dev_ctx->fpriv->opriv, + pending_pkt_queue); + + if (nwb) { + if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_util_get_dest(fmac_dev_ctx, + nwb), + nrf_wifi_util_get_dest(fmac_dev_ctx, + first_nwb))) { + aggr = false; + } + + if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_util_get_src(fmac_dev_ctx, + nwb), + nrf_wifi_util_get_src(fmac_dev_ctx, + first_nwb))) { + aggr = false; + } + } + + + return aggr; +} + + +int get_peer_from_wakeup_q(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int ac) +{ + int peer_id = -1; + struct peers_info *peer = NULL; + void *pend_q = NULL; + unsigned int pend_q_len; + void *client_q = NULL; + void *list_node = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + client_q = def_dev_ctx->tx_config.wakeup_client_q; + + list_node = nrf_wifi_osal_llist_get_node_head(fmac_dev_ctx->fpriv->opriv, + client_q); + + while (list_node) { + peer = nrf_wifi_osal_llist_node_data_get(fmac_dev_ctx->fpriv->opriv, + list_node); + + if (peer != NULL && peer->ps_token_count) { + + pend_q = def_dev_ctx->tx_config.data_pending_txq[peer->peer_id][ac]; + pend_q_len = nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, pend_q); + + if (pend_q_len) { + peer->ps_token_count--; + return peer->peer_id; + } + } + + list_node = nrf_wifi_osal_llist_get_node_nxt(fmac_dev_ctx->fpriv->opriv, + client_q, + list_node); + } + + return peer_id; +} + + +int tx_curr_peer_opp_get(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int ac) +{ + unsigned int i = 0; + unsigned int curr_peer_opp = 0; + unsigned int init_peer_opp = 0; + unsigned int pend_q_len; + void *pend_q = NULL; + int peer_id = -1; + unsigned char ps_state = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (ac == NRF_WIFI_FMAC_AC_MC) { + return MAX_PEERS; + } + + peer_id = get_peer_from_wakeup_q(fmac_dev_ctx, ac); + + if (peer_id != -1) { + return peer_id; + } + + init_peer_opp = def_dev_ctx->tx_config.curr_peer_opp[ac]; + + for (i = 0; i < MAX_PEERS; i++) { + curr_peer_opp = (init_peer_opp + i) % MAX_PEERS; + + ps_state = def_dev_ctx->tx_config.peers[curr_peer_opp].ps_state; + + if (ps_state == NRF_WIFI_CLIENT_PS_MODE) { + continue; + } + + pend_q = def_dev_ctx->tx_config.data_pending_txq[curr_peer_opp][ac]; + pend_q_len = nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pend_q); + + if (pend_q_len) { + def_dev_ctx->tx_config.curr_peer_opp[ac] = + (curr_peer_opp + 1) % MAX_PEERS; + break; + } + } + + if (i != MAX_PEERS) { + peer_id = curr_peer_opp; + } + + return peer_id; +} + +size_t _tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc, + unsigned int ac) +{ + int len = 0; + void *pend_pkt_q = NULL; + void *txq = NULL; + struct tx_pkt_info *pkt_info = NULL; + int peer_id = -1; + void *nwb = NULL; + void *first_nwb = NULL; + + int max_txq_len, avail_ampdu_len_per_token; + int ampdu_len = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + max_txq_len = def_priv->data_config.max_tx_aggregation; + avail_ampdu_len_per_token = def_priv->avail_ampdu_len_per_token; + + peer_id = tx_curr_peer_opp_get(fmac_dev_ctx, ac); + + /* No pending frames for any peer in that AC. */ + if (peer_id == -1) { + return 0; + } + + pend_pkt_q = def_dev_ctx->tx_config.data_pending_txq[peer_id][ac]; + + if (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q) == 0) { + return 0; + } + + pkt_info = &def_dev_ctx->tx_config.pkt_info_p[desc]; + txq = pkt_info->pkt; + + /* Aggregate Only MPDU's with same RA, same Rate, + * same Rate flags, same Tx Info flags + */ + if (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q)) { + first_nwb = nrf_wifi_utils_q_peek(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q); + } + + while (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q)) { + nwb = nrf_wifi_utils_q_peek(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q); + + ampdu_len += TX_BUF_HEADROOM + + nrf_wifi_osal_nbuf_data_size(fmac_dev_ctx->fpriv->opriv, + (void *)nwb); + + if (ampdu_len >= avail_ampdu_len_per_token) { + break; + } + + if (!can_xmit(fmac_dev_ctx, nwb) || + (!tx_aggr_check(fmac_dev_ctx, first_nwb, ac, peer_id)) || + (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + txq) >= max_txq_len)) { + break; + } + + nwb = nrf_wifi_utils_q_dequeue(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q); + + nrf_wifi_utils_list_add_tail(fmac_dev_ctx->fpriv->opriv, + txq, + nwb); + } + + /* If our criterion rejects all pending frames, or + * pend_q is empty, send only 1 + */ + if (!nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, txq)) { + nwb = nrf_wifi_utils_q_dequeue(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q); + + if (!can_xmit(fmac_dev_ctx, nwb)) { + return 0; + } + + nrf_wifi_utils_list_add_tail(fmac_dev_ctx->fpriv->opriv, + txq, + nwb); + } + + len = nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, txq); + + if (len > 0) { + def_dev_ctx->tx_config.pkt_info_p[desc].peer_id = peer_id; + } + + update_pend_q_bmp(fmac_dev_ctx, ac, peer_id); + + return len; +} + + +enum nrf_wifi_status tx_cmd_prep_callbk_fn(void *callbk_data, + void *nbuf) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_buf_map_info *tx_buf_info = NULL; + unsigned long nwb = 0; + unsigned long nwb_data = 0; + unsigned long phy_addr = 0; + struct tx_cmd_prep_info *info = NULL; + struct nrf_wifi_tx_buff *config = NULL; + unsigned int desc_id = 0; + unsigned int buf_len = 0; + unsigned char frame_indx = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + info = (struct tx_cmd_prep_info *)callbk_data; + fmac_dev_ctx = info->fmac_dev_ctx; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + config = info->config; + frame_indx = config->num_tx_pkts; + + nwb = (unsigned long)nbuf; + + desc_id = (config->tx_desc_num * + def_priv->data_config.max_tx_aggregation) + frame_indx; + + tx_buf_info = &def_dev_ctx->tx_buf_info[desc_id]; + + if (tx_buf_info->mapped) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Init_TX cmd called for already mapped TX buffer(%d)\n", + __func__, + desc_id); + + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nwb_data = (unsigned long)nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + (void *)nwb); + + buf_len = nrf_wifi_osal_nbuf_data_size(fmac_dev_ctx->fpriv->opriv, + (void *)nwb); + + phy_addr = nrf_wifi_hal_buf_map_tx(fmac_dev_ctx->hal_dev_ctx, + nwb_data, + buf_len, + desc_id, + config->tx_desc_num, + frame_indx); + + if (!phy_addr) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_buf_map_tx failed\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + tx_buf_info->nwb = nwb; + tx_buf_info->mapped = true; + + config->tx_buff_info[frame_indx].ddr_ptr = + (unsigned long long)phy_addr; + + config->tx_buff_info[frame_indx].pkt_length = buf_len; + config->num_tx_pkts++; + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +enum nrf_wifi_status tx_cmd_prepare(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct host_rpu_msg *umac_cmd, + int desc, + void *txq, + int peer_id) +{ + struct nrf_wifi_tx_buff *config = NULL; + int len = 0; + void *nwb = NULL; + void *nwb_data = NULL; + unsigned int txq_len = 0; + unsigned char *data = NULL; + struct tx_cmd_prep_info info; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + unsigned char vif_id; + struct nrf_wifi_fmac_vif_ctx *vif_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + vif_id = def_dev_ctx->tx_config.peers[peer_id].if_idx; + vif_ctx = def_dev_ctx->vif_ctx[vif_id]; + + txq_len = nrf_wifi_utils_list_len(fmac_dev_ctx->fpriv->opriv, + txq); + + if (txq_len == 0) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: txq_len = %d\n", + __func__, + txq_len); + goto err; + } + + nwb = nrf_wifi_utils_list_peek(fmac_dev_ctx->fpriv->opriv, + txq); + + def_dev_ctx->tx_config.send_pkt_coalesce_count_p[desc] = txq_len; + + config = (struct nrf_wifi_tx_buff *)(umac_cmd->msg); + + data = nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb); + + len = nrf_wifi_osal_nbuf_data_size(fmac_dev_ctx->fpriv->opriv, + nwb); + + config->umac_head.cmd = NRF_WIFI_CMD_TX_BUFF; + + config->umac_head.len += sizeof(struct nrf_wifi_tx_buff); + config->umac_head.len += sizeof(struct nrf_wifi_tx_buff_info) * txq_len; + + config->tx_desc_num = desc; + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + config->mac_hdr_info.dest, + nrf_wifi_util_get_dest(fmac_dev_ctx, nwb), + NRF_WIFI_ETH_ADDR_LEN); + + nrf_wifi_osal_mem_cpy(fmac_dev_ctx->fpriv->opriv, + config->mac_hdr_info.src, + nrf_wifi_util_get_src(fmac_dev_ctx, nwb), + NRF_WIFI_ETH_ADDR_LEN); + + nwb_data = nrf_wifi_osal_nbuf_data_get(fmac_dev_ctx->fpriv->opriv, + nwb); + config->mac_hdr_info.etype = + nrf_wifi_util_tx_get_eth_type(fmac_dev_ctx, + nwb_data); + + config->mac_hdr_info.dscp_or_tos = + nrf_wifi_util_get_tid(fmac_dev_ctx, nwb); + + if (is_twt_emergency_pkt(fmac_dev_ctx->fpriv->opriv, nwb)) { + config->mac_hdr_info.dscp_or_tos |= DSCP_OR_TOS_TWT_EMERGENCY_TX; + } + + config->num_tx_pkts = 0; + + info.fmac_dev_ctx = fmac_dev_ctx; + info.config = config; + + status = nrf_wifi_utils_list_traverse(fmac_dev_ctx->fpriv->opriv, + txq, + &info, + tx_cmd_prep_callbk_fn); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: build_mac80211_hdr failed\n", + __func__); + goto err; + } + + def_dev_ctx->host_stats.total_tx_pkts += config->num_tx_pkts; + config->wdev_id = def_dev_ctx->tx_config.peers[peer_id].if_idx; + + if ((vif_ctx->if_type == NRF_WIFI_IFTYPE_AP || + vif_ctx->if_type == NRF_WIFI_IFTYPE_AP_VLAN || + vif_ctx->if_type == NRF_WIFI_IFTYPE_MESH_POINT) && + pending_frames_count(fmac_dev_ctx, peer_id) != 0) { + config->mac_hdr_info.more_data = 1; + } + + if (def_dev_ctx->tx_config.peers[peer_id].ps_token_count == 0) { + nrf_wifi_utils_list_del_node(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.wakeup_client_q, + &def_dev_ctx->tx_config.peers[peer_id]); + + config->mac_hdr_info.eosp = 1; + + } else { + config->mac_hdr_info.eosp = 0; + } + + return NRF_WIFI_STATUS_SUCCESS; +err: + return NRF_WIFI_STATUS_FAIL; +} + + +enum nrf_wifi_status tx_cmd_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *txq, + int desc, + int peer_id) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_msg *umac_cmd = NULL; + unsigned int len = 0; + + len += sizeof(struct nrf_wifi_tx_buff_info); + len *= nrf_wifi_utils_list_len(fmac_dev_ctx->fpriv->opriv, txq); + + len += sizeof(struct nrf_wifi_tx_buff); + + umac_cmd = umac_cmd_alloc(fmac_dev_ctx, + NRF_WIFI_HOST_RPU_MSG_TYPE_DATA, + len); + + status = tx_cmd_prepare(fmac_dev_ctx, + umac_cmd, + desc, + txq, + peer_id); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: tx_cmd_prepare failed\n", + __func__); + + goto out; + } + + status = nrf_wifi_hal_data_cmd_send(fmac_dev_ctx->hal_dev_ctx, + NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX, + umac_cmd, + sizeof(*umac_cmd) + len, + desc, + 0); + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + umac_cmd); +out: + return status; +} + + +enum nrf_wifi_status tx_pending_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int desc, + unsigned int ac) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!fmac_dev_ctx) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid params\n", + __func__); + goto out; + } + + if (_tx_pending_process(fmac_dev_ctx, desc, ac)) { + status = tx_cmd_init(fmac_dev_ctx, + def_dev_ctx->tx_config.pkt_info_p[desc].pkt, + desc, + def_dev_ctx->tx_config.pkt_info_p[desc].peer_id); + } else { + tx_desc_free(fmac_dev_ctx, + desc, + ac); + + status = NRF_WIFI_STATUS_SUCCESS; + } + +out: + return status; +} + + +enum nrf_wifi_status tx_enqueue(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + void *nwb, + unsigned int ac, + unsigned int peer_id) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + void *queue = NULL; + int qlen = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!fmac_dev_ctx || !nwb) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid params\n", + __func__); + goto out; + } + + queue = def_dev_ctx->tx_config.data_pending_txq[peer_id][ac]; + + qlen = nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, queue); + + if (qlen >= CONFIG_NRF700X_MAX_TX_PENDING_QLEN) { + goto out; + } + + if (is_twt_emergency_pkt(fmac_dev_ctx->fpriv->opriv, nwb)) { + nrf_wifi_utils_q_enqueue_head(fmac_dev_ctx->fpriv->opriv, + queue, + nwb); + } else { + nrf_wifi_utils_q_enqueue(fmac_dev_ctx->fpriv->opriv, + queue, + nwb); + } + + status = update_pend_q_bmp(fmac_dev_ctx, ac, peer_id); + +out: + return status; +} + + +enum nrf_wifi_fmac_tx_status tx_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned char if_idx, + void *nbuf, + unsigned int ac, + unsigned int peer_id) +{ + enum nrf_wifi_fmac_tx_status status; + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + void *pend_pkt_q = NULL; + void *first_nwb = NULL; + unsigned char ps_state = 0; + bool aggr_status = false; + int max_cmds = 0; + + fpriv = fmac_dev_ctx->fpriv; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fpriv); + + status = tx_enqueue(fmac_dev_ctx, + nbuf, + ac, + peer_id); + + if (status != NRF_WIFI_FMAC_TX_STATUS_SUCCESS) { + goto err; + } + + ps_state = def_dev_ctx->tx_config.peers[peer_id].ps_state; + + if (ps_state == NRF_WIFI_CLIENT_PS_MODE) { + goto out; + } + + pend_pkt_q = def_dev_ctx->tx_config.data_pending_txq[peer_id][ac]; + + /* If outstanding_descs for a particular + * access category >= NUM_TX_DESCS_PER_AC means there are already + * pending packets for that access category. So now see if frames + * can be aggregated depending upon access category depending + * upon SA, RA & AC + */ + + if ((def_dev_ctx->tx_config.outstanding_descs[ac]) >= def_priv->num_tx_tokens_per_ac) { + if (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q)) { + first_nwb = nrf_wifi_utils_q_peek(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q); + + aggr_status = true; + + if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_util_get_dest(fmac_dev_ctx, + nbuf), + nrf_wifi_util_get_dest(fmac_dev_ctx, + first_nwb))) { + aggr_status = false; + } + + if (!nrf_wifi_util_ether_addr_equal(nrf_wifi_util_get_src(fmac_dev_ctx, + nbuf), + nrf_wifi_util_get_src(fmac_dev_ctx, + first_nwb))) { + aggr_status = false; + } + } + + if (aggr_status) { + max_cmds = def_priv->data_config.max_tx_aggregation; + + if (nrf_wifi_utils_q_len(fmac_dev_ctx->fpriv->opriv, + pend_pkt_q) < max_cmds) { + goto out; + } + } + } + return NRF_WIFI_FMAC_TX_STATUS_SUCCESS; +out: + return NRF_WIFI_FMAC_TX_STATUS_QUEUED; +err: + return NRF_WIFI_FMAC_TX_STATUS_FAIL; +} + + +unsigned int tx_buff_req_free(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + unsigned int tx_desc_num, + unsigned char *ac) +{ + unsigned int pkts_pend = 0; + unsigned int desc = tx_desc_num; + int tx_done_q = 0, start_ac, end_ac, cnt = 0; + unsigned short tx_done_spare_desc_q_map = 0; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + /* Determine the Queue from the descriptor */ + /* Reserved desc */ + if (desc < (def_priv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX)) { + tx_done_q = (desc % NRF_WIFI_FMAC_AC_MAX); + start_ac = end_ac = tx_done_q; + } else { + /* Derive the queue here as it is not given by UMAC. */ + if (desc >= (def_priv->num_tx_tokens_per_ac * NRF_WIFI_FMAC_AC_MAX)) { + tx_done_spare_desc_q_map = get_spare_desc_q_map(fmac_dev_ctx, desc); + + if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_BK)) + tx_done_q = NRF_WIFI_FMAC_AC_BK; + else if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_BE)) + tx_done_q = NRF_WIFI_FMAC_AC_BE; + else if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_VI)) + tx_done_q = NRF_WIFI_FMAC_AC_VI; + else if (tx_done_spare_desc_q_map & (1 << NRF_WIFI_FMAC_AC_VO)) + tx_done_q = NRF_WIFI_FMAC_AC_VO; + } + + /* Spare desc: + * Loop through all AC's + */ + start_ac = NRF_WIFI_FMAC_AC_VO; + end_ac = NRF_WIFI_FMAC_AC_BK; + } + + for (cnt = start_ac; cnt >= end_ac; cnt--) { + pkts_pend = _tx_pending_process(fmac_dev_ctx, desc, cnt); + + if (pkts_pend) { + *ac = (unsigned char)cnt; + + /* Spare Token Case*/ + if (tx_done_q != *ac) { + /* Adjust the counters */ + def_dev_ctx->tx_config.outstanding_descs[tx_done_q]--; + def_dev_ctx->tx_config.outstanding_descs[*ac]++; + + /* Update the queue_map */ + /* Clear the last access category. */ + clear_spare_desc_q_map(fmac_dev_ctx, desc, tx_done_q); + /* Set the new access category. */ + set_spare_desc_q_map(fmac_dev_ctx, desc, *ac); + } + break; + } + } + + if (!pkts_pend) { + /* Mark the desc as available */ + tx_desc_free(fmac_dev_ctx, + desc, + tx_done_q); + } + + return pkts_pend; +} + + +enum nrf_wifi_status tx_done_process(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_tx_buff_done *config) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_priv *fpriv = NULL; + void *nwb = NULL; + void *nwb_list = NULL; + unsigned int desc = 0; + unsigned int frame = 0; + unsigned int desc_id = 0; + unsigned long virt_addr = 0; + struct nrf_wifi_fmac_buf_map_info *tx_buf_info = NULL; + struct tx_pkt_info *pkt_info = NULL; + unsigned int pkt = 0; + unsigned int pkts_pending = 0; + unsigned char queue = 0; + void *txq = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + fpriv = fmac_dev_ctx->fpriv; + + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fmac_dev_ctx->fpriv); + + desc = config->tx_desc_num; + + if (desc > def_priv->num_tx_tokens) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "Invalid desc\n"); + goto out; + } + + pkt_info = &def_dev_ctx->tx_config.pkt_info_p[desc]; + nwb_list = pkt_info->pkt; + + for (frame = 0; + frame < def_dev_ctx->tx_config.send_pkt_coalesce_count_p[desc]; + frame++) { + desc_id = (desc * def_priv->data_config.max_tx_aggregation) + frame; + + tx_buf_info = &def_dev_ctx->tx_buf_info[desc_id]; + + if (!tx_buf_info->mapped) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Deinit_TX cmd called for unmapped TX buf(%d)\n", + __func__, + desc_id); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + virt_addr = nrf_wifi_hal_buf_unmap_tx(fmac_dev_ctx->hal_dev_ctx, + desc_id); + + if (!virt_addr) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: nrf_wifi_hal_buf_unmap_tx failed\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + /* TODO: See why we can't free the nwb here itself instead of + * later as is being done now + */ + tx_buf_info->nwb = 0; + tx_buf_info->mapped = false; + } + + pkt = 0; + + while (nrf_wifi_utils_q_len(fpriv->opriv, + nwb_list)) { + nwb = nrf_wifi_utils_q_dequeue(fpriv->opriv, + nwb_list); + + if (!nwb) { + continue; + } + + nrf_wifi_osal_nbuf_free(fmac_dev_ctx->fpriv->opriv, + nwb); + pkt++; + } + + def_dev_ctx->host_stats.total_tx_done_pkts += pkt; + + pkts_pending = tx_buff_req_free(fmac_dev_ctx, config->tx_desc_num, &queue); + + if (pkts_pending) { + if (def_dev_ctx->twt_sleep_status == + NRF_WIFI_FMAC_TWT_STATE_AWAKE) { + + pkt_info = &def_dev_ctx->tx_config.pkt_info_p[desc]; + + txq = pkt_info->pkt; + + status = tx_cmd_init(fmac_dev_ctx, + txq, + desc, + pkt_info->peer_id); + } else { + status = NRF_WIFI_STATUS_SUCCESS; + } + + } else { + status = NRF_WIFI_STATUS_SUCCESS; + } +out: + return status; +} + +#ifdef CONFIG_NRF700X_TX_DONE_WQ_ENABLED +static void tx_done_tasklet_fn(unsigned long data) +{ + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = (struct nrf_wifi_fmac_dev_ctx *)data; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + void *tx_done_tasklet_event_q = (void *)def_dev_ctx->tx_config.tx_done_tasklet_event_q; + + struct nrf_wifi_tx_buff_done *config = nrf_wifi_utils_q_dequeue( + fmac_dev_ctx->fpriv->opriv, + tx_done_tasklet_event_q); + + if (!config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: TX done event Q is empty\n", + __func__); + return; + } + + (void) nrf_wifi_fmac_tx_done_event_process(fmac_dev_ctx, config); + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + config); +} +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ + +enum nrf_wifi_status (nrf_wifi_fmac_tx_done_event_process)( + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + struct nrf_wifi_tx_buff_done *config) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (!fmac_dev_ctx) { + goto out; + } + + if (!config) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Invalid parameters\n", + __func__); + + goto out; + } + + nrf_wifi_osal_spinlock_take(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + status = tx_done_process(fmac_dev_ctx, + config); + + nrf_wifi_osal_spinlock_rel(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + +out: + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Failed\n", + __func__); + } + + return status; +} + + +enum nrf_wifi_fmac_tx_status nrf_wifi_fmac_tx(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx, + int if_id, + void *nbuf, + unsigned int ac, + unsigned int peer_id) +{ + enum nrf_wifi_fmac_tx_status status = NRF_WIFI_FMAC_TX_STATUS_FAIL; + unsigned int desc = 0; + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + + fpriv = fmac_dev_ctx->fpriv; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fpriv); + + nrf_wifi_osal_spinlock_take(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + + if (def_priv->num_tx_tokens == 0) { + goto out; + } + + status = tx_process(fmac_dev_ctx, + if_id, + nbuf, + ac, + peer_id); + + if (status != NRF_WIFI_FMAC_TX_STATUS_SUCCESS) { + goto out; + } + + status = NRF_WIFI_FMAC_TX_STATUS_QUEUED; + + if (!can_xmit(fmac_dev_ctx, nbuf)) { + goto out; + } + + desc = tx_desc_get(fmac_dev_ctx, ac); + + if (desc == def_priv->num_tx_tokens) { + goto out; + } + + status = tx_pending_process(fmac_dev_ctx, + desc, + ac); +out: + nrf_wifi_osal_spinlock_rel(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + return status; +} + + +enum nrf_wifi_status tx_init(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + void *q_ptr = NULL; + unsigned int i = 0; + unsigned int j = 0; + + if (!fmac_dev_ctx) { + goto out; + } + + fpriv = fmac_dev_ctx->fpriv; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + def_priv = wifi_fmac_priv(fpriv); + + def_dev_ctx->tx_config.send_pkt_coalesce_count_p = + nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + (sizeof(unsigned int) * + def_priv->num_tx_tokens)); + + if (!def_dev_ctx->tx_config.send_pkt_coalesce_count_p) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate send_pkt_coalesce_count_p\n", + __func__); + goto out; + } + + for (i = 0; i < NRF_WIFI_FMAC_AC_MAX; i++) { + for (j = 0; j < MAX_SW_PEERS; j++) { + def_dev_ctx->tx_config.data_pending_txq[j][i] = + nrf_wifi_utils_q_alloc(fpriv->opriv); + + if (!def_dev_ctx->tx_config.data_pending_txq[j][i]) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate data_pending_txq\n", + __func__); + goto coal_q_free; + } + } + + def_dev_ctx->tx_config.outstanding_descs[i] = 0; + } + + /* Used to store the address of tx'ed skb and len of 802.11 hdr + * it will be used in tx complete. + */ + def_dev_ctx->tx_config.pkt_info_p = nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + (sizeof(struct tx_pkt_info) * + def_priv->num_tx_tokens)); + + if (!def_dev_ctx->tx_config.pkt_info_p) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate pkt_info_p\n", + __func__); + goto tx_q_free; + } + + for (i = 0; i < def_priv->num_tx_tokens; i++) { + def_dev_ctx->tx_config.pkt_info_p[i].pkt = nrf_wifi_utils_list_alloc(fpriv->opriv); + + if (!def_dev_ctx->tx_config.pkt_info_p[i].pkt) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate pkt list\n", + __func__); + goto tx_q_setup_free; + } + } + + for (j = 0; j < NRF_WIFI_FMAC_AC_MAX; j++) { + def_dev_ctx->tx_config.curr_peer_opp[j] = 0; + } + + def_dev_ctx->tx_config.buf_pool_bmp_p = + nrf_wifi_osal_mem_zalloc(fmac_dev_ctx->fpriv->opriv, + (sizeof(unsigned long) * + (def_priv->num_tx_tokens/TX_DESC_BUCKET_BOUND) + 1)); + + if (!def_dev_ctx->tx_config.buf_pool_bmp_p) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate buf_pool_bmp_p\n", + __func__); + goto tx_pkt_info_free; + } + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.buf_pool_bmp_p, + 0, + sizeof(long)*((def_priv->num_tx_tokens/TX_DESC_BUCKET_BOUND) + 1)); + + for (i = 0; i < MAX_PEERS; i++) { + def_dev_ctx->tx_config.peers[i].peer_id = -1; + } + + def_dev_ctx->tx_config.tx_lock = nrf_wifi_osal_spinlock_alloc(fmac_dev_ctx->fpriv->opriv); + + if (!def_dev_ctx->tx_config.tx_lock) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate TX lock\n", + __func__); + goto tx_buff_map_free; + } + + nrf_wifi_osal_spinlock_init(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + def_dev_ctx->tx_config.wakeup_client_q = nrf_wifi_utils_q_alloc(fpriv->opriv); + + if (!def_dev_ctx->tx_config.wakeup_client_q) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate Wakeup Client List\n", + __func__); + goto tx_spin_lock_free; + } + + def_dev_ctx->twt_sleep_status = NRF_WIFI_FMAC_TWT_STATE_AWAKE; + +#ifdef CONFIG_NRF700X_TX_DONE_WQ_ENABLED + def_dev_ctx->tx_done_tasklet = nrf_wifi_osal_tasklet_alloc(fpriv->opriv, + NRF_WIFI_TASKLET_TYPE_TX_DONE); + if (!def_dev_ctx->tx_done_tasklet) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate tx_done_tasklet\n", + __func__); + goto wakeup_client_q_free; + } + def_dev_ctx->tx_config.tx_done_tasklet_event_q = nrf_wifi_utils_q_alloc(fpriv->opriv); + if (!def_dev_ctx->tx_config.tx_done_tasklet_event_q) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Unable to allocate tx_done_tasklet_event_q\n", + __func__); + goto tx_done_tasklet_free; + } + + nrf_wifi_osal_tasklet_init(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_done_tasklet, + tx_done_tasklet_fn, + (unsigned long)fmac_dev_ctx); +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ + return NRF_WIFI_STATUS_SUCCESS; +#ifdef CONFIG_NRF700X_TX_DONE_WQ_ENABLED +tx_done_tasklet_free: + nrf_wifi_osal_tasklet_free(fpriv->opriv, + def_dev_ctx->tx_done_tasklet); +wakeup_client_q_free: + nrf_wifi_utils_q_free(fpriv->opriv, def_dev_ctx->tx_config.wakeup_client_q); +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ +tx_spin_lock_free: + nrf_wifi_osal_spinlock_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); +tx_buff_map_free: + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.buf_pool_bmp_p); +tx_pkt_info_free: + for (i = 0; i < def_priv->num_tx_tokens; i++) { + nrf_wifi_utils_list_free(fpriv->opriv, + def_dev_ctx->tx_config.pkt_info_p[i].pkt); + } +tx_q_setup_free: + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.pkt_info_p); +tx_q_free: + for (i = 0; i < NRF_WIFI_FMAC_AC_MAX; i++) { + for (j = 0; j < MAX_SW_PEERS; j++) { + q_ptr = def_dev_ctx->tx_config.data_pending_txq[j][i]; + + nrf_wifi_utils_q_free(fpriv->opriv, + q_ptr); + } + } +coal_q_free: + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.send_pkt_coalesce_count_p); +out: + return NRF_WIFI_STATUS_FAIL; +} + + +void tx_deinit(struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx) +{ + struct nrf_wifi_fmac_priv *fpriv = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + struct nrf_wifi_fmac_priv_def *def_priv = NULL; + unsigned int i = 0; + unsigned int j = 0; + + fpriv = fmac_dev_ctx->fpriv; + + def_priv = wifi_fmac_priv(fpriv); + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + +#ifdef CONFIG_NRF700X_TX_DONE_WQ_ENABLED + /* TODO: Need to deinit network buffers? */ + nrf_wifi_osal_tasklet_free(fpriv->opriv, + def_dev_ctx->tx_done_tasklet); + nrf_wifi_utils_q_free(fpriv->opriv, + def_dev_ctx->tx_config.tx_done_tasklet_event_q); +#endif /* CONFIG_NRF700X_TX_DONE_WQ_ENABLED */ + nrf_wifi_utils_q_free(fpriv->opriv, + def_dev_ctx->tx_config.wakeup_client_q); + + nrf_wifi_osal_spinlock_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.tx_lock); + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.buf_pool_bmp_p); + + for (i = 0; i < def_priv->num_tx_tokens; i++) { + if (def_dev_ctx->tx_config.pkt_info_p) { + nrf_wifi_utils_list_free(fpriv->opriv, + def_dev_ctx->tx_config.pkt_info_p[i].pkt); + } + } + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.pkt_info_p); + + for (i = 0; i < NRF_WIFI_FMAC_AC_MAX; i++) { + for (j = 0; j < MAX_SW_PEERS; j++) { + nrf_wifi_utils_q_free(fpriv->opriv, + def_dev_ctx->tx_config.data_pending_txq[j][i]); + } + } + + nrf_wifi_osal_mem_free(fmac_dev_ctx->fpriv->opriv, + def_dev_ctx->tx_config.send_pkt_coalesce_count_p); + + nrf_wifi_osal_mem_set(fmac_dev_ctx->fpriv->opriv, + &def_dev_ctx->tx_config, + 0, + sizeof(struct tx_config)); +} + + +static int map_ac_from_tid(int tid) +{ + const int map_1d_to_ac[8] = { + NRF_WIFI_FMAC_AC_BE, /*UP 0, 802.1D(BE), AC(BE) */ + NRF_WIFI_FMAC_AC_BK, /*UP 1, 802.1D(BK), AC(BK) */ + NRF_WIFI_FMAC_AC_BK, /*UP 2, 802.1D(BK), AC(BK) */ + NRF_WIFI_FMAC_AC_BE, /*UP 3, 802.1D(EE), AC(BE) */ + NRF_WIFI_FMAC_AC_VI, /*UP 4, 802.1D(CL), AC(VI) */ + NRF_WIFI_FMAC_AC_VI, /*UP 5, 802.1D(VI), AC(VI) */ + NRF_WIFI_FMAC_AC_VO, /*UP 6, 802.1D(VO), AC(VO) */ + NRF_WIFI_FMAC_AC_VO /*UP 7, 802.1D(NC), AC(VO) */ + }; + + return map_1d_to_ac[tid & 7]; +} + + +static int get_ac(unsigned int tid, + unsigned char *ra) +{ + if (nrf_wifi_util_is_multicast_addr(ra)) { + return NRF_WIFI_FMAC_AC_MC; + } + + return map_ac_from_tid(tid); +} + + +enum nrf_wifi_status nrf_wifi_fmac_start_xmit(void *dev_ctx, + unsigned char if_idx, + void *nbuf) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + enum nrf_wifi_fmac_tx_status tx_status = NRF_WIFI_FMAC_TX_STATUS_FAIL; + struct nrf_wifi_fmac_dev_ctx *fmac_dev_ctx = NULL; + struct nrf_wifi_fmac_dev_ctx_def *def_dev_ctx = NULL; + unsigned char *ra = NULL; + int tid = 0; + int ac = 0; + int peer_id = -1; + + if (!nbuf) { + goto out; + } + + fmac_dev_ctx = dev_ctx; + def_dev_ctx = wifi_dev_priv(fmac_dev_ctx); + + if (nrf_wifi_osal_nbuf_data_size(fmac_dev_ctx->fpriv->opriv, + nbuf) < NRF_WIFI_FMAC_ETH_HDR_LEN) { + goto out; + } + + ra = nrf_wifi_util_get_ra(def_dev_ctx->vif_ctx[if_idx], nbuf); + + peer_id = nrf_wifi_fmac_peer_get_id(fmac_dev_ctx, ra); + + if (peer_id == -1) { + nrf_wifi_osal_log_err(fmac_dev_ctx->fpriv->opriv, + "%s: Got packet for unknown PEER\n", + __func__); + + goto out; + } else if (peer_id == MAX_PEERS) { + ac = NRF_WIFI_FMAC_AC_MC; + } else { + if (def_dev_ctx->tx_config.peers[peer_id].qos_supported) { + tid = nrf_wifi_util_get_tid(fmac_dev_ctx, nbuf); + ac = get_ac(tid, ra); + } else { + ac = NRF_WIFI_FMAC_AC_BE; + } + } + + tx_status = nrf_wifi_fmac_tx(fmac_dev_ctx, + if_idx, + nbuf, + ac, + peer_id); + + if (tx_status == NRF_WIFI_FMAC_TX_STATUS_FAIL) { + nrf_wifi_osal_log_dbg(fmac_dev_ctx->fpriv->opriv, + "%s: Failed to send packet\n", + __func__); + goto out; + } + + return NRF_WIFI_STATUS_SUCCESS; +out: + if (nbuf) { + nrf_wifi_osal_nbuf_free(fmac_dev_ctx->fpriv->opriv, + nbuf); + } + return status; +} diff --git a/nrf_wifi/hw_if/hal/inc/fw/pack_def.h b/nrf_wifi/hw_if/hal/inc/fw/pack_def.h new file mode 100644 index 0000000000..389066a63c --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/fw/pack_def.h @@ -0,0 +1,16 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief phy init config parameters. These are passed to phy at init. + */ + +#ifndef __PACK_DEF__ +#define __PACK_DEF__ + +#define __NRF_WIFI_PKD __attribute__((__packed__)) + +#endif diff --git a/nrf_wifi/hw_if/hal/inc/fw/phy_rf_params.h b/nrf_wifi/hw_if/hal/inc/fw/phy_rf_params.h new file mode 100644 index 0000000000..1d1c3315c7 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/fw/phy_rf_params.h @@ -0,0 +1,301 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief PHY init config parameters. These are passed to phy at init. + */ + +#ifndef _PHY_RF_PARAMS_H_ +#define _PHY_RF_PARAMS_H_ +#include "pack_def.h" + +#define NRF_WIFI_RF_PARAMS_SIZE 200 +#define NRF_WIFI_RF_PARAMS_CONF_SIZE 42 + +#ifdef CONFIG_NRF700X_RADIO_TEST +#define NRF_WIFI_DEF_RF_PARAMS "0000000000002A0000000003030303544040383838383838000000003C00000000000000000000000000007077003F032424001000002800323500000C0008087D8105010071630300EED501001F6F00003B350100F52E0000E35E0000B7B6000066EFFEFFB5F60000896200007A840200E28FFCFF080808080408120100000000A1A10178000000080050003B020726181818181A120A140E0600" +#define MAX_TX_PWR_SYS_TEST 30 +#define MAX_TX_PWR_RADIO_TEST 24 +#else +#define NRF_WIFI_DEF_RF_PARAMS "0000000000002A0000000003030303544040383838383838000000003C00FC00F8FCFCFC00FC00000000007077003F032424001000002800323500000CF008087D8105010071630300EED501001F6F00003B350100F52E0000E35E0000B7B6000066EFFEFFB5F60000896200007A840200E28FFCFF080808080408120100000000A1A10178000000080050003B020726181818181A120A140E0600" +#endif + +#define NRF_WIFI_RF_PARAMS_OFF_RESV_1 0 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_X0 6 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_PDADJM7 7 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_PDADJM0 11 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR2G 15 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR2GM0M7 16 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM7 18 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_PWR5GM0 21 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_RXGNOFF 24 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_MAX_TEMP 28 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_MIN_TEMP 29 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_TXP_BOFF_2GH 30 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_TXP_BOFF_2GL 31 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_TXP_BOFF_5GH 32 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_TXP_BOFF_5GL 33 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_TXP_BOFF_V 34 +#define NRF_WIFI_RF_PARAMS_OFF_CALIB_RESV_2 37 + + +#define NRF_WIFI_PHY_CALIB_FLAG_RXDC 1 +#define NRF_WIFI_PHY_CALIB_FLAG_TXDC 2 +#define NRF_WIFI_PHY_CALIB_FLAG_TXPOW 0 +#define NRF_WIFI_PHY_CALIB_FLAG_TXIQ 8 +#define NRF_WIFI_PHY_CALIB_FLAG_RXIQ 16 +#define NRF_WIFI_PHY_CALIB_FLAG_DPD 32 + +#define NRF_WIFI_PHY_SCAN_CALIB_FLAG_RXDC (1<<16) +#define NRF_WIFI_PHY_SCAN_CALIB_FLAG_TXDC (2<<16) +#define NRF_WIFI_PHY_SCAN_CALIB_FLAG_TXPOW (0<<16) +#define NRF_WIFI_PHY_SCAN_CALIB_FLAG_TXIQ (0<<16) +#define NRF_WIFI_PHY_SCAN_CALIB_FLAG_RXIQ (0<<16) +#define NRF_WIFI_PHY_SCAN_CALIB_FLAG_DPD (0<<16) + +#define NRF_WIFI_DEF_PHY_CALIB (NRF_WIFI_PHY_CALIB_FLAG_RXDC |\ + NRF_WIFI_PHY_CALIB_FLAG_TXDC |\ + NRF_WIFI_PHY_CALIB_FLAG_RXIQ |\ + NRF_WIFI_PHY_CALIB_FLAG_TXIQ |\ + NRF_WIFI_PHY_CALIB_FLAG_TXPOW |\ + NRF_WIFI_PHY_CALIB_FLAG_DPD |\ + NRF_WIFI_PHY_SCAN_CALIB_FLAG_RXDC |\ + NRF_WIFI_PHY_SCAN_CALIB_FLAG_TXDC |\ + NRF_WIFI_PHY_SCAN_CALIB_FLAG_RXIQ |\ + NRF_WIFI_PHY_SCAN_CALIB_FLAG_TXIQ |\ + NRF_WIFI_PHY_SCAN_CALIB_FLAG_TXPOW |\ + NRF_WIFI_PHY_SCAN_CALIB_FLAG_DPD) + +/* Temperature based calibration params */ +#define NRF_WIFI_DEF_PHY_TEMP_CALIB (NRF_WIFI_PHY_CALIB_FLAG_RXDC |\ + NRF_WIFI_PHY_CALIB_FLAG_TXDC |\ + NRF_WIFI_PHY_CALIB_FLAG_RXIQ |\ + NRF_WIFI_PHY_CALIB_FLAG_TXIQ |\ + NRF_WIFI_PHY_CALIB_FLAG_TXPOW |\ + NRF_WIFI_PHY_CALIB_FLAG_DPD) + + +#define NRF_WIFI_TEMP_CALIB_PERIOD (1024 * 1024) /* micro seconds */ +#define NRF_WIFI_TEMP_CALIB_THRESHOLD (40) +#define NRF_WIFI_TEMP_CALIB_ENABLE 1 + +/* Battery voltage changes base calibrations and voltage thresholds */ +#define NRF_WIFI_DEF_PHY_VBAT_CALIB (NRF_WIFI_PHY_CALIB_FLAG_DPD) +#define NRF_WIFI_VBAT_VERYLOW (8) /* Corresponds to (2.5+8*0.07)=3.06V */ +#define NRF_WIFI_VBAT_LOW (12) /* Correspond to (2.5+12*0.07)=3.34V */ +#define NRF_WIFI_VBAT_HIGH (14) /* Correspond to (2.5+14*0.07)=3.48V */ + + + +#ifdef CONFIG_NRF700X_RADIO_TEST +enum nrf_wifi_rf_test { + NRF_WIFI_RF_TEST_RX_ADC_CAP, + NRF_WIFI_RF_TEST_RX_STAT_PKT_CAP, + NRF_WIFI_RF_TEST_RX_DYN_PKT_CAP, + NRF_WIFI_RF_TEST_TX_TONE, + NRF_WIFI_RF_TEST_DPD, + NRF_WIFI_RF_TEST_RF_RSSI, + NRF_WIFI_RF_TEST_SLEEP, + NRF_WIFI_RF_TEST_GET_TEMPERATURE, + NRF_WIFI_RF_TEST_XO_CALIB, + NRF_WIFI_RF_TEST_XO_TUNE, + NRF_WIFI_RF_TEST_MAX, +}; + +enum nrf_wifi_rf_test_event { + NRF_WIFI_RF_TEST_EVENT_RX_ADC_CAP, + NRF_WIFI_RF_TEST_EVENT_RX_STAT_PKT_CAP, + NRF_WIFI_RF_TEST_EVENT_RX_DYN_PKT_CAP, + NRF_WIFI_RF_TEST_EVENT_TX_TONE_START, + NRF_WIFI_RF_TEST_EVENT_DPD_ENABLE, + NRF_WIFI_RF_TEST_EVENT_RF_RSSI, + NRF_WIFI_RF_TEST_EVENT_SLEEP, + NRF_WIFI_RF_TEST_EVENT_TEMP_MEAS, + NRF_WIFI_RF_TEST_EVENT_XO_CALIB, + NRF_WIFI_RF_TEST_EVENT_MAX, +}; + + + +/* Holds the RX capture related info */ +struct nrf_wifi_rf_test_capture_params { + unsigned char test; + + /* Number of samples to be captured. */ + unsigned short int cap_len; + + /* LNA Gain to be configured. It is a 3 bit value. The mapping is, + * '0' = 24dB + * '1' = 18dB + * '2' = 12dB + * '3' = 0dB + * '4' = -12dB + */ + unsigned char lna_gain; + + /* Baseband Gain to be configured. It is a 5 bit value. + * It supports 64dB range.The increment happens lineraly 2dB/step + */ + unsigned char bb_gain; +} __NRF_WIFI_PKD; + + +/* Struct to hold the events from RF test SW. */ +struct nrf_wifi_rf_test_capture_meas { + unsigned char test; + + /* Mean of I samples. Format: Q.11 */ + signed short mean_I; + + /* Mean of Q samples. Format: Q.11 */ + signed short mean_Q; + + /* RMS of I samples */ + unsigned int rms_I; + + /* RMS of Q samples */ + unsigned int rms_Q; +} __NRF_WIFI_PKD; + + +/* Holds the transmit related info */ +struct nrf_wifi_rf_test_tx_params { + unsigned char test; + + /* Desired tone frequency in MHz in steps of 1 MHz from -10 MHz to +10 MHz.*/ + signed char tone_freq; + + /* Desired TX power in the range -16 dBm to +24 dBm. + * in steps of 2 dBm + */ + signed char tx_pow; + + /* Set 1 for staring tone transmission.*/ + unsigned char enabled; +} __NRF_WIFI_PKD; + +struct nrf_wifi_rf_test_dpd_params { + unsigned char test; + unsigned char enabled; + +} __NRF_WIFI_PKD; + +struct nrf_wifi_temperature_params { + unsigned char test; + + /** current measured temperature */ + signed int temperature; + + /** Temperature measurment status. + *0: Reading successful + *1: Reading failed + */ + unsigned int readTemperatureStatus; +} __NRF_WIFI_PKD; + + +struct nrf_wifi_rf_get_rf_rssi { + unsigned char test; + unsigned char lna_gain; + unsigned char bb_gain; + unsigned char agc_status_val; +} __NRF_WIFI_PKD; + + +struct nrf_wifi_rf_test_xo_calib { + unsigned char test; + + /* XO value in the range between 0 to 127 */ + unsigned char xo_val; + +} __NRF_WIFI_PKD; + + +struct nrf_wifi_rf_get_xo_value { + unsigned char test; + + /* Optimal XO value computed. */ + unsigned char xo_value; +} __NRF_WIFI_PKD; + +#endif /* CONFIG_NRF700X_RADIO_TEST */ + +/** + * @brief This structure defines the parameters used to control the max transmit (TX) power + * in both frequency bands for different data rates. + * + */ + +struct nrf_wifi_tx_pwr_ceil_params { + /** Maximum power permitted while transmitting DSSS rates in 2.4G band. + * Resolution is 0.25dBm. + */ + unsigned char max_pwr_2g_dsss; + /** Maximum power permitted while transmitting MCS0 rate in 2.4G band. + * Resolution is 0.25dBm. + */ + unsigned char max_pwr_2g_mcs0; + /** Maximum power permitted while transmitting MCS7 rate in 2.4G band. + * Resolution is 0.25dBm. + */ + unsigned char max_pwr_2g_mcs7; + /** Maximum power permitted while transmitting MCS0 rate in 5G lowband. + * Low band corresponds to ch: 36 to 64 Resolution is 0.25dBm. + */ + unsigned char max_pwr_5g_low_mcs0; + /** Maximum power permitted while transmitting MCS7 rate in 5G lowband. + * Low band corresponds to ch: 36 to 64, resolution is 0.25dBm. + */ + unsigned char max_pwr_5g_low_mcs7; + /** Maximum power permitted while transmitting MCS0 rate in 5G midband. + * Mid band corresponds to ch: 96 to 132, resolution is 0.25dBm. + */ + unsigned char max_pwr_5g_mid_mcs0; + /** Maximum power permitted while transmitting MCS7 rate in 5G midband. + * Mid band corresponds to ch: 96 to 132, resolution is 0.25dBm. + */ + unsigned char max_pwr_5g_mid_mcs7; + /** Maximum power permitted while transmitting MCS0 rate in 5G highband. + * High band corresponds to ch: 136 to 177, resolution is 0.25dBm. + */ + unsigned char max_pwr_5g_high_mcs0; + /** Maximum power permitted while transmitting MCS7 rate in 5G highband. + * High band corresponds to ch: 136 to 177, resolution is 0.25dBm. + */ + unsigned char max_pwr_5g_high_mcs7; + /** Flag to determine presence of overriding, default parameters present + * in RF parameters string. + */ + unsigned char rf_tx_pwr_ceil_params_override; +} __NRF_WIFI_PKD; + +/* FT Prog version info */ +enum ft_prog_ver { + FT_PROG_VER1 = 1, + FT_PROG_VER2 = 2, + FT_PROG_VER3 = 3 +}; + +/* FT Prog version dependent back off values + * from Max transmit power + */ +#define FT_PROG_VER1_2G_DSSS_TXCEIL_BKOFF 0 +#define FT_PROG_VER1_2G_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER1_5G_LOW_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER1_5G_MID_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER1_5G_HIGH_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER2_2G_DSSS_TXCEIL_BKOFF 0 +#define FT_PROG_VER2_2G_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER2_5G_LOW_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER2_5G_MID_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER2_5G_HIGH_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER3_2G_DSSS_TXCEIL_BKOFF 0 +#define FT_PROG_VER3_2G_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER3_5G_LOW_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER3_5G_MID_OFDM_TXCEIL_BKOFF 0 +#define FT_PROG_VER3_5G_HIGH_OFDM_TXCEIL_BKOFF 0 + +#endif diff --git a/nrf_wifi/hw_if/hal/inc/fw/rpu_if.h b/nrf_wifi/hw_if/hal/inc/fw/rpu_if.h new file mode 100644 index 0000000000..3b6cd9214d --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/fw/rpu_if.h @@ -0,0 +1,474 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Common structures and definations. + */ + +#ifndef __RPU_IF_H__ +#define __RPU_IF_H__ +#include "pack_def.h" + +#define RPU_ADDR_SPI_START 0x00000000 +#define RPU_ADDR_GRAM_START 0xB7000000 +#define RPU_ADDR_GRAM_END 0xB70101FF +#define RPU_ADDR_SBUS_START 0xA4000000 +#define RPU_ADDR_SBUS_END 0xA4007FFF +#define RPU_ADDR_PBUS_START 0xA5000000 +#define RPU_ADDR_PBUS_END 0xA503FFFF +#define RPU_ADDR_BEV_START 0xBFC00000 +#define RPU_ADDR_BEV_END 0xBFCFFFFF +#define RPU_ADDR_PKTRAM_START 0xB0000000 +#define RPU_ADDR_PKTRAM_END 0xB0030FFF + +/* Needed for calculatating sleep controller address */ +#define RPU_ADDR_LMAC_CORE_RET_START 0x80040000 +#define RPU_ADDR_UMAC_CORE_RET_START 0x80080000 + +enum RPU_MCU_ADDR_REGIONS { + RPU_MCU_ADDR_REGION_ROM = 0, + RPU_MCU_ADDR_REGION_RETENTION, + RPU_MCU_ADDR_REGION_SCRATCH, + RPU_MCU_ADDR_REGION_MAX, +}; + +struct rpu_addr_region { + unsigned int start; + unsigned int end; +}; + +struct rpu_addr_map { + struct rpu_addr_region regions[RPU_MCU_ADDR_REGION_MAX]; +}; + +static const struct rpu_addr_map RPU_ADDR_MAP_MCU[] = { + /* MCU1 - LMAC */ + { + { + {0x80000000, 0x80033FFF}, + {0x80040000, 0x8004BFFF}, + {0x80080000, 0x8008FFFF} + }, + }, + /* MCU2 - UMAC */ + { + { + {0x80000000, 0x800617FF}, + {0x80080000, 0x800A3FFF}, + {0x80100000, 0x80137FFF}, + } + }, +}; + +#define RPU_ADDR_MASK_BASE 0xFF000000 +#define RPU_ADDR_MASK_OFFSET 0x00FFFFFF +#define RPU_ADDR_MASK_BEV_OFFSET 0x000FFFFF + +/* Register locations from the Echo520 TRM */ +#define RPU_REG_INT_FROM_RPU_CTRL 0xA4000400 /* 8.1.1 */ +#define RPU_REG_BIT_INT_FROM_RPU_CTRL 17 + +#define RPU_REG_INT_TO_MCU_CTRL 0xA4000480 /* 8.3.7 */ + +#define RPU_REG_INT_FROM_MCU_ACK 0xA4000488 /* 8.3.9 */ +#define RPU_REG_BIT_INT_FROM_MCU_ACK 31 + +#define RPU_REG_INT_FROM_MCU_CTRL 0xA4000494 /* 8.3.12 */ +#define RPU_REG_BIT_INT_FROM_MCU_CTRL 31 + +#define RPU_REG_UCC_SLEEP_CTRL_DATA_0 0xA4002C2C /* 9.1.11 */ +#define RPU_REG_UCC_SLEEP_CTRL_DATA_1 0xA4002C30 /* 9.1.12 */ + +#define RPU_REG_MIPS_MCU_CONTROL 0xA4000000 /* 13.1.1 */ +#define RPU_REG_BIT_MIPS_MCU_LATCH_SOFT_RESET 1 +#define RPU_REG_MIPS_MCU2_CONTROL 0xA4000100 /* 13.1.1 */ + +#define RPU_REG_MIPS_MCU_UCCP_INT_STATUS 0xA4000004 +#define RPU_REG_BIT_MIPS_UCCP_INT_STATUS 0 +#define RPU_REG_BIT_MIPS_WATCHDOG_INT_STATUS 1 + +#define RPU_REG_MIPS_MCU_TIMER_CONTROL 0xA4000048 + +#define RPU_REG_MIPS_MCU_SYS_CORE_MEM_CTRL 0xA4000030 /* 13.1.10 */ +#define RPU_REG_MIPS_MCU_SYS_CORE_MEM_WDATA 0xA4000034 /* 13.1.11 */ +#define RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_0 0xA4000050 /* 13.1.15 */ +#define RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_1 0xA4000054 /* 13.1.16 */ +#define RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_2 0xA4000058 /* 13.1.17 */ +#define RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_3 0xA400005C /* 13.1.18 */ + +#define RPU_REG_MIPS_MCU2_SYS_CORE_MEM_CTRL 0xA4000130 /* 13.1.10 */ +#define RPU_REG_MIPS_MCU2_SYS_CORE_MEM_WDATA 0xA4000134 /* 13.1.11 */ +#define RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_0 0xA4000150 /* 13.1.15 */ +#define RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_1 0xA4000154 /* 13.1.16 */ +#define RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_2 0xA4000158 /* 13.1.17 */ +#define RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_3 0xA400015C /* 13.1.18 */ + +#define RPU_REG_MCP_SYS_CSTRCTRL 0xA4001200 +#define RPU_REG_MCP_SYS_CSTRDAT32 0xA4001218 + +#define RPU_REG_MCP2_SYS_CSTRCTRL 0xA4003200 +#define RPU_REG_MCP2_SYS_CSTRDAT32 0xA4003218 + +#define RPU_REG_MCP3_SYS_CSTRCTRL 0xA4004200 +#define RPU_REG_MCP3_SYS_CSTRDAT32 0xA4004218 + +#ifdef RPU_RF_C0_SUPPORT +#define PWR_CTRL1_SYSDEF 0xA4019000 +#define PWR_COUNTERSTART_SYSDEF 0xA40190A0 +#define PWR_COUNTERCYCLES_SYSDEF 0xA40190A4 +#define PWR_COUNTERSTATUS0_SYSDEF 0xA40190B0 +#define PWR_COUNTERSTATUS1_SYSDEF 0xA40190B4 +#define PWR_COUNTERSTATUS2_SYSDEF 0xA40190B8 +#define PWR_COUNTERSTATUS3_SYSDEF 0xA40190BC +#define WL_PWR_MON_SYSDEF 0xA4009310 +#define WL_PWR_AUX_SYSDEF 0xA4009314 +#define WL_PWR_VMON_CTRL_SYSDEF 0xA4009330 +#define WL_PWR_VMON_DATA_SYSDEF 0xA4009334 +#define WLAFE_WL_BBPLLEN_SYSDEF 0xA400B004 +#define WLAFE_RG_BBPLL_CLK_01_SYSDEF 0xA400B050 +#define WLAFE_RG_AFE_LDOCTRL_SYSDEF 0xA400B0F0 + +#define PWR_BREAKTIMER90_SYSDEF 0xA4019190 +#define PWR_BREAKCOND2_SYSDEF 0xA4019094 +#define PWR_BREAK3_SYSDEF 0xA4019080 +#define PWR_BREAKCOND3_SYSDEF 0xA4019098 +#define PWR_BREAK5_SYSDEF 0xA4019088 + +#else /* RPU_RF_C0_SUPPORT */ + +#define RPU_REG_RFCTL_UCC_RF_CTRL_CONFIG_00 0xA401C200 +#define RPU_REG_RFCTL_UCC_RF_CTRL_CONFIG_01 0xA401C204 +#define RPU_REG_RFCTL_UCC_RF_CTRL_CONFIG_02 0xA401C208 +#define RPU_REG_RFCTL_UCC_RF_CTRL_CONFIG_04 0xA401C210 +#define RPU_REG_RFCTL_UCC_RF_CTRL_CONFIG_16 0xA401C260 +#define RPU_REG_RFCTL_SPI_CMD_DATA_TABLE_0 0xA401C300 +#define RPU_REG_RFCTL_SPI_CMD_DATA_TABLE_1 0xA401C304 +#define RPU_REG_RFCTL_SPI_CMD_DATA_TABLE_2 0xA401C308 +#define RPU_REG_RFCTL_SPI_READ_DATA_TABLE_0 0xA401C380 + +#define PWR_CTRL1_SYSDEF 0x1040 +#define PWR_COUNTERSTART_SYSDEF 0x1158 +#define PWR_COUNTERCYCLES_SYSDEF 0x1159 +#define PWR_COUNTERSTATUS0_SYSDEF 0x115C +#define PWR_COUNTERSTATUS1_SYSDEF 0x115D +#define PWR_COUNTERSTATUS2_SYSDEF 0x115E +#define PWR_COUNTERSTATUS3_SYSDEF 0x115F +#define WL_PWR_MON_SYSDEF 0x0144 +#define WL_PWR_AUX_SYSDEF 0x0145 + +#define PWR_BREAKTIMER90_SYSDEF 0x1264 +#define PWR_BREAKCOND2_SYSDEF 0x1155 +#define PWR_BREAK3_SYSDEF 0x1150 +#define PWR_BREAKCOND3_SYSDEF 0x1156 +#define PWR_BREAK5_SYSDEF 0x1152 + +#define SPI_PAGESELECT 0x007C +#define SPI_DIGREFCLOCKCTRL 0x007D +#endif /* !RPU_RF_C0_SUPPORT */ + +#define RPU_REG_BIT_HARDRST_CTRL 8 +#define RPU_REG_BIT_PS_CTRL 0 +#define RPU_REG_BIT_PS_STATE 1 +#define RPU_REG_BIT_READY_STATE 2 + +#define RPU_MEM_RX_CMD_BASE 0xB7000D58 + +#define RPU_MEM_HPQ_INFO 0xB0000024 +#define RPU_MEM_TX_CMD_BASE 0xB00000B8 +#define RPU_MEM_OTP_INFO 0xB000005C +#define RPU_MEM_OTP_FT_PROG_VERSION 0xB0004FD8 +#define RPU_MEM_OTP_INFO_FLAGS 0xB0004FDC +#define RPU_MEM_LMAC_IF_INFO 0xB0004FE0 + +#define RPU_MEM_PKT_BASE 0xB0005000 +#define RPU_CMD_START_MAGIC 0xDEAD +#define RPU_DATA_CMD_SIZE_MAX_RX 8 +#define RPU_DATA_CMD_SIZE_MAX_TX 148 +#define RPU_EVENT_COMMON_SIZE_MAX 128 + +/*Event pool*/ +#define EVENT_POOL_NUM_ELEMS (7) +#define MAX_EVENT_POOL_LEN 1000 + +#define MAX_NUM_OF_RX_QUEUES 3 + +#define NRF_WIFI_RPU_PWR_DATA_TYPE_LFC_ERR 0 +#define NRF_WIFI_RPU_PWR_DATA_TYPE_VBAT_MON 1 +#define NRF_WIFI_RPU_PWR_DATA_TYPE_TEMP 2 +#define NRF_WIFI_RPU_PWR_DATA_TYPE_ALL 3 +#define NRF_WIFI_RPU_PWR_DATA_TYPE_MAX 4 + +#ifndef RPU_RF_C0_SUPPORT +#define NRF_WIFI_RPU_RF_CLK_TYPE_20 0 +#define NRF_WIFI_RPU_RF_CLK_TYPE_40 1 +#define NRF_WIFI_RPU_RF_CLK_TYPE_MAX 2 +#endif /* RPU_RF_C0_SUPPORT */ + +#define RPU_PKTRAM_SIZE (RPU_ADDR_PKTRAM_END - RPU_MEM_PKT_BASE + 1) + +#ifdef CONFIG_NRF700X_RADIO_TEST +#define RPU_MEM_RF_TEST_CAP_BASE 0xB0006000 +#endif /* CONFIG_NRF700X_RADIO_TEST */ + +/* REGION PROTECT : OTP Address offsets (word offsets) */ +#define REGION_PROTECT 64 +#define PRODTEST_FT_PROGVERSION 29 +#define PRODTEST_TRIM0 32 +#define PRODTEST_TRIM1 33 +#define PRODTEST_TRIM2 34 +#define PRODTEST_TRIM3 35 +#define PRODTEST_TRIM4 36 +#define PRODTEST_TRIM5 37 +#define PRODTEST_TRIM6 38 +#define PRODTEST_TRIM7 39 +#define PRODTEST_TRIM8 40 +#define PRODTEST_TRIM9 41 +#define PRODTEST_TRIM10 42 +#define PRODTEST_TRIM11 43 +#define PRODTEST_TRIM12 44 +#define PRODTEST_TRIM13 45 +#define PRODTEST_TRIM14 46 +#define PRODCTRL_DISABLE5GHZ 47 +#define INFO_PART 48 +#define INFO_VARIANT 49 +#define INFO_UUID 52 +#define QSPI_KEY 68 +#define MAC0_ADDR 72 +#define MAC1_ADDR 74 +#define CALIB_XO 76 +#define CALIB_PDADJM7 77 +#define CALIB_PDADJM0 78 +#define CALIB_PWR2G 79 +#define CALIB_PWR5GM7 80 +#define CALIB_PWR5GM0 81 +#define CALIB_RXGNOFF 82 +#define CALIB_TXPOWBACKOFFT 83 +#define CALIB_TXPOWBACKOFFV 84 +#define REGION_DEFAULTS 85 +#define PRODRETEST_PROGVERSION 86 +#define PRODRETEST_TRIM0 87 +#define PRODRETEST_TRIM1 88 +#define PRODRETEST_TRIM2 89 +#define PRODRETEST_TRIM3 90 +#define PRODRETEST_TRIM4 91 +#define PRODRETEST_TRIM5 92 +#define PRODRETEST_TRIM6 93 +#define PRODRETEST_TRIM7 94 +#define PRODRETEST_TRIM8 95 +#define PRODRETEST_TRIM9 96 +#define PRODRETEST_TRIM10 97 +#define PRODRETEST_TRIM11 98 +#define PRODRETEST_TRIM12 99 +#define PRODRETEST_TRIM13 100 +#define PRODRETEST_TRIM14 101 +#define OTP_MAX_WORD_LEN 128 +#define QSPI_KEY_LENGTH_BYTES 16 +#define RETRIM_LEN 15 + +/* Size of OTP fields in bytes */ +#define OTP_SZ_CALIB_XO 1 +#define OTP_SZ_CALIB_PDADJM7 4 +#define OTP_SZ_CALIB_PDADJM0 4 +#define OTP_SZ_CALIB_PWR2G 1 +#define OTP_SZ_CALIB_PWR2GM0M7 2 +#define OTP_SZ_CALIB_PWR5GM7 3 +#define OTP_SZ_CALIB_PWR5GM0 3 +#define OTP_SZ_CALIB_RXGNOFF 4 +#define OTP_SZ_CALIB_TXP_BOFF_2GH 1 +#define OTP_SZ_CALIB_TXP_BOFF_2GL 1 +#define OTP_SZ_CALIB_TXP_BOFF_5GH 1 +#define OTP_SZ_CALIB_TXP_BOFF_5GL 1 +#define OTP_SZ_CALIB_TXP_BOFF_V 4 + +/* Offsets of OTP calib values in the calib field */ +#define OTP_OFF_CALIB_XO 0 +#define OTP_OFF_CALIB_PDADJM7 4 +#define OTP_OFF_CALIB_PDADJM0 8 +#define OTP_OFF_CALIB_PWR2G 12 +#define OTP_OFF_CALIB_PWR2GM0M7 13 +#define OTP_OFF_CALIB_PWR5GM7 16 +#define OTP_OFF_CALIB_PWR5GM0 20 +#define OTP_OFF_CALIB_RXGNOFF 24 +#define OTP_OFF_CALIB_TXP_BOFF_2GH 28 +#define OTP_OFF_CALIB_TXP_BOFF_2GL 29 +#define OTP_OFF_CALIB_TXP_BOFF_5GH 30 +#define OTP_OFF_CALIB_TXP_BOFF_5GL 31 +#define OTP_OFF_CALIB_TXP_BOFF_V 32 + +/* MASKS to program bit fields in REGION_DEFAULTS register */ +#define QSPI_KEY_FLAG_MASK ~(1U<<0) +#define MAC0_ADDR_FLAG_MASK ~(1U<<1) +#define MAC1_ADDR_FLAG_MASK ~(1U<<2) +#define CALIB_XO_FLAG_MASK ~(1U<<3) +#define CALIB_PDADJM7_FLAG_MASK ~(1U<<4) +#define CALIB_PDADJM0_FLAG_MASK ~(1U<<5) +#define CALIB_PWR2G_FLAG_MASK ~(1U<<6) +#define CALIB_PWR5GM7_FLAG_MASK ~(1U<<7) +#define CALIB_PWR5GM0_FLAG_MASK ~(1U<<8) +#define CALIB_RXGNOFF_FLAG_MASK ~(1U<<9) +#define CALIB_TXPOWBACKOFFT_FLAG_MASK ~(1U<<10) +#define CALIB_TXPOWBACKOFFV_FLAG_MASK ~(1U<<11) + +/* OTP Device address definitions */ +#define OTP_VOLTCTRL_ADDR 0x19004 +#define OTP_VOLTCTRL_2V5 0x3b +#define OTP_VOLTCTRL_1V8 0xb + +#define OTP_POLL_ADDR 0x01B804 +#define OTP_WR_DONE 0x1 +#define OTP_READ_VALID 0x2 +#define OTP_READY 0x4 + + +#define OTP_RWSBMODE_ADDR 0x01B800 +#define OTP_STANDBY_MODE 0x0 +#define OTP_READ_MODE 0x1 +#define OTP_BYTE_WRITE_MODE 0x42 + + +#define OTP_RDENABLE_ADDR 0x01B810 +#define OTP_READREG_ADDR 0x01B814 + +#define OTP_WRENABLE_ADDR 0x01B808 +#define OTP_WRITEREG_ADDR 0x01B80C + +#define OTP_TIMING_REG1_ADDR 0x01B820 +#define OTP_TIMING_REG1_VAL 0x0 +#define OTP_TIMING_REG2_ADDR 0x01B824 +#define OTP_TIMING_REG2_VAL 0x030D8B + +#define PRODTEST_TRIM_LEN 15 + +#define OTP_FRESH_FROM_FAB 0xFFFFFFFF +#define OTP_PROGRAMMED 0x00000000 +#define OTP_ENABLE_PATTERN 0x50FA50FA +#define OTP_INVALID 0xDEADBEEF + +#define FT_PROG_VER_MASK 0xF0000 + +/** + * struct nrf_wifi_rpu_pwr_data - Data that host may want to read from the Power IP. + * @lfc_err: Estimated Lo Frequency Clock error in ppm. + * @vbat_mon: Vbat monitor readout. The actual Vbat in volt equals 2.5 + 0.07*vbat_mon. + * @temp: Estimated die temperature (degC). + * + * This structure represents the Power IP monitoring data. + */ +struct nrf_wifi_rpu_pwr_data { + int lfc_err; + int vbat_mon; + int temp; +}; + +/** + * struct host_rpu_rx_buf_info - RX buffer related information to be passed to + * the RPU. + * @addr: Address in the host memory where the RX buffer is located. + * + * This structure encapsulates the information to be passed to the RPU for + * buffers which the RPU will use to pass the received frames. + */ + +struct host_rpu_rx_buf_info { + unsigned int addr; +} __NRF_WIFI_PKD; + +/** + * struct host_rpu_hpq - Hostport Queue (HPQ) information. + * @enqueue_addr: HPQ address where the host can post the address of a + * message intended for the RPU. + * @dequeue_addr: HPQ address where the host can get the address of a + * message intended for the host. + * + * This structure encapsulates the information which represents a HPQ. + */ + +struct host_rpu_hpq { + unsigned int enqueue_addr; + unsigned int dequeue_addr; +} __NRF_WIFI_PKD; + +/** + * struct host_rpu_hpqm_info - Information about Hostport Queues (HPQ) to be used + * for exchanging information between the Host and RPU. + * @event_busy_queue: Queue which the RPU uses to inform the host about events. + * @event_avl_queue: Queue on which the consumed events are pushed so that RPU + * can reuse them. + * @cmd_busy_queue: Queue used by the host to push commands to the RPU. + * @cmd_avl_queue: Queue which RPU uses to inform host about command + * buffers which can be used to push commands to the RPU. + * + * Hostport queue information passed by the RPU to the host, which the host can + * use, to communicate with the RPU. + */ + +struct host_rpu_hpqm_info { + struct host_rpu_hpq event_busy_queue; + struct host_rpu_hpq event_avl_queue; + struct host_rpu_hpq cmd_busy_queue; + struct host_rpu_hpq cmd_avl_queue; + struct host_rpu_hpq rx_buf_busy_queue[MAX_NUM_OF_RX_QUEUES]; +} __NRF_WIFI_PKD; + +/** + * struct host_rpu_msg_hdr - Common header included in each command/event. + * @len: Length of the message. + * @resubmit: Flag to indicate whether the recipient is expected to resubmit + * the cmd/event address back to the trasmitting entity. + * + * This structure encapsulates the common information included at the start of + * each command/event exchanged with the RPU. + */ + +struct host_rpu_msg_hdr { + unsigned int len; + unsigned int resubmit; +} __NRF_WIFI_PKD; + +#define BT_INIT 0x1 +#define BT_MODE 0x2 +#define BT_CTRL 0x4 + +/*! BT coexistence module enable or disable */ + +#define BT_COEX_DISABLE 0 +#define BT_COEX_ENABLE 1 + +/* External BT mode master or slave */ + +#define SLAVE 0 +#define MASTER 1 + +struct pta_ext_params { + /*! Set polarity to 1 if BT_TX_RX active high indicates Tx. Set polarity to 0 if BT_TX_RX + * active high indicates Rx. + */ + unsigned char tx_rx_pol; + + /*! BT_ACTIVE signal lead time period. This is with reference to time instance at which + *BT slot boundary starts if BT supports classic only mode and BT activity starts if BT + *supports BLE or dual mode + */ + unsigned int lead_time; + + /*! Time instance at which BT_STATUS is sampled by PTA to get the BT_PTI information. This + *is done anywhere between BT_ACTIVE_ASSERT time and BT_STATUS priority signalling time + *period ends.This is with reference to BT_ACTIVE assert time. + */ + unsigned int pti_samp_time; + + /*! Time instance at which BT_STATUS is sampled by PTA to get BT_TX_RX information. + *This is done by PTA after the end of time period T2. This is with reference to BT_ACTIVE + *assert time. + */ + unsigned int tx_rx_samp_time; + + /*! Time instance at which PTA takes arbitration decision and posts WLAN_DENY to BT. This + * is with reference to BT_ACTIVE assert time. + */ + unsigned int dec_time; +} __NRF_WIFI_PKD; +#endif /* __RPU_IF_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/hal_api.h b/nrf_wifi/hw_if/hal/inc/hal_api.h new file mode 100644 index 0000000000..7b5cbf0b74 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_api.h @@ -0,0 +1,185 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing API declarations for the + * HAL Layer of the Wi-Fi driver. + */ + + +#ifndef __HAL_API_H__ +#define __HAL_API_H__ + +#include +#include "osal_api.h" +#include "rpu_if.h" +#include "bal_api.h" +#include "hal_structs.h" +#include "hal_mem.h" +#include "hal_reg.h" +#include "hal_fw_patch_loader.h" + + +/** + * nrf_wifi_hal_init() - Initialize the HAL layer. + * + * @opriv: Pointer to the OSAL layer. + * @cfg_params: Parameters needed to configure the HAL for WLAN operation. + * @intr_callbk_fn: Pointer to the callback function which the user of this + * layer needs to implement to handle events from the RPU. + * + * This API is used to initialize the HAL layer and is expected to be called + * before using the HAL layer. This API returns a pointer to the HAL context + * which might need to be passed to further API calls. + * + * Returns: Pointer to instance of HAL layer context. + */ +struct nrf_wifi_hal_priv * +nrf_wifi_hal_init(struct nrf_wifi_osal_priv *opriv, + struct nrf_wifi_hal_cfg_params *cfg_params, + enum nrf_wifi_status (*intr_callbk_fn)(void *mac_ctx, + void *event_data, + unsigned int len)); + +/** + * nrf_wifi_hal_deinit() - Deinitialize the HAL layer. + * @hpriv: Pointer to the HAL context returned by the @nrf_wifi_hal_init API. + * + * This API is used to deinitialize the HAL layer and is expected to be called + * after done using the HAL layer. + * + * Returns: None. + */ +void nrf_wifi_hal_deinit(struct nrf_wifi_hal_priv *hpriv); + + +struct nrf_wifi_hal_dev_ctx *nrf_wifi_hal_dev_add(struct nrf_wifi_hal_priv *hpriv, + void *mac_dev_ctx); + + +void nrf_wifi_hal_dev_rem(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); + + +enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); + + +void nrf_wifi_hal_dev_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); + +/** + * nrf_wifi_hal_ctrl_cmd_send() - Sends a control command to the RPU. + * @hal_ctx: Pointer to HAL context. + * @cmd: Pointer to command data. + * @cmd_size: Size of the command data pointed to by @cmd. + * + * This function takes care of sending a command to the RPU. It does the + * following: + * + * - Fragments a command into smaller chunks if the size of a command is + * greater than %MAX_CMD_SIZE. + * - Queues up the command(s) to the HAL command queue. + * - Calls a function to further process the commands queued up in the HAL + * command queue which handles it by: + * + * - Waiting for the RPU to be ready to handle a command. + * - Copies the command to the GRAM memory and indicates to the RPU + * that a command has been posted + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status nrf_wifi_hal_ctrl_cmd_send(struct nrf_wifi_hal_dev_ctx *hal_ctx, + void *cmd, + unsigned int cmd_size); + + +/** + * nrf_wifi_hal_data_cmd_send() - Send a data command to the RPU. + * @hal_ctx: Pointer to HAL context. + * @cmd_type: Type of the data command to send to the RPU. + * @data_cmd: The data command to be sent to the RPU. + * @data_cmd_size: Size of the data command to be sent to the RPU. + * @desc_id: Descriptor ID of the buffer being submitted to RPU. + * @pool_id: Pool ID to which the buffer being submitted to RPU belongs. + * + * This function programs the relevant information about a data command, + * to the RPU. These buffers are needed by the RPU to receive data and + * management frames as well as to transmit data frames. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status nrf_wifi_hal_data_cmd_send(struct nrf_wifi_hal_dev_ctx *hal_ctx, + enum NRF_WIFI_HAL_MSG_TYPE cmd_type, + void *data_cmd, + unsigned int data_cmd_size, + unsigned int desc_id, + unsigned int pool_id); + +/** + * hal_rpu_eventq_process() - Process events from the RPU. + * @hpriv: Pointer to HAL context. + * + * This function processes the events which have been queued into the event + * queue by an ISR. It does the following: + * + * - Dequeues an event from the event queue. + * - Calls hal_event_process to further process the event. + * + * Return: Status + * Pass: %NRF_WIFI_STATUS_SUCCESS + * Fail: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_eventq_process(struct nrf_wifi_hal_dev_ctx *hal_ctx); + + +unsigned long nrf_wifi_hal_buf_map_rx(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned long buf, + unsigned int buf_len, + unsigned int pool_id, + unsigned int buf_id); + +unsigned long nrf_wifi_hal_buf_unmap_rx(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned int data_len, + unsigned int pool_id, + unsigned int buf_id); + +unsigned long nrf_wifi_hal_buf_map_tx(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned long buf, + unsigned int buf_len, + unsigned int desc_id, + unsigned int token, + unsigned int buf_indx); + +unsigned long nrf_wifi_hal_buf_unmap_tx(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned int desc_id); + +void nrf_wifi_hal_proc_ctx_set(struct nrf_wifi_hal_dev_ctx *hal_ctx, + enum RPU_PROC_TYPE proc); + +enum nrf_wifi_status nrf_wifi_hal_proc_reset(struct nrf_wifi_hal_dev_ctx *hal_ctx, + enum RPU_PROC_TYPE rpu_proc); + +enum nrf_wifi_status nrf_wifi_hal_fw_chk_boot(struct nrf_wifi_hal_dev_ctx *hal_ctx, + enum RPU_PROC_TYPE rpu_proc); + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +enum nrf_wifi_status hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); +enum nrf_wifi_status nrf_wifi_hal_get_rpu_ps_state( + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + int *rpu_ps_ctrl_state); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ +#endif /* __HAL_API_H__ */ + + +enum nrf_wifi_status nrf_wifi_hal_otp_info_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + struct host_rpu_umac_info *otp_info, + unsigned int *otp_flags); + +enum nrf_wifi_status nrf_wifi_hal_otp_ft_prog_ver_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int *ft_prog_ver); diff --git a/nrf_wifi/hw_if/hal/inc/hal_common.h b/nrf_wifi/hw_if/hal/inc/hal_common.h new file mode 100644 index 0000000000..d84630fc2f --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_common.h @@ -0,0 +1,22 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing common declarations for the + * HAL Layer of the Wi-Fi driver. + */ + +#ifndef __HAL_COMMON_H__ +#define __HAL_COMMON_H__ + +enum nrf_wifi_status hal_rpu_hpq_enqueue(struct nrf_wifi_hal_dev_ctx *hal_ctx, + struct host_rpu_hpq *hpq, + unsigned int val); + +enum nrf_wifi_status hal_rpu_hpq_dequeue(struct nrf_wifi_hal_dev_ctx *hal_ctx, + struct host_rpu_hpq *hpq, + unsigned int *val); +#endif /* __HAL_COMMON_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/hal_fw_patch_loader.h b/nrf_wifi/hw_if/hal/inc/hal_fw_patch_loader.h new file mode 100644 index 0000000000..8739c806a8 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_fw_patch_loader.h @@ -0,0 +1,37 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing patch loader specific declarations for the + * HAL Layer of the Wi-Fi driver. + */ + +#ifndef __HAL_FW_PATCH_LOADER_H__ +#define __HAL_FW_PATCH_LOADER_H__ + +#include "hal_structs.h" + +enum nrf_wifi_fw_patch_type { + NRF_WIFI_FW_PATCH_TYPE_PRI, + NRF_WIFI_FW_PATCH_TYPE_SEC, + NRF_WIFI_FW_PATCH_TYPE_MAX +}; + + +/* + * Downloads a firmware patch into RPU memory. + */ +enum nrf_wifi_status nrf_wifi_hal_fw_patch_load(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc, + const void *fw_pri_patch_data, + unsigned int fw_pri_patch_size, + const void *fw_sec_patch_data, + unsigned int fw_sec_patch_size); + +enum nrf_wifi_status nrf_wifi_hal_fw_patch_boot(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc, + bool is_patch_present); +#endif /* __HAL_FW_PATCH_LOADER_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/hal_interrupt.h b/nrf_wifi/hw_if/hal/inc/hal_interrupt.h new file mode 100644 index 0000000000..c21e0e6781 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_interrupt.h @@ -0,0 +1,61 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing interrupt handler specific declarations for the + * HAL Layer of the Wi-Fi driver. + */ + +#ifndef __HAL_INTERRUPT_H__ +#define __HAL_INTERRUPT_H__ + +#include "hal_api.h" + +/** + * hal_rpu_irq_enable() - Enables interrupts from the RPU. + * @hal_dev_ctx: Pointer to HAL context. + * + * This function enables the interrupts from the RPU. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_irq_enable(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); + + +/** + * hal_rpu_irq_disable() - Disables interrupts from the RPU. + * @hal_dev_ctx: Pointer to HAL context. + * + * This function disables the interrupts from the RPU. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_irq_disable(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); + + +/** + * hal_rpu_irq_process() - Processes an interrupt from the RPU. + * @hal_dev_ctx: Pointer to HAL context. + * + * This function is an interrupt handler for the interrupts generated by the + * RPU. This function does the following: + * + * - Stores the event details for as many events as available,into local + * buffers and queues them to the event queue for deferred + * processing. (Refer to hal_eventq_process for the + * deferred handler). + * - Acknowledges the RPU interrupt. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_irq_process(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx); +#endif /* __HAL_INTERRUPT_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/hal_mem.h b/nrf_wifi/hw_if/hal/inc/hal_mem.h new file mode 100644 index 0000000000..f969f31063 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_mem.h @@ -0,0 +1,84 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing memoy read/write specific declarations for the + * HAL Layer of the Wi-Fi driver. + */ + +#ifndef __HAL_MEM_H__ +#define __HAL_MEM_H__ + +#include "hal_api.h" + +enum HAL_RPU_MEM_TYPE { + HAL_RPU_MEM_TYPE_GRAM, + HAL_RPU_MEM_TYPE_PKTRAM, + HAL_RPU_MEM_TYPE_CORE_ROM, + HAL_RPU_MEM_TYPE_CORE_RET, + HAL_RPU_MEM_TYPE_CORE_SCRATCH, + HAL_RPU_MEM_TYPE_MAX +}; + + +/** + * hal_rpu_mem_read() - Read from the RPU memory. + * @hpriv: Pointer to HAL context. + * @host_addr: Pointer to the host memory where the contents read from the RPU + * memory are to be copied. + * @rpu_mem_addr: Absolute value of the RPU memory address from which the + * contents are to be read. + * @len: The length (in bytes) of the contents to be read from the RPU memory. + * + * This function reads len bytes of contents from the RPU memory and copies them + * to the host memory pointed to by the host_addr parameter. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_mem_read(struct nrf_wifi_hal_dev_ctx *hal_ctx, + void *host_addr, + unsigned int rpu_mem_addr, + unsigned int len); + +/** + * hal_rpu_mem_write() - Write to the RPU memory. + * @hpriv: Pointer to HAL context. + * @rpu_mem_addr: Absolute value of the RPU memory address where the contents + * are to be written. + * @host_addr: Pointer to the host memory from where the contents are to be + * copied to the RPU memory. + * @len: The length (in bytes) of the contents to be copied to the RPU memory. + * + * This function writes len bytes of contents to the RPU memory from the host + * memory pointed to by the host_addr parameter. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_mem_write(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned int rpu_mem_addr, + void *host_addr, + unsigned int len); + + +/** + * hal_rpu_mem_clr() - Clear contents of RPU memory. + * @hal_ctx: Pointer to HAL context. + * @mem_type: The type of the RPU memory to be cleared. + * + * This function fills the RPU memory with 0's. + * + * Return: Status + * Pass : %NRF_WIFI_STATUS_SUCCESS + * Error: %NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_mem_clr(struct nrf_wifi_hal_dev_ctx *hal_ctx, + enum RPU_PROC_TYPE rpu_proc, + enum HAL_RPU_MEM_TYPE mem_type); +#endif /* __HAL_MEM_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/hal_reg.h b/nrf_wifi/hw_if/hal/inc/hal_reg.h new file mode 100644 index 0000000000..7fbd5b9a0d --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_reg.h @@ -0,0 +1,54 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing register read/write specific declarations for the + * HAL Layer of the Wi-Fi driver. + */ + + + +#ifndef __HAL_REG_H__ +#define __HAL_REG_H__ + +#include "hal_structs.h" + +/** + * hal_rpu_reg_read() - Read from a RPU register. + * @hal_ctx: Pointer to HAL context. + * @val: Pointer to the host memory where the value read from the RPU register + * is to be copied. + * @rpu_reg_addr: Absolute value of RPU register address from which the + * value is to be read. + * + * This function reads a 4 byte value from a RPU register and copies it + * to the host memory pointed to by the val parameter. + * + * Return: Status + * Pass : NRF_WIFI_STATUS_SUCCESS + * Error: NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_reg_read(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned int *val, + unsigned int rpu_reg_addr); + +/** + * hal_rpu_reg_write() - Write to a RPU register. + * @hal_ctx: Pointer to HAL context. + * @rpu_reg_addr: Absolute value of RPU register address to which the + * value is to be written. + * @val: The value which is to be written to the RPU register. + * + * This function writes a 4 byte value to a RPU register. + * + * Return: Status + * Pass : NRF_WIFI_STATUS_SUCCESS + * Error: NRF_WIFI_STATUS_FAIL + */ +enum nrf_wifi_status hal_rpu_reg_write(struct nrf_wifi_hal_dev_ctx *hal_ctx, + unsigned int rpu_reg_addr, + unsigned int val); +#endif /* __HAL_REG_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/hal_structs.h b/nrf_wifi/hw_if/hal/inc/hal_structs.h new file mode 100644 index 0000000000..c58ead1513 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/hal_structs.h @@ -0,0 +1,249 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing structure declarations for the + * HAL Layer of the Wi-Fi driver. + */ + +#ifndef __HAL_STRUCTS_H__ +#define __HAL_STRUCTS_H__ + +#include +#include "lmac_if_common.h" +#include "host_rpu_common_if.h" +#include "osal_api.h" +#include "bal_api.h" + +#define MAX_HAL_RPU_READY_WAIT (1 * 1000 * 1000) /* 1 sec */ + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#define RPU_PS_WAKE_INTERVAL_MS 1 +#define RPU_PS_WAKE_TIMEOUT_S 1 +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + +enum RPU_PROC_TYPE { + RPU_PROC_TYPE_MCU_LMAC = 0, + RPU_PROC_TYPE_MCU_UMAC, + RPU_PROC_TYPE_MAX +}; + +static inline const char *rpu_proc_to_str(enum RPU_PROC_TYPE proc) +{ + switch (proc) { + case RPU_PROC_TYPE_MCU_LMAC: + return "LMAC"; + case RPU_PROC_TYPE_MCU_UMAC: + return "UMAC"; + default: + return "UNKNOWN"; + } +} + + +enum NRF_WIFI_REGION_TYPE { + NRF_WIFI_REGION_TYPE_GRAM, + NRF_WIFI_REGION_TYPE_PKTRAM, + NRF_WIFI_REGION_TYPE_SYSBUS, + NRF_WIFI_REGION_TYPE_PBUS, +}; + + +enum NRF_WIFI_HAL_MSG_TYPE { + NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL, + NRF_WIFI_HAL_MSG_TYPE_EVENT, + NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX, + NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_MGMT, + NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX, + NRF_WIFI_HAL_MSG_TYPE_MAX, +}; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +enum RPU_PS_STATE { + RPU_PS_STATE_ASLEEP, + RPU_PS_STATE_AWAKE, + RPU_PS_STATE_MAX +}; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + +struct nrf_wifi_hal_cfg_params { + unsigned int max_cmd_size; + unsigned int max_event_size; + +#ifndef CONFIG_NRF700X_RADIO_TEST + unsigned char rx_buf_headroom_sz; + unsigned char tx_buf_headroom_sz; +#ifdef CONFIG_NRF700X_DATA_TX + unsigned int max_tx_frms; +#endif /* CONFIG_NRF700X_DATA_TX */ + struct rx_buf_pool_params rx_buf_pool[MAX_NUM_OF_RX_QUEUES]; + unsigned int max_tx_frm_sz; + unsigned int max_ampdu_len_per_token; +#endif /* !CONFIG_NRF700X_RADIO_TEST */ +}; + + +/** + * struct nrf_wifi_hal_priv - Structure to hold context information for the + * HAL layer. + * @opriv: Pointer to the OS abstraction layer. + * @bpriv: Pointer to the Bus abstraction layer. + * @add_dev_callbk_data: Data to be passed back when invoking @add_dev_callbk_fn. + * @add_dev_callbk_fn: Callback function to be called when a new device is being added. + * @rem_dev_callbk_fn: Callback function to be called when a device is being removed. + * @init_dev_callbk_fn: Callback function to be called when a device is being initialised. + * @deinit_dev_callbk_fn: Callback function to be called when a device is being deinitialised. + * @intr_callback_fn: Pointer to the function which needs to be called when an + * interrupt is received. + * @max_cmd_size: Maximum size of the command that can be sent to the + * Firmware. + * + * This structure maintains the context information necessary for the + * operation of the HAL layer. + */ +struct nrf_wifi_hal_priv { + struct nrf_wifi_osal_priv *opriv; + struct nrf_wifi_bal_priv *bpriv; + unsigned char num_devs; + + void *add_dev_callbk_data; + void *(*add_dev_callbk_fn)(void *add_dev_callbk_data, + void *hal_dev_ctx); + void (*rem_dev_callbk_fn)(void *mac_ctx); + + enum nrf_wifi_status (*init_dev_callbk_fn)(void *mac_ctx); + void (*deinit_dev_callbk_fn)(void *mac_ctx); + + enum nrf_wifi_status (*intr_callbk_fn)(void *mac_ctx, + void *event_data, + unsigned int len); + struct nrf_wifi_hal_cfg_params cfg_params; + unsigned long addr_pktram_base; +}; + + +/** + * struct nrf_wifi_hal_info - Structure to hold RPU information. + * @hpqm_info: HPQM queue(s) related information. + * @rx_cmd_base: The base address for posting RX commands. + * @tx_cmd_base: The base address for posting TX commands. + * + * This structure contains RPU related information needed by the + * HAL layer. + */ +struct nrf_wifi_hal_info { + struct host_rpu_hpqm_info hpqm_info; + unsigned int rx_cmd_base; + unsigned int tx_cmd_base; +}; + + +struct nrf_wifi_hal_buf_map_info { + bool mapped; + unsigned long virt_addr; + unsigned long phy_addr; + unsigned int buf_len; +}; + + +/** + * struct nrf_wifi_hal_dev_ctx - Structure to hold per device context information + * for the HAL layer. + * @hpriv: Pointer to the HAL abstraction layer. + * @idx: The index of the HAL instantiation (the instance of the device to + * which this HAL instance is associated to) + * @mac_ctx: Pointer to the per device MAC context which is using the HAL layer. + * @dev_ctx: Pointer to the per device BUS context which is being used by the + * HAL layer. + * @rpu_info: RPU specific information necessary for the operation + * of the HAL. + * @num_cmds: Debug counter for number of commands sent by the host to the RPU. + * @cmd_q: Queue to hold commands before they are sent to the RPU. + * @event_q: Queue to hold events received from the RPU before they are + * processed by the host. + * @curr_proc: The RPU MCU whose context is active for a given HAL operation. + * This is needed only during FW loading and not necessary during + * the regular operation after the FW has been loaded. + * @lock_hal: Lock to be used for atomic HAL operations. + * @lock_rx: Lock to be used for atomic RX operations. + * @event_tasklet: Pointer to the bottom half handler for RX events. + * @rpu_ps_state: PS state of the RPU. + * @rpu_ps_timer: Inactivity timer used to put RPU back to sleep after + * waking it up. + * @rpu_ps_lock: Lock to be used for atomic RPU PS operations. + * @num_isrs: Debug counter for number of interrupts received from the RPU. + * @num_events: Debug counter for number of events received from the RPU. + * @num_events_resubmit: Debug counter for number of event pointers + * resubmitted back to the RPU. + * + * This structure maintains the context information necessary for the + * operation of the HAL. Some of the elements of the structure need to be + * initialized durign the initialization of the driver while others need to + * be kept updated over the duration of the driver operation. + */ +struct nrf_wifi_hal_dev_ctx { + struct nrf_wifi_hal_priv *hpriv; + void *mac_dev_ctx; + void *bal_dev_ctx; + unsigned char idx; + + struct nrf_wifi_hal_info rpu_info; + + unsigned int num_cmds; + + void *cmd_q; + void *event_q; + + /* This is only used during FW loading where we need the information + * about the processor whose core memory the code/data needs to be + * loaded into (since the FW image parser does not have the processor + * information coded into it). Necessitated due to FullMAC + * configuration where the RPU has 2 MCUs. + */ + enum RPU_PROC_TYPE curr_proc; + + void *lock_hal; + void *event_tasklet; + void *lock_rx; + + struct nrf_wifi_hal_buf_map_info *rx_buf_info[MAX_NUM_OF_RX_QUEUES]; + struct nrf_wifi_hal_buf_map_info *tx_buf_info; + + unsigned long addr_rpu_pktram_base; + unsigned long addr_rpu_pktram_base_tx; + unsigned long addr_rpu_pktram_base_rx; + unsigned long addr_rpu_pktram_base_rx_pool[MAX_NUM_OF_RX_QUEUES]; + unsigned long tx_frame_offset; +#ifdef CONFIG_NRF_WIFI_LOW_POWER + enum RPU_PS_STATE rpu_ps_state; + void *rpu_ps_timer; + void *rpu_ps_lock; + bool dbg_enable; + bool irq_ctx; + bool rpu_fw_booted; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + char *event_data; + char *event_data_curr; + unsigned int event_data_len; + unsigned int event_data_pending; + unsigned int event_resubmit; +}; + + +/** + * struct nrf_wifi_hal_msg - Structure to hold information about a HAL message. + * @len: Length of the HAL message. + * @data: Pointer to the buffer containing the HAL message. + * + * This structure contains information about a HAL message (command/event). + */ +struct nrf_wifi_hal_msg { + unsigned int len; + char data[0]; +}; +#endif /* __HAL_STRUCTS_H__ */ diff --git a/nrf_wifi/hw_if/hal/inc/pal.h b/nrf_wifi/hw_if/hal/inc/pal.h new file mode 100644 index 0000000000..0491ebb307 --- /dev/null +++ b/nrf_wifi/hw_if/hal/inc/pal.h @@ -0,0 +1,99 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing SoC specific declarations for the + * HAL Layer of the Wi-Fi driver. + */ + +#ifndef __PAL_H__ +#define __PAL_H__ + +#include "hal_api.h" + +#define SOC_BOOT_SUCCESS 0 +#define SOC_BOOT_FAIL 1 +#define SOC_BOOT_ERRORS 2 + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +#define SOC_MMAP_ADDR_RPU_PS_CTRL 0x3FFFFC +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + +#define DEFAULT_IMGPCI_VENDOR_ID 0x0700 +#define DEFAULT_IMGPCI_DEVICE_ID PCI_ANY_ID +#define PCIE_BAR_OFFSET_WLAN_RPU 0x0 +#define PCIE_DMA_MASK 0xFFFFFFFF + + +#define SOC_MMAP_ADDR_OFFSET_PKTRAM_HOST_VIEW 0x0C0000 +#define SOC_MMAP_ADDR_OFFSET_PKTRAM_RPU_VIEW 0x380000 + +#ifdef RPU_CONFIG_72 +#define SOC_MMAP_ADDR_OFFSET_GRAM_PKD 0xC00000 +#define SOC_MMAP_ADDR_OFFSET_SYSBUS 0xE00000 +#define SOC_MMAP_ADDR_OFFSET_PBUS 0xE40000 +#else +#define SOC_MMAP_ADDR_OFFSET_GRAM_PKD 0x80000 +#define SOC_MMAP_ADDR_OFFSET_SYSBUS 0x00000 +#define SOC_MMAP_ADDR_OFFSET_PBUS 0x40000 + +static const unsigned int SOC_MMAP_ADDR_OFFSETS_MCU[] = { + 0x100000, + 0x200000 +}; + +#endif /* RPU_CONFIG_72 */ + +#define RPU_MCU_CORE_INDIRECT_BASE 0xC0000000 + +#define NRF_WIFI_FW_LMAC_PATCH_LOC_PRI "img/wlan/nrf_wifi_lmac_patch_pri.bimg" +#define NRF_WIFI_FW_LMAC_PATCH_LOC_SEC "img/wlan/nrf_wifi_lmac_patch_sec.bin" +#define NRF_WIFI_FW_UMAC_PATCH_LOC_PRI "img/wlan/nrf_wifi_umac_patch_pri.bimg" +#define NRF_WIFI_FW_UMAC_PATCH_LOC_SEC "img/wlan/nrf_wifi_umac_patch_sec.bin" + +enum nrf_wifi_fw_type { + NRF_WIFI_FW_TYPE_LMAC_PATCH, + NRF_WIFI_FW_TYPE_UMAC_PATCH, + NRF_WIFI_FW_TYPE_MAX +}; + +enum nrf_wifi_fw_subtype { + NRF_WIFI_FW_SUBTYPE_PRI, + NRF_WIFI_FW_SUBTYPE_SEC, + NRF_WIFI_FW_SUBTYPE_MAX +}; + +bool pal_check_rpu_mcu_regions(enum RPU_PROC_TYPE proc, unsigned int addr_val); + +static inline enum RPU_MCU_ADDR_REGIONS pal_mem_type_to_region(enum HAL_RPU_MEM_TYPE mem_type) +{ + switch (mem_type) { + case HAL_RPU_MEM_TYPE_CORE_ROM: + return RPU_MCU_ADDR_REGION_ROM; + case HAL_RPU_MEM_TYPE_CORE_RET: + return RPU_MCU_ADDR_REGION_RETENTION; + case HAL_RPU_MEM_TYPE_CORE_SCRATCH: + return RPU_MCU_ADDR_REGION_SCRATCH; + default: + return RPU_MCU_ADDR_REGION_MAX; + } +} + +enum nrf_wifi_status pal_rpu_addr_offset_get(struct nrf_wifi_osal_priv *opriv, + unsigned int rpu_addr, + unsigned long *addr_offset, + enum RPU_PROC_TYPE proc); + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +unsigned long pal_rpu_ps_ctrl_reg_addr_get(void); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + +char *pal_ops_get_fw_loc(struct nrf_wifi_osal_priv *opriv, + enum nrf_wifi_fw_type fw_type, + enum nrf_wifi_fw_subtype fw_subtype); + +#endif /* __PAL_H__ */ diff --git a/nrf_wifi/hw_if/hal/src/hal_api.c b/nrf_wifi/hw_if/hal/src/hal_api.c new file mode 100644 index 0000000000..e2cf72fa51 --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/hal_api.c @@ -0,0 +1,1732 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing API definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "queue.h" +#include "hal_structs.h" +#include "hal_common.h" +#include "hal_reg.h" +#include "hal_mem.h" +#include "hal_interrupt.h" +#include "pal.h" + +#ifndef CONFIG_NRF700X_RADIO_TEST +static enum nrf_wifi_status +nrf_wifi_hal_rpu_pktram_buf_map_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int pool_idx = 0; + + status = pal_rpu_addr_offset_get(hal_dev_ctx->hpriv->opriv, + RPU_MEM_PKT_BASE, + &hal_dev_ctx->addr_rpu_pktram_base, + hal_dev_ctx->curr_proc); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: pal_rpu_addr_offset_get failed\n", + __func__); + goto out; + } + + hal_dev_ctx->addr_rpu_pktram_base_tx = hal_dev_ctx->addr_rpu_pktram_base; + + hal_dev_ctx->addr_rpu_pktram_base_rx_pool[0] = + (hal_dev_ctx->addr_rpu_pktram_base + RPU_PKTRAM_SIZE) - + (CONFIG_NRF700X_RX_NUM_BUFS * CONFIG_NRF700X_RX_MAX_DATA_SIZE); + + for (pool_idx = 1; pool_idx < MAX_NUM_OF_RX_QUEUES; pool_idx++) { + hal_dev_ctx->addr_rpu_pktram_base_rx_pool[pool_idx] = + hal_dev_ctx->addr_rpu_pktram_base_rx_pool[pool_idx - 1] + + (hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[pool_idx - 1].num_bufs * + hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[pool_idx - 1].buf_sz); + } + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +unsigned long nrf_wifi_hal_buf_map_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned long buf, + unsigned int buf_len, + unsigned int pool_id, + unsigned int buf_id) +{ + struct nrf_wifi_hal_buf_map_info *rx_buf_info = NULL; + unsigned long addr_to_map = 0; + unsigned long bounce_buf_addr = 0; + unsigned long rpu_addr = 0; + + rx_buf_info = &hal_dev_ctx->rx_buf_info[pool_id][buf_id]; + + if (rx_buf_info->mapped) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Called for already mapped RX buffer\n", + __func__); + goto out; + } + + rx_buf_info->virt_addr = buf; + rx_buf_info->buf_len = buf_len; + + if (buf_len != hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[pool_id].buf_sz) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid buf_len (%d) for pool_id (%d)\n", + __func__, + buf_len, + pool_id); + goto out; + } + + bounce_buf_addr = hal_dev_ctx->addr_rpu_pktram_base_rx_pool[pool_id] + + (buf_id * buf_len); + + rpu_addr = RPU_MEM_PKT_BASE + (bounce_buf_addr - hal_dev_ctx->addr_rpu_pktram_base); + + hal_rpu_mem_write(hal_dev_ctx, + (unsigned int)rpu_addr, + (void *)buf, + hal_dev_ctx->hpriv->cfg_params.rx_buf_headroom_sz); + + addr_to_map = bounce_buf_addr + hal_dev_ctx->hpriv->cfg_params.rx_buf_headroom_sz; + + rx_buf_info->phy_addr = nrf_wifi_bal_dma_map(hal_dev_ctx->bal_dev_ctx, + addr_to_map, + buf_len, + NRF_WIFI_OSAL_DMA_DIR_FROM_DEV); + + if (!rx_buf_info->phy_addr) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: DMA map failed\n", + __func__); + goto out; + } + +out: + if (rx_buf_info->phy_addr) { + rx_buf_info->mapped = true; + } + + return rx_buf_info->phy_addr; +} + + +unsigned long nrf_wifi_hal_buf_unmap_rx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int data_len, + unsigned int pool_id, + unsigned int buf_id) +{ + struct nrf_wifi_hal_buf_map_info *rx_buf_info = NULL; + unsigned long unmapped_addr = 0; + unsigned long virt_addr = 0; + unsigned long rpu_addr = 0; + + rx_buf_info = &hal_dev_ctx->rx_buf_info[pool_id][buf_id]; + + if (!rx_buf_info->mapped) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Called for unmapped RX buffer\n", + __func__); + goto out; + } + + unmapped_addr = nrf_wifi_bal_dma_unmap(hal_dev_ctx->bal_dev_ctx, + rx_buf_info->phy_addr, + rx_buf_info->buf_len, + NRF_WIFI_OSAL_DMA_DIR_FROM_DEV); + + rpu_addr = RPU_MEM_PKT_BASE + (unmapped_addr - hal_dev_ctx->addr_rpu_pktram_base); + + if (data_len) { + if (!unmapped_addr) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: DMA unmap failed\n", + __func__); + goto out; + } + + hal_rpu_mem_read(hal_dev_ctx, + (void *)(rx_buf_info->virt_addr + + hal_dev_ctx->hpriv->cfg_params.rx_buf_headroom_sz), + (unsigned int)rpu_addr, + data_len); + } + + virt_addr = rx_buf_info->virt_addr; + + nrf_wifi_osal_mem_set(hal_dev_ctx->hpriv->opriv, + rx_buf_info, + 0, + sizeof(*rx_buf_info)); +out: + return virt_addr; +} + + +unsigned long nrf_wifi_hal_buf_map_tx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned long buf, + unsigned int buf_len, + unsigned int desc_id, + unsigned int token, + unsigned int buf_indx) +{ + struct nrf_wifi_hal_buf_map_info *tx_buf_info = NULL; + unsigned long addr_to_map = 0; + unsigned long bounce_buf_addr = 0; + unsigned long tx_token_base_addr = hal_dev_ctx->addr_rpu_pktram_base_tx + + (token * hal_dev_ctx->hpriv->cfg_params.max_ampdu_len_per_token); + unsigned long rpu_addr = 0; + + tx_buf_info = &hal_dev_ctx->tx_buf_info[desc_id]; + + if (tx_buf_info->mapped) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Called for already mapped TX buffer\n", + __func__); + goto out; + } + + tx_buf_info->virt_addr = buf; + + if (buf_len > (hal_dev_ctx->hpriv->cfg_params.max_tx_frm_sz - + hal_dev_ctx->hpriv->cfg_params.tx_buf_headroom_sz)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid TX buf_len (%d) for (%d)\n", + __func__, + buf_len, + desc_id); + goto out; + } + + if (buf_indx == 0) { + hal_dev_ctx->tx_frame_offset = tx_token_base_addr; + } + + bounce_buf_addr = hal_dev_ctx->tx_frame_offset; + + /* Align bounce buffer and buffer length to 4-byte boundary */ + bounce_buf_addr = (bounce_buf_addr + 3) & ~3; + buf_len = (buf_len + 3) & ~3; + + hal_dev_ctx->tx_frame_offset += (bounce_buf_addr - hal_dev_ctx->tx_frame_offset) + + buf_len + hal_dev_ctx->hpriv->cfg_params.tx_buf_headroom_sz; + + rpu_addr = RPU_MEM_PKT_BASE + (bounce_buf_addr - hal_dev_ctx->addr_rpu_pktram_base); + + nrf_wifi_osal_log_dbg(hal_dev_ctx->hpriv->opriv, + "%s: bounce_buf_addr: 0x%lx, rpu_addr: 0x%lx, buf_len: %d off:%d\n", + __func__, + bounce_buf_addr, + rpu_addr, + buf_len, + hal_dev_ctx->tx_frame_offset); + + hal_rpu_mem_write(hal_dev_ctx, + (unsigned int)rpu_addr, + (void *)buf, + buf_len); + + addr_to_map = bounce_buf_addr; + + tx_buf_info->phy_addr = nrf_wifi_bal_dma_map(hal_dev_ctx->bal_dev_ctx, + addr_to_map, + buf_len, + NRF_WIFI_OSAL_DMA_DIR_TO_DEV); + + if (!tx_buf_info->phy_addr) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: DMA map failed\n", + __func__); + goto out; + } + tx_buf_info->buf_len = buf_len; + +out: + if (tx_buf_info->phy_addr) { + tx_buf_info->mapped = true; + } + + return tx_buf_info->phy_addr; +} + + +unsigned long nrf_wifi_hal_buf_unmap_tx(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int desc_id) +{ + struct nrf_wifi_hal_buf_map_info *tx_buf_info = NULL; + unsigned long unmapped_addr = 0; + unsigned long virt_addr = 0; + + tx_buf_info = &hal_dev_ctx->tx_buf_info[desc_id]; + + if (!tx_buf_info->mapped) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Called for unmapped TX buffer\n", + __func__); + goto out; + } + + unmapped_addr = nrf_wifi_bal_dma_unmap(hal_dev_ctx->bal_dev_ctx, + tx_buf_info->phy_addr, + tx_buf_info->buf_len, + NRF_WIFI_OSAL_DMA_DIR_TO_DEV); + + if (!unmapped_addr) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: DMA unmap failed\n", + __func__); + goto out; + } + + virt_addr = tx_buf_info->virt_addr; + + nrf_wifi_osal_mem_set(hal_dev_ctx->hpriv->opriv, + tx_buf_info, + 0, + sizeof(*tx_buf_info)); +out: + return virt_addr; +} +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +enum nrf_wifi_status hal_rpu_ps_wake(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + unsigned int reg_val = 0; + unsigned int rpu_ps_state_mask = 0; + unsigned long start_time_us = 0; + unsigned long idle_time_start_us = 0; + unsigned long idle_time_us = 0; + unsigned long elapsed_time_sec = 0; + unsigned long elapsed_time_usec = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!hal_dev_ctx) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid parameters\n", + __func__); + return status; + } + + + /* If the FW is not yet booted up (e.g. during the FW load stage of Host FW load) + * then skip the RPU wake attempt since RPU sleep/wake kicks in only after FW boot + */ + if (!hal_dev_ctx->rpu_fw_booted) + return NRF_WIFI_STATUS_SUCCESS; + + if (hal_dev_ctx->rpu_ps_state == RPU_PS_STATE_AWAKE) { + status = NRF_WIFI_STATUS_SUCCESS; + + goto out; + } + + nrf_wifi_bal_rpu_ps_wake(hal_dev_ctx->bal_dev_ctx); + + start_time_us = nrf_wifi_osal_time_get_curr_us(hal_dev_ctx->hpriv->opriv); + + rpu_ps_state_mask = ((1 << RPU_REG_BIT_PS_STATE) | + (1 << RPU_REG_BIT_READY_STATE)); + + /* Add a delay to avoid a race condition in the RPU */ + /* TODO: Reduce to 200 us after sleep has been stabilized */ + nrf_wifi_osal_delay_us(hal_dev_ctx->hpriv->opriv, + 1000); + + do { + /* Poll the RPU PS state */ + reg_val = nrf_wifi_bal_rpu_ps_status(hal_dev_ctx->bal_dev_ctx); + + if ((reg_val & rpu_ps_state_mask) == rpu_ps_state_mask) { + status = NRF_WIFI_STATUS_SUCCESS; + break; + } + + idle_time_start_us = nrf_wifi_osal_time_get_curr_us(hal_dev_ctx->hpriv->opriv); + + do { + idle_time_us = nrf_wifi_osal_time_elapsed_us(hal_dev_ctx->hpriv->opriv, + idle_time_start_us); + } while ((idle_time_us / 1000) < RPU_PS_WAKE_INTERVAL_MS); + + elapsed_time_usec = nrf_wifi_osal_time_elapsed_us(hal_dev_ctx->hpriv->opriv, + start_time_us); + elapsed_time_sec = (elapsed_time_usec / 1000000); + } while (elapsed_time_sec < RPU_PS_WAKE_TIMEOUT_S); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: RPU is not ready for more than %d sec," + "reg_val = 0x%X rpu_ps_state_mask = 0x%X\n", + __func__, + RPU_PS_WAKE_TIMEOUT_S, + reg_val, + rpu_ps_state_mask); + goto out; + } + hal_dev_ctx->rpu_ps_state = RPU_PS_STATE_AWAKE; + +out: + if (!hal_dev_ctx->irq_ctx) { + nrf_wifi_osal_timer_schedule(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_timer, + CONFIG_NRF700X_RPU_PS_IDLE_TIMEOUT_MS); + } + return status; +} + + +static void hal_rpu_ps_sleep(unsigned long data) +{ + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL; + unsigned long flags = 0; + + hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data; + + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); + + nrf_wifi_bal_rpu_ps_sleep(hal_dev_ctx->bal_dev_ctx); + + hal_dev_ctx->rpu_ps_state = RPU_PS_STATE_ASLEEP; + + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); +} + + +static enum nrf_wifi_status hal_rpu_ps_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + hal_dev_ctx->rpu_ps_lock = nrf_wifi_osal_spinlock_alloc(hal_dev_ctx->hpriv->opriv); + + if (!hal_dev_ctx->rpu_ps_lock) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to allocate lock\n", + __func__); + goto out; + } + + nrf_wifi_osal_spinlock_init(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock); + + hal_dev_ctx->rpu_ps_timer = nrf_wifi_osal_timer_alloc(hal_dev_ctx->hpriv->opriv); + + if (!hal_dev_ctx->rpu_ps_timer) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to allocate timer\n", + __func__); + nrf_wifi_osal_spinlock_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock); + goto out; + } + + nrf_wifi_osal_timer_init(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_timer, + hal_rpu_ps_sleep, + (unsigned long)hal_dev_ctx); + + hal_dev_ctx->rpu_ps_state = RPU_PS_STATE_ASLEEP; + hal_dev_ctx->dbg_enable = true; + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +static void hal_rpu_ps_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + nrf_wifi_osal_timer_kill(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_timer); + + nrf_wifi_osal_timer_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_timer); + + nrf_wifi_osal_spinlock_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock); +} + + +static void hal_rpu_ps_set_state(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PS_STATE ps_state) +{ + hal_dev_ctx->rpu_ps_state = ps_state; +} + +enum nrf_wifi_status nrf_wifi_hal_get_rpu_ps_state( + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + int *rpu_ps_ctrl_state) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!hal_dev_ctx) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + *rpu_ps_ctrl_state = hal_dev_ctx->rpu_ps_state; + + return NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + +static bool hal_rpu_hpq_is_empty(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + struct host_rpu_hpq *hpq) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + + status = hal_rpu_reg_read(hal_dev_ctx, + &val, + hpq->dequeue_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Read from dequeue address failed, val (0x%X)\n", + __func__, + val); + return true; + } + + if (val) { + return false; + } + + return true; +} + + +static enum nrf_wifi_status hal_rpu_ready(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum NRF_WIFI_HAL_MSG_TYPE msg_type) +{ + bool is_empty = false; + struct host_rpu_hpq *avl_buf_q = NULL; + + if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) { + avl_buf_q = &hal_dev_ctx->rpu_info.hpqm_info.cmd_avl_queue; + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid msg type %d\n", + __func__, + msg_type); + + return NRF_WIFI_STATUS_FAIL; + } + + /* Check if any command pointers are available to post a message */ + is_empty = hal_rpu_hpq_is_empty(hal_dev_ctx, + avl_buf_q); + + if (is_empty == true) { + return NRF_WIFI_STATUS_FAIL; + } + + return NRF_WIFI_STATUS_SUCCESS; +} + + +static enum nrf_wifi_status hal_rpu_ready_wait(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum NRF_WIFI_HAL_MSG_TYPE msg_type) +{ + unsigned long start_time_us = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + start_time_us = nrf_wifi_osal_time_get_curr_us(hal_dev_ctx->hpriv->opriv); + + while (hal_rpu_ready(hal_dev_ctx, msg_type) != NRF_WIFI_STATUS_SUCCESS) { + if (nrf_wifi_osal_time_elapsed_us(hal_dev_ctx->hpriv->opriv, + start_time_us) >= MAX_HAL_RPU_READY_WAIT) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Timed out waiting (msg_type = %d)\n", + __func__, + msg_type); + goto out; + } + } + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_msg_trigger(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_INT_TO_MCU_CTRL, + (hal_dev_ctx->num_cmds | 0x7fff0000)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to MCU cmd register failed\n", + __func__); + goto out; + } + + hal_dev_ctx->num_cmds++; +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_msg_post(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum NRF_WIFI_HAL_MSG_TYPE msg_type, + unsigned int queue_id, + unsigned int msg_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_hpq *busy_queue = NULL; + + if (queue_id >= MAX_NUM_OF_RX_QUEUES) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid queue_id (%d)\n", + __func__, + queue_id); + goto out; + } + + if ((msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) || + (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX)) { + busy_queue = &hal_dev_ctx->rpu_info.hpqm_info.cmd_busy_queue; + } else if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) { + busy_queue = &hal_dev_ctx->rpu_info.hpqm_info.rx_buf_busy_queue[queue_id]; + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid msg_type (%d)\n", + __func__, + msg_type); + goto out; + } + + /* Copy the address, to which information was posted, + * to the busy queue. + */ + status = hal_rpu_hpq_enqueue(hal_dev_ctx, + busy_queue, + msg_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Queueing of message to RPU failed\n", + __func__); + goto out; + } + + if (msg_type != NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) { + /* Indicate to the RPU that the information has been posted */ + status = hal_rpu_msg_trigger(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Posting command to RPU failed\n", + __func__); + goto out; + } + } +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_msg_get_addr(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum NRF_WIFI_HAL_MSG_TYPE msg_type, + unsigned int *msg_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct host_rpu_hpq *avl_queue = NULL; + + if (msg_type == NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL) { + avl_queue = &hal_dev_ctx->rpu_info.hpqm_info.cmd_avl_queue; + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid msg_type (%d)\n", + __func__, + msg_type); + goto out; + } + + status = hal_rpu_hpq_dequeue(hal_dev_ctx, + avl_queue, + msg_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Dequeue of address failed msg_addr 0x%X\n", + __func__, + *msg_addr); + *msg_addr = 0; + goto out; + } +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_msg_write(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum NRF_WIFI_HAL_MSG_TYPE msg_type, + void *msg, + unsigned int len) +{ + unsigned int msg_addr = 0; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + /* Get the address from the RPU to which + * the command needs to be copied to + */ + status = hal_rpu_msg_get_addr(hal_dev_ctx, + msg_type, + &msg_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Getting address (0x%X) to post message failed\n", + __func__, + msg_addr); + goto out; + } + + /* Copy the information to the suggested address */ + status = hal_rpu_mem_write(hal_dev_ctx, + msg_addr, + msg, + len); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Copying information to RPU failed\n", + __func__); + goto out; + } + + /* Post the updated information to the RPU */ + status = hal_rpu_msg_post(hal_dev_ctx, + msg_type, + 0, + msg_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Posting command to RPU failed\n", + __func__); + goto out; + } + +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_cmd_process_queue(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_hal_msg *cmd = NULL; + + while ((cmd = nrf_wifi_utils_q_dequeue(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->cmd_q))) { + status = hal_rpu_ready_wait(hal_dev_ctx, + NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Timeout waiting to get free cmd buff from RPU\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + cmd); + cmd = NULL; + continue; + } + + status = hal_rpu_msg_write(hal_dev_ctx, + NRF_WIFI_HAL_MSG_TYPE_CMD_CTRL, + cmd->data, + cmd->len); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing command to RPU failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + cmd); + cmd = NULL; + continue; + } + + /* Free the command data and command */ + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + cmd); + cmd = NULL; + } + + return status; +} + + +static enum nrf_wifi_status hal_rpu_cmd_queue(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + void *cmd, + unsigned int cmd_size) +{ + int len = 0; + int size = 0; + char *data = NULL; + struct nrf_wifi_hal_msg *hal_msg = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + len = cmd_size; + data = cmd; + + if (len > hal_dev_ctx->hpriv->cfg_params.max_cmd_size) { + while (len > 0) { + if (len > hal_dev_ctx->hpriv->cfg_params.max_cmd_size) { + size = hal_dev_ctx->hpriv->cfg_params.max_cmd_size; + } else { + size = len; + } + + hal_msg = nrf_wifi_osal_mem_zalloc(hal_dev_ctx->hpriv->opriv, + sizeof(*hal_msg) + size); + + if (!hal_msg) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to alloc buff for frag HAL cmd\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nrf_wifi_osal_mem_cpy(hal_dev_ctx->hpriv->opriv, + hal_msg->data, + data, + size); + + hal_msg->len = size; + + status = nrf_wifi_utils_q_enqueue(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->cmd_q, + hal_msg); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to queue frag HAL cmd\n", + __func__); + goto out; + } + + len -= size; + data += size; + } + } else { + hal_msg = nrf_wifi_osal_mem_zalloc(hal_dev_ctx->hpriv->opriv, + sizeof(*hal_msg) + len); + + if (!hal_msg) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to allocate buffer for HAL command\n", + __func__); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nrf_wifi_osal_mem_cpy(hal_dev_ctx->hpriv->opriv, + hal_msg->data, + cmd, + len); + + hal_msg->len = len; + + status = nrf_wifi_utils_q_enqueue(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->cmd_q, + hal_msg); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to queue fragmented command\n", + __func__); + goto out; + } + } + + /* Free the original command data */ + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + cmd); + +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_hal_ctrl_cmd_send(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + void *cmd, + unsigned int cmd_size) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + nrf_wifi_osal_spinlock_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_hal); + + status = hal_rpu_cmd_queue(hal_dev_ctx, + cmd, + cmd_size); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Queueing of command failed\n", + __func__); + goto out; + } + + status = hal_rpu_cmd_process_queue(hal_dev_ctx); + +out: + nrf_wifi_osal_spinlock_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_hal); + + return status; +} + + +enum nrf_wifi_status nrf_wifi_hal_data_cmd_send(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum NRF_WIFI_HAL_MSG_TYPE cmd_type, + void *cmd, + unsigned int cmd_size, + unsigned int desc_id, + unsigned int pool_id) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int addr_base = 0; + unsigned int max_cmd_size = 0; + unsigned int addr = 0; + unsigned int host_addr = 0; + + + nrf_wifi_osal_spinlock_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_hal); + + if (cmd_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) { + addr_base = hal_dev_ctx->rpu_info.rx_cmd_base; + max_cmd_size = RPU_DATA_CMD_SIZE_MAX_RX; + } else if (cmd_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_TX) { + addr_base = hal_dev_ctx->rpu_info.tx_cmd_base; + max_cmd_size = RPU_DATA_CMD_SIZE_MAX_TX; + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid data command type %d\n", + __func__, + cmd_type); + } + + addr = addr_base + (max_cmd_size * desc_id); + host_addr = addr; + + /* This is a indrect write to core memory */ + if (cmd_type == NRF_WIFI_HAL_MSG_TYPE_CMD_DATA_RX) { + host_addr &= RPU_ADDR_MASK_OFFSET; + host_addr |= RPU_MCU_CORE_INDIRECT_BASE; + } + + /* Copy the information to the suggested address */ + status = hal_rpu_mem_write(hal_dev_ctx, + host_addr, + cmd, + cmd_size); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Copying data cmd(%d) to RPU failed\n", + __func__, + cmd_type); + goto out; + } + + /* Post the updated information to the RPU */ + status = hal_rpu_msg_post(hal_dev_ctx, + cmd_type, + pool_id, + addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Posting RX buf info to RPU failed\n", + __func__); + goto out; + } +out: + nrf_wifi_osal_spinlock_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_hal); + + + return status; +} + + +static void event_tasklet_fn(unsigned long data) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL; + + hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data; + + status = hal_rpu_eventq_process(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Event queue processing failed\n", + __func__); + } +} + + +enum nrf_wifi_status hal_rpu_eventq_process(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_SUCCESS; + struct nrf_wifi_hal_msg *event = NULL; + unsigned long flags = 0; + void *event_data = NULL; + unsigned int event_len = 0; + + while (1) { + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_rx, + &flags); + + event = nrf_wifi_utils_q_dequeue(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_q); + + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_rx, + &flags); + + if (!event) { + goto out; + } + + event_data = event->data; + event_len = event->len; + + /* Process the event further */ + status = hal_dev_ctx->hpriv->intr_callbk_fn(hal_dev_ctx->mac_dev_ctx, + event_data, + event_len); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Interrupt callback failed\n", + __func__); + } + + /* Free up the local buffer */ + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + event); + event = NULL; + } + +out: + return status; +} + + +void nrf_wifi_hal_proc_ctx_set(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE proc) +{ + hal_dev_ctx->curr_proc = proc; +} + + +struct nrf_wifi_hal_dev_ctx *nrf_wifi_hal_dev_add(struct nrf_wifi_hal_priv *hpriv, + void *mac_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL; +#ifndef CONFIG_NRF700X_RADIO_TEST + unsigned int i = 0; + unsigned int num_rx_bufs = 0; + unsigned int size = 0; +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + + hal_dev_ctx = nrf_wifi_osal_mem_zalloc(hpriv->opriv, + sizeof(*hal_dev_ctx)); + + if (!hal_dev_ctx) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Unable to allocate hal_dev_ctx\n", + __func__); + goto err; + } + + hal_dev_ctx->hpriv = hpriv; + hal_dev_ctx->mac_dev_ctx = mac_dev_ctx; + hal_dev_ctx->idx = hpriv->num_devs++; + + hal_dev_ctx->num_cmds = RPU_CMD_START_MAGIC; + + hal_dev_ctx->cmd_q = nrf_wifi_utils_q_alloc(hpriv->opriv); + + if (!hal_dev_ctx->cmd_q) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Unable to allocate command queue\n", + __func__); + goto hal_dev_free; + } + + hal_dev_ctx->event_q = nrf_wifi_utils_q_alloc(hpriv->opriv); + + if (!hal_dev_ctx->event_q) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Unable to allocate event queue\n", + __func__); + goto cmd_q_free; + } + + hal_dev_ctx->lock_hal = nrf_wifi_osal_spinlock_alloc(hpriv->opriv); + + if (!hal_dev_ctx->lock_hal) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Unable to allocate HAL lock\n", __func__); + hal_dev_ctx = NULL; + goto event_q_free; + } + + nrf_wifi_osal_spinlock_init(hpriv->opriv, + hal_dev_ctx->lock_hal); + + hal_dev_ctx->lock_rx = nrf_wifi_osal_spinlock_alloc(hpriv->opriv); + + if (!hal_dev_ctx->lock_rx) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Unable to allocate HAL lock\n", + __func__); + goto lock_hal_free; + } + + nrf_wifi_osal_spinlock_init(hpriv->opriv, + hal_dev_ctx->lock_rx); + + hal_dev_ctx->event_tasklet = nrf_wifi_osal_tasklet_alloc(hpriv->opriv, + NRF_WIFI_TASKLET_TYPE_BH); + + if (!hal_dev_ctx->event_tasklet) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Unable to allocate event_tasklet\n", + __func__); + goto lock_rx_free; + } + + nrf_wifi_osal_tasklet_init(hpriv->opriv, + hal_dev_ctx->event_tasklet, + event_tasklet_fn, + (unsigned long)hal_dev_ctx); + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + status = hal_rpu_ps_init(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: hal_rpu_ps_init failed\n", + __func__); + goto tasklet_free; + } +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + hal_dev_ctx->bal_dev_ctx = nrf_wifi_bal_dev_add(hpriv->bpriv, + hal_dev_ctx); + + if (!hal_dev_ctx->bal_dev_ctx) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: nrf_wifi_bal_dev_add failed\n", + __func__); + goto tasklet_free; + } + + status = hal_rpu_irq_enable(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: hal_rpu_irq_enable failed\n", + __func__); + goto bal_dev_free; + } + +#ifndef CONFIG_NRF700X_RADIO_TEST + for (i = 0; i < MAX_NUM_OF_RX_QUEUES; i++) { + num_rx_bufs = hal_dev_ctx->hpriv->cfg_params.rx_buf_pool[i].num_bufs; + + size = (num_rx_bufs * sizeof(struct nrf_wifi_hal_buf_map_info)); + + hal_dev_ctx->rx_buf_info[i] = nrf_wifi_osal_mem_zalloc(hpriv->opriv, + size); + + if (!hal_dev_ctx->rx_buf_info[i]) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: No space for RX buf info[%d]\n", + __func__, + i); + goto bal_dev_free; + } + } +#ifdef CONFIG_NRF700X_DATA_TX + size = (hal_dev_ctx->hpriv->cfg_params.max_tx_frms * + sizeof(struct nrf_wifi_hal_buf_map_info)); + + hal_dev_ctx->tx_buf_info = nrf_wifi_osal_mem_zalloc(hpriv->opriv, + size); + + if (!hal_dev_ctx->tx_buf_info) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: No space for TX buf info\n", + __func__); + goto rx_buf_free; + } +#endif /* CONFIG_NRF700X_DATA_TX */ + + status = nrf_wifi_hal_rpu_pktram_buf_map_init(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hpriv->opriv, + "%s: Buffer map init failed\n", + __func__); +#ifdef CONFIG_NRF700X_DATA_TX + goto tx_buf_free; +#endif /* CONFIG_NRF700X_DATA_TX */ + } +#endif /* !CONFIG_NRF700X_RADIO_TEST */ + + return hal_dev_ctx; +#ifndef CONFIG_NRF700X_RADIO_TEST +#ifdef CONFIG_NRF700X_DATA_TX +tx_buf_free: + nrf_wifi_osal_mem_free(hpriv->opriv, + hal_dev_ctx->tx_buf_info); + hal_dev_ctx->tx_buf_info = NULL; +rx_buf_free: + + for (i = 0; i < MAX_NUM_OF_RX_QUEUES; i++) { + nrf_wifi_osal_mem_free(hpriv->opriv, + hal_dev_ctx->rx_buf_info[i]); + hal_dev_ctx->rx_buf_info[i] = NULL; + } +#endif /* CONFIG_NRF700X_DATA_TX */ +#endif /* !CONFIG_NRF700X_RADIO_TEST */ +bal_dev_free: + nrf_wifi_bal_dev_rem(hal_dev_ctx->bal_dev_ctx); +tasklet_free: + nrf_wifi_osal_tasklet_free(hpriv->opriv, + hal_dev_ctx->event_tasklet); +lock_rx_free: + nrf_wifi_osal_spinlock_free(hpriv->opriv, + hal_dev_ctx->lock_rx); +lock_hal_free: + nrf_wifi_osal_spinlock_free(hpriv->opriv, + hal_dev_ctx->lock_hal); +event_q_free: + nrf_wifi_utils_q_free(hpriv->opriv, + hal_dev_ctx->event_q); +cmd_q_free: + nrf_wifi_utils_q_free(hpriv->opriv, + hal_dev_ctx->cmd_q); +hal_dev_free: + nrf_wifi_osal_mem_free(hpriv->opriv, + hal_dev_ctx); + hal_dev_ctx = NULL; +err: + return NULL; +} + + +void nrf_wifi_hal_dev_rem(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + unsigned int i = 0; + + + nrf_wifi_bal_dev_rem(hal_dev_ctx->bal_dev_ctx); + + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->tx_buf_info); + hal_dev_ctx->tx_buf_info = NULL; + + for (i = 0; i < MAX_NUM_OF_RX_QUEUES; i++) { + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rx_buf_info[i]); + hal_dev_ctx->rx_buf_info[i] = NULL; + } + + nrf_wifi_osal_tasklet_kill(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_tasklet); + + nrf_wifi_osal_tasklet_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_tasklet); + + nrf_wifi_osal_spinlock_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_hal); + nrf_wifi_osal_spinlock_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_rx); + + nrf_wifi_utils_q_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_q); + + nrf_wifi_utils_q_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->cmd_q); + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + hal_rpu_ps_deinit(hal_dev_ctx); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + hal_dev_ctx->hpriv->num_devs--; + + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_hal_dev_init(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + hal_dev_ctx->rpu_fw_booted = true; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + status = nrf_wifi_bal_dev_init(hal_dev_ctx->bal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: nrf_wifi_bal_dev_init failed\n", + __func__); + goto out; + } + + /* Read the HPQM info for all the queues provided by the RPU + * (like command, event, RX buf queues etc) + */ + status = hal_rpu_mem_read(hal_dev_ctx, + &hal_dev_ctx->rpu_info.hpqm_info, + RPU_MEM_HPQ_INFO, + sizeof(hal_dev_ctx->rpu_info.hpqm_info)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Failed to get the HPQ info\n", + __func__); + goto out; + } + + status = hal_rpu_mem_read(hal_dev_ctx, + &hal_dev_ctx->rpu_info.rx_cmd_base, + RPU_MEM_RX_CMD_BASE, + sizeof(hal_dev_ctx->rpu_info.rx_cmd_base)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading the RX cmd base failed\n", + __func__); + goto out; + } + + hal_dev_ctx->rpu_info.tx_cmd_base = RPU_MEM_TX_CMD_BASE; +out: + return status; +} + + +void nrf_wifi_hal_dev_deinit(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + nrf_wifi_bal_dev_deinit(hal_dev_ctx->bal_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_hal_irq_handler(void *data) +{ + struct nrf_wifi_hal_dev_ctx *hal_dev_ctx = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned long flags = 0; +#ifdef CONFIG_NRF_WIFI_LOW_POWER + enum RPU_PS_STATE ps_state = RPU_PS_STATE_ASLEEP; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + hal_dev_ctx = (struct nrf_wifi_hal_dev_ctx *)data; + + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_rx, + &flags); + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + ps_state = hal_dev_ctx->rpu_ps_state; + hal_rpu_ps_set_state(hal_dev_ctx, + RPU_PS_STATE_AWAKE); +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG + hal_dev_ctx->irq_ctx = true; +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + status = hal_rpu_irq_process(hal_dev_ctx); + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + hal_rpu_ps_set_state(hal_dev_ctx, + ps_state); +#ifdef CONFIG_NRF_WIFI_LOW_POWER_DBG + hal_dev_ctx->irq_ctx = false; +#endif /* CONFIG_NRF_WIFI_LOW_POWER_DBG */ +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->lock_rx, + &flags); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + goto out; + } + + nrf_wifi_osal_tasklet_schedule(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_tasklet); + +out: + return status; +} + + +static int nrf_wifi_hal_poll_reg(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int reg_addr, + unsigned int mask, + unsigned int req_value, + unsigned int poll_delay) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + unsigned int count = 50; + + do { + status = hal_rpu_reg_read(hal_dev_ctx, + &val, + reg_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Read from address (0x%X) failed, val (0x%X)\n", + __func__, + reg_addr, + val); + } + + if ((val & mask) == req_value) { + status = NRF_WIFI_STATUS_SUCCESS; + break; + } + + nrf_wifi_osal_sleep_ms(hal_dev_ctx->hpriv->opriv, + poll_delay); + } while (count-- > 0); + + if (count == 0) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Timed out polling on (0x%X)\n", + __func__, + reg_addr); + + status = NRF_WIFI_STATUS_FAIL; + goto out; + } +out: + return status; +} + + +/* Perform MIPS reset */ +enum nrf_wifi_status nrf_wifi_hal_proc_reset(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if ((rpu_proc != RPU_PROC_TYPE_MCU_LMAC) && + (rpu_proc != RPU_PROC_TYPE_MCU_UMAC)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unsupported RPU processor(%d)\n", + __func__, + rpu_proc); + goto out; + } + + /* Perform pulsed soft reset of MIPS */ + if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) { + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_MIPS_MCU_CONTROL, + 0x1); + } else { + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_MIPS_MCU2_CONTROL, + 0x1); + } + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Pulsed soft reset of MCU failed for (%d) processor\n", + __func__, + rpu_proc); + goto out; + } + + + /* Wait for it to come out of reset */ + if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) { + status = nrf_wifi_hal_poll_reg(hal_dev_ctx, + RPU_REG_MIPS_MCU_CONTROL, + 0x1, + 0, + 10); + } else { + status = nrf_wifi_hal_poll_reg(hal_dev_ctx, + RPU_REG_MIPS_MCU2_CONTROL, + 0x1, + 0, + 10); + } + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: MCU (%d) failed to come out of reset\n", + __func__, + rpu_proc); + goto out; + } + + /* MIPS will restart from it's boot exception registers + * and hit its default wait instruction + */ + if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) { + status = nrf_wifi_hal_poll_reg(hal_dev_ctx, + 0xA4000018, + 0x1, + 0x1, + 10); + } else { + status = nrf_wifi_hal_poll_reg(hal_dev_ctx, + 0xA4000118, + 0x1, + 0x1, + 10); + } +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_hal_fw_chk_boot(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int addr = 0; + unsigned int val = 0; + unsigned int exp_val = 0; + unsigned int i = 0; + + if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) { + addr = RPU_MEM_LMAC_BOOT_SIG; + exp_val = NRF_WIFI_LMAC_BOOT_SIG; + } else if (rpu_proc == RPU_PROC_TYPE_MCU_UMAC) { + addr = RPU_MEM_UMAC_BOOT_SIG; + exp_val = NRF_WIFI_UMAC_BOOT_SIG; + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid RPU processor (%d)\n", + __func__, + rpu_proc); + } + + while (i < 1000) { + status = hal_rpu_mem_read(hal_dev_ctx, + (unsigned char *)&val, + addr, + sizeof(val)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading of boot signature failed for RPU(%d)\n", + __func__, + rpu_proc); + } + + if (val == exp_val) { + break; + } + + /* Sleep for 10 ms */ + nrf_wifi_osal_sleep_ms(hal_dev_ctx->hpriv->opriv, + 10); + + i++; + + }; + + if (i == 1000) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Boot_sig check failed for RPU(%d), " + "Expected: 0x%X, Actual: 0x%X\n", + __func__, + rpu_proc, + exp_val, + val); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + +struct nrf_wifi_hal_priv * +nrf_wifi_hal_init(struct nrf_wifi_osal_priv *opriv, + struct nrf_wifi_hal_cfg_params *cfg_params, + enum nrf_wifi_status (*intr_callbk_fn)(void *dev_ctx, + void *event_data, + unsigned int len)) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_hal_priv *hpriv = NULL; + struct nrf_wifi_bal_cfg_params bal_cfg_params; + + hpriv = nrf_wifi_osal_mem_zalloc(opriv, + sizeof(*hpriv)); + + if (!hpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate memory for hpriv\n", + __func__); + goto out; + } + + hpriv->opriv = opriv; + + nrf_wifi_osal_mem_cpy(opriv, + &hpriv->cfg_params, + cfg_params, + sizeof(hpriv->cfg_params)); + + hpriv->intr_callbk_fn = intr_callbk_fn; + + status = pal_rpu_addr_offset_get(opriv, + RPU_ADDR_PKTRAM_START, + &hpriv->addr_pktram_base, + RPU_PROC_TYPE_MAX); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(opriv, + "%s: pal_rpu_addr_offset_get failed\n", + __func__); + goto out; + } + + bal_cfg_params.addr_pktram_base = hpriv->addr_pktram_base; + + hpriv->bpriv = nrf_wifi_bal_init(opriv, + &bal_cfg_params, + &nrf_wifi_hal_irq_handler); + + if (!hpriv->bpriv) { + nrf_wifi_osal_log_err(opriv, + "%s: Failed\n", + __func__); + nrf_wifi_osal_mem_free(opriv, + hpriv); + hpriv = NULL; + } +out: + return hpriv; +} + + +void nrf_wifi_hal_deinit(struct nrf_wifi_hal_priv *hpriv) +{ + nrf_wifi_bal_deinit(hpriv->bpriv); + + nrf_wifi_osal_mem_free(hpriv->opriv, + hpriv); +} + + +enum nrf_wifi_status nrf_wifi_hal_otp_info_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + struct host_rpu_umac_info *otp_info, + unsigned int *otp_flags) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!hal_dev_ctx || !otp_info) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + status = hal_rpu_mem_read(hal_dev_ctx, + otp_info, + RPU_MEM_UMAC_BOOT_SIG, + sizeof(*otp_info)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: OTP info get failed\n", + __func__); + goto out; + } + + status = hal_rpu_mem_read(hal_dev_ctx, + otp_flags, + RPU_MEM_OTP_INFO_FLAGS, + sizeof(*otp_flags)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: OTP flags get failed\n", + __func__); + goto out; + } +out: + return status; +} + + +enum nrf_wifi_status nrf_wifi_hal_otp_ft_prog_ver_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int *ft_prog_ver) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!hal_dev_ctx || !ft_prog_ver) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid parameters\n", + __func__); + goto out; + } + + status = hal_rpu_mem_read(hal_dev_ctx, + ft_prog_ver, + RPU_MEM_OTP_FT_PROG_VERSION, + sizeof(*ft_prog_ver)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: FT program version get failed\n", + __func__); + goto out; + } +out: + return status; +} diff --git a/nrf_wifi/hw_if/hal/src/hal_fw_patch_loader.c b/nrf_wifi/hw_if/hal/src/hal_fw_patch_loader.c new file mode 100644 index 0000000000..033c665988 --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/hal_fw_patch_loader.c @@ -0,0 +1,345 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing patch loader specific definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "host_rpu_common_if.h" +#include "hal_fw_patch_loader.h" +#include "hal_mem.h" + +/* To reduce HEAP maximum usage */ +#define MAX_PATCH_CHUNK_SIZE 8192 +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) + +struct patch_contents { + const char *id_str; + const void *data; + unsigned int size; + unsigned int dest_addr; +}; + +/* In order to save RAM, divide the patch in to chunks download */ +static enum nrf_wifi_status hal_fw_patch_load(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc, + const char *patch_id_str, + unsigned int dest_addr, + const void *fw_patch_data, + unsigned int fw_patch_size) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + int last_chunk_size = fw_patch_size % MAX_PATCH_CHUNK_SIZE; + int num_chunks = fw_patch_size / MAX_PATCH_CHUNK_SIZE + + (last_chunk_size ? 1 : 0); + int chunk = 0; + + for (chunk = 0; chunk < num_chunks; chunk++) { + unsigned char *patch_data_ram; + unsigned int patch_chunk_size = + ((chunk == num_chunks - 1) ? last_chunk_size : MAX_PATCH_CHUNK_SIZE); + const void *src_patch_offset = (const char *)fw_patch_data + + chunk * MAX_PATCH_CHUNK_SIZE; + int dest_chunk_offset = dest_addr + chunk * MAX_PATCH_CHUNK_SIZE; + + patch_data_ram = nrf_wifi_osal_mem_alloc(hal_dev_ctx->hpriv->opriv, + patch_chunk_size); + if (!patch_data_ram) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Failed to allocate memory for patch %s-%s: chunk %d/%d, size: %d\n", + __func__, + rpu_proc_to_str(rpu_proc), + patch_id_str, + chunk + 1, + num_chunks, + patch_chunk_size); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + nrf_wifi_osal_mem_cpy(hal_dev_ctx->hpriv->opriv, + patch_data_ram, + src_patch_offset, + patch_chunk_size); + + + nrf_wifi_osal_log_dbg(hal_dev_ctx->hpriv->opriv, + "%s: Copying patch %s-%s: chunk %d/%d, size: %d\n", + __func__, + rpu_proc_to_str(rpu_proc), + patch_id_str, + chunk + 1, + num_chunks, + patch_chunk_size); + + status = hal_rpu_mem_write(hal_dev_ctx, + dest_chunk_offset, + patch_data_ram, + patch_chunk_size); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Copying patch %s-%s: chunk %d/%d, size: %d failed\n", + __func__, + rpu_proc_to_str(rpu_proc), + patch_id_str, + chunk + 1, + num_chunks, + patch_chunk_size); + goto out; + } +out: + if (patch_data_ram) + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + patch_data_ram); + if (status != NRF_WIFI_STATUS_SUCCESS) + break; + } + + return status; +} + +/* + * Copies the firmware patches to the RPU memory. + */ +enum nrf_wifi_status nrf_wifi_hal_fw_patch_load(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc, + const void *fw_pri_patch_data, + unsigned int fw_pri_patch_size, + const void *fw_sec_patch_data, + unsigned int fw_sec_patch_size) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int pri_dest_addr = 0; + unsigned int sec_dest_addr = 0; + int patch = 0; + + if (!fw_pri_patch_data) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Primary patch missing for RPU (%d)\n", + __func__, + rpu_proc); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + if (!fw_sec_patch_data) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Secondary patch missing for RPU (%d)\n", + __func__, + rpu_proc); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + /* Set the HAL RPU context to the current required context */ + hal_dev_ctx->curr_proc = rpu_proc; + + switch (rpu_proc) { + case RPU_PROC_TYPE_MCU_LMAC: + pri_dest_addr = RPU_MEM_LMAC_PATCH_BIMG; + sec_dest_addr = RPU_MEM_LMAC_PATCH_BIN; + break; + case RPU_PROC_TYPE_MCU_UMAC: + pri_dest_addr = RPU_MEM_UMAC_PATCH_BIMG; + sec_dest_addr = RPU_MEM_UMAC_PATCH_BIN; + break; + default: + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid RPU processor type[%d]\n", + __func__, + rpu_proc); + + goto out; + } + + /* This extra block is needed to avoid compilation error for inline + * declaration but still keep using const data. + */ + { + const struct patch_contents patches[] = { + { "bimg", fw_pri_patch_data, fw_pri_patch_size, pri_dest_addr }, + { "bin", fw_sec_patch_data, fw_sec_patch_size, sec_dest_addr }, + }; + + for (patch = 0; patch < ARRAY_SIZE(patches); patch++) { + status = hal_fw_patch_load(hal_dev_ctx, + rpu_proc, + patches[patch].id_str, + patches[patch].dest_addr, + patches[patch].data, + patches[patch].size); + if (status != NRF_WIFI_STATUS_SUCCESS) + goto out; + } + } +out: + /* Reset the HAL RPU context to the LMAC context */ + hal_dev_ctx->curr_proc = RPU_PROC_TYPE_MCU_LMAC; + + return status; +} + + +enum nrf_wifi_status nrf_wifi_hal_fw_patch_boot(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE rpu_proc, + bool is_patch_present) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int boot_sig_addr = 0; + unsigned int boot_sig_val = 0; + unsigned int boot_excp_0_addr = 0; + unsigned int boot_excp_1_addr = 0; + unsigned int boot_excp_2_addr = 0; + unsigned int boot_excp_3_addr = 0; + unsigned int boot_excp_0_val = 0; + unsigned int boot_excp_1_val = 0; + unsigned int boot_excp_2_val = 0; + unsigned int boot_excp_3_val = 0; + unsigned int sleepctrl_addr = 0; + unsigned int sleepctrl_val = 0; + unsigned int run_addr = 0; + + if (rpu_proc == RPU_PROC_TYPE_MCU_LMAC) { + boot_sig_addr = RPU_MEM_LMAC_BOOT_SIG; + run_addr = RPU_REG_MIPS_MCU_CONTROL; + boot_excp_0_addr = RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_0; + boot_excp_0_val = NRF_WIFI_LMAC_BOOT_EXCP_VECT_0; + boot_excp_1_addr = RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_1; + boot_excp_1_val = NRF_WIFI_LMAC_BOOT_EXCP_VECT_1; + boot_excp_2_addr = RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_2; + boot_excp_2_val = NRF_WIFI_LMAC_BOOT_EXCP_VECT_2; + boot_excp_3_addr = RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_3; + boot_excp_3_val = NRF_WIFI_LMAC_BOOT_EXCP_VECT_3; + if (is_patch_present) { + sleepctrl_addr = RPU_REG_UCC_SLEEP_CTRL_DATA_0; + sleepctrl_val = NRF_WIFI_LMAC_ROM_PATCH_OFFSET; + } + } else if (rpu_proc == RPU_PROC_TYPE_MCU_UMAC) { + boot_sig_addr = RPU_MEM_UMAC_BOOT_SIG; + run_addr = RPU_REG_MIPS_MCU2_CONTROL; + boot_excp_0_addr = RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_0; + boot_excp_0_val = NRF_WIFI_UMAC_BOOT_EXCP_VECT_0; + boot_excp_1_addr = RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_1; + boot_excp_1_val = NRF_WIFI_UMAC_BOOT_EXCP_VECT_1; + boot_excp_2_addr = RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_2; + boot_excp_2_val = NRF_WIFI_UMAC_BOOT_EXCP_VECT_2; + boot_excp_3_addr = RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_3; + boot_excp_3_val = NRF_WIFI_UMAC_BOOT_EXCP_VECT_3; + if (is_patch_present) { + sleepctrl_addr = RPU_REG_UCC_SLEEP_CTRL_DATA_1; + sleepctrl_val = NRF_WIFI_UMAC_ROM_PATCH_OFFSET; + } + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid RPU processor type %d\n", + __func__, + rpu_proc); + goto out; + } + + /* Set the HAL RPU context to the current required context */ + hal_dev_ctx->curr_proc = rpu_proc; + + /* Clear the firmware pass signature location */ + status = hal_rpu_mem_write(hal_dev_ctx, + boot_sig_addr, + &boot_sig_val, + sizeof(boot_sig_val)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Clearing of FW pass signature failed for RPU(%d)\n", + __func__, + rpu_proc); + + goto out; + } + + if (is_patch_present) { + /* Write to sleep control register */ + status = hal_rpu_reg_write(hal_dev_ctx, + sleepctrl_addr, + sleepctrl_val); + } + + /* Write to Boot exception address 0 */ + status = hal_rpu_reg_write(hal_dev_ctx, + boot_excp_0_addr, + boot_excp_0_val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to Boot exception 0 reg for RPU processor(%d) failed\n", + __func__, + rpu_proc); + + goto out; + } + + /* Write to Boot exception address 1 */ + status = hal_rpu_reg_write(hal_dev_ctx, + boot_excp_1_addr, + boot_excp_1_val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to Boot exception 1 reg for RPU processor(%d) failed\n", + __func__, + rpu_proc); + + goto out; + } + + /* Write to Boot exception address 2 */ + status = hal_rpu_reg_write(hal_dev_ctx, + boot_excp_2_addr, + boot_excp_2_val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to Boot exception 2 reg for RPU processor(%d) failed\n", + __func__, + rpu_proc); + + goto out; + } + + /* Write to Boot exception address 3 */ + status = hal_rpu_reg_write(hal_dev_ctx, + boot_excp_3_addr, + boot_excp_3_val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to Boot exception 3 reg for RPU processor(%d) failed\n", + __func__, + rpu_proc); + + goto out; + } + + /* Perform pulsed soft reset of MIPS - this should now run */ + status = hal_rpu_reg_write(hal_dev_ctx, + run_addr, + 0x1); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: RPU processor(%d) run failed\n", + __func__, + rpu_proc); + + goto out; + } +out: + /* Reset the HAL RPU context to the LMAC context */ + hal_dev_ctx->curr_proc = RPU_PROC_TYPE_MCU_LMAC; + + return status; + +} diff --git a/nrf_wifi/hw_if/hal/src/hal_interrupt.c b/nrf_wifi/hw_if/hal/src/hal_interrupt.c new file mode 100644 index 0000000000..2fe37e7363 --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/hal_interrupt.c @@ -0,0 +1,537 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing interrupt handler specific definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "queue.h" +#include "hal_reg.h" +#include "hal_mem.h" +#include "hal_common.h" + + + +enum nrf_wifi_status hal_rpu_irq_enable(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + + /* First enable the blockwise interrupt for the relevant block in the + * master register + */ + status = hal_rpu_reg_read(hal_dev_ctx, + &val, + RPU_REG_INT_FROM_RPU_CTRL); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading from Root interrupt register failed\n", + __func__); + goto out; + } + + val |= (1 << RPU_REG_BIT_INT_FROM_RPU_CTRL); + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_INT_FROM_RPU_CTRL, + val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Enabling Root interrupt failed\n", + __func__); + goto out; + } + + /* Now enable the relevant MCU interrupt line */ + val = (1 << RPU_REG_BIT_INT_FROM_MCU_CTRL); + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_INT_FROM_MCU_CTRL, + val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s:Enabling MCU interrupt failed\n", + __func__); + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status hal_rpu_irq_disable(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + + status = hal_rpu_reg_read(hal_dev_ctx, + &val, + RPU_REG_INT_FROM_RPU_CTRL); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading from Root interrupt register failed\n", + __func__); + goto out; + } + + val &= ~((unsigned int)(1 << RPU_REG_BIT_INT_FROM_RPU_CTRL)); + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_INT_FROM_RPU_CTRL, + val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Disabling Root interrupt failed\n", + __func__); + goto out; + } + + val = ~((unsigned int)(1 << RPU_REG_BIT_INT_FROM_MCU_CTRL)); + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_INT_FROM_MCU_CTRL, + val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Disabling MCU interrupt failed\n", + __func__); + goto out; + } + +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_irq_ack(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + + val = (1 << RPU_REG_BIT_INT_FROM_MCU_ACK); + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_INT_FROM_MCU_ACK, + val); + + return status; +} + + +static bool hal_rpu_irq_wdog_chk(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + bool ret = false; + + status = hal_rpu_reg_read(hal_dev_ctx, + &val, + RPU_REG_MIPS_MCU_UCCP_INT_STATUS); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading from interrupt status register failed\n", + __func__); + goto out; + } + + if (val & (1 << RPU_REG_BIT_MIPS_WATCHDOG_INT_STATUS)) { + ret = true; + } +out: + return ret; + +} + + +static enum nrf_wifi_status hal_rpu_irq_wdog_ack(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int val = 0; + + status = hal_rpu_reg_write(hal_dev_ctx, + RPU_REG_MIPS_MCU_TIMER_CONTROL, + val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Acknowledging watchdog interrupt failed\n", + __func__); + goto out; + } + +out: + return status; + +} + + +static enum nrf_wifi_status hal_rpu_event_free(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int event_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = hal_rpu_hpq_enqueue(hal_dev_ctx, + &hal_dev_ctx->rpu_info.hpqm_info.event_avl_queue, + event_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Enqueueing of event failed\n", + __func__); + goto out; + } + +out: + return status; +} + + +static enum nrf_wifi_status hal_rpu_event_get(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int event_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + struct nrf_wifi_hal_msg *event = NULL; + struct host_rpu_msg_hdr *rpu_msg_hdr = NULL; + unsigned int rpu_msg_len = 0; + unsigned int event_data_size = 0; + /* QSPI : avoid global vars as they can be unaligned */ + unsigned char event_data_typical[RPU_EVENT_COMMON_SIZE_MAX]; + + nrf_wifi_osal_mem_set(hal_dev_ctx->hpriv->opriv, + event_data_typical, + 0, + sizeof(event_data_typical)); + + if (!hal_dev_ctx->event_data_pending) { + /* Copy data worth the maximum size of frequently occurring events from + * the RPU to a local buffer + */ + status = hal_rpu_mem_read(hal_dev_ctx, + event_data_typical, + event_addr, + sizeof(event_data_typical)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading of the event failed\n", + __func__); + goto out; + } + + rpu_msg_hdr = (struct host_rpu_msg_hdr *)event_data_typical; + + rpu_msg_len = rpu_msg_hdr->len; + + /* Allocate space to assemble the entire event */ + hal_dev_ctx->event_data = nrf_wifi_osal_mem_zalloc(hal_dev_ctx->hpriv->opriv, + rpu_msg_len); + + if (!hal_dev_ctx->event_data) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to alloc buff for event data\n", + __func__); + goto out; + } else { + hal_dev_ctx->event_data_curr = hal_dev_ctx->event_data; + } + + hal_dev_ctx->event_data_len = rpu_msg_len; + hal_dev_ctx->event_data_pending = rpu_msg_len; + hal_dev_ctx->event_resubmit = rpu_msg_hdr->resubmit; + + /* Fragmented event */ + if (rpu_msg_len > hal_dev_ctx->hpriv->cfg_params.max_event_size) { + status = hal_rpu_mem_read(hal_dev_ctx, + hal_dev_ctx->event_data_curr, + event_addr, + hal_dev_ctx->hpriv->cfg_params.max_event_size); + + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading of first fragment of event failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + + /* Free up the event in the RPU if necessary */ + if (hal_dev_ctx->event_resubmit) { + status = hal_rpu_event_free(hal_dev_ctx, + event_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Freeing up of the event failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + } + + hal_dev_ctx->event_data_pending -= + hal_dev_ctx->hpriv->cfg_params.max_event_size; + hal_dev_ctx->event_data_curr += + hal_dev_ctx->hpriv->cfg_params.max_event_size; + } else { + /* If this is not part of a fragmented event check if we need to + * copy any additional data i.e. if the event is a corner case + * event of large size. + */ + if (rpu_msg_len > RPU_EVENT_COMMON_SIZE_MAX) { + status = hal_rpu_mem_read(hal_dev_ctx, + hal_dev_ctx->event_data_curr, + event_addr, + rpu_msg_len); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading of large event failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + } else { + nrf_wifi_osal_mem_cpy(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data_curr, + event_data_typical, + rpu_msg_len); + } + + /* Free up the event in the RPU if necessary */ + if (hal_dev_ctx->event_resubmit) { + status = hal_rpu_event_free(hal_dev_ctx, + event_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Freeing up of the event failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + } + + hal_dev_ctx->event_data_pending -= rpu_msg_len; + hal_dev_ctx->event_data_curr += rpu_msg_len; + + } + } else { + event_data_size = (hal_dev_ctx->event_data_pending > + hal_dev_ctx->hpriv->cfg_params.max_event_size) ? + hal_dev_ctx->hpriv->cfg_params.max_event_size : + hal_dev_ctx->event_data_pending; + + if (hal_dev_ctx->event_data) { + status = hal_rpu_mem_read(hal_dev_ctx, + hal_dev_ctx->event_data_curr, + event_addr, + event_data_size); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Reading of large event failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + } + + /* Free up the event in the RPU if necessary */ + if (hal_dev_ctx->event_resubmit) { + status = hal_rpu_event_free(hal_dev_ctx, + event_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Freeing up of the event failed\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + } + + hal_dev_ctx->event_data_pending -= event_data_size; + hal_dev_ctx->event_data_curr += event_data_size; + } + + /* This is either a unfragmented event or the last fragment of a + * fragmented event + */ + if (!hal_dev_ctx->event_data_pending) { + event = nrf_wifi_osal_mem_zalloc(hal_dev_ctx->hpriv->opriv, + sizeof(*event) + hal_dev_ctx->event_data_len); + + if (!event) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to alloc HAL msg for event\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + + nrf_wifi_osal_mem_cpy(hal_dev_ctx->hpriv->opriv, + event->data, + hal_dev_ctx->event_data, + hal_dev_ctx->event_data_len); + + event->len = hal_dev_ctx->event_data_len; + + status = nrf_wifi_utils_q_enqueue(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_q, + event); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Unable to queue event\n", + __func__); + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + event); + event = NULL; + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + goto out; + } + + /* Reset the state variables */ + nrf_wifi_osal_mem_free(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->event_data); + hal_dev_ctx->event_data = NULL; + hal_dev_ctx->event_data_curr = NULL; + hal_dev_ctx->event_data_len = 0; + hal_dev_ctx->event_resubmit = 0; + } +out: + return status; +} + + +static unsigned int hal_rpu_event_get_all(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int num_events = 0; + unsigned int event_addr = 0; + + while (1) { + event_addr = 0; + + /* First get the event address */ + status = hal_rpu_hpq_dequeue(hal_dev_ctx, + &hal_dev_ctx->rpu_info.hpqm_info.event_busy_queue, + &event_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Failed to get event addr\n", + __func__); + goto out; + } + + /* No more events to read. Sometimes when low power mode is enabled + * we see a wrong address, but it work after a while, so, add a + * check for that. + */ + if (!event_addr || event_addr == 0xAAAAAAAA) { + break; + } + + /* Now get the event for further processing */ + status = hal_rpu_event_get(hal_dev_ctx, + event_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Failed to queue event\n", + __func__); + goto out; + } + + num_events++; + } + +out: + return num_events; +} + + +enum nrf_wifi_status hal_rpu_irq_process(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int num_events = 0; + + + /* Get all the events in the queue. It is possible that there are no + * events in the queue. This is a valid scenario as per our present + * design (as discussed with LMAC team), since the RPU will raise + * interrupts for every event, irrespective of whether the host has + * acknowledged the previous event or not. This is being done to + * address an issue with FPGA platform where some interrupts are + * getting lost. Also RPU does not provide a register to check if + * the interrupt is from the RPU, so presently host cannot identify + * the interrupt source. This will be a problem in shared interrupt + * scenarios and has to be taken care by the SOC designers. + */ + num_events = hal_rpu_event_get_all(hal_dev_ctx); + + /* If we received an interrupt without any associated event(s) it is a + * likely indication that the RPU is stuck and this interrupt has been + * raised by the watchdog + */ + if (!num_events) { + /* Check the if this interrupt has been raised by the + * RPU watchdog + */ + if (hal_rpu_irq_wdog_chk(hal_dev_ctx)) { + /* TODO: Perform RPU recovery */ + nrf_wifi_osal_log_dbg(hal_dev_ctx->hpriv->opriv, + "Received watchdog interrupt\n"); + + status = hal_rpu_irq_wdog_ack(hal_dev_ctx); + + if (status == NRF_WIFI_STATUS_FAIL) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: hal_rpu_irq_wdog_ack failed\n", + __func__); + goto out; + } + } + } + + status = hal_rpu_irq_ack(hal_dev_ctx); + + if (status == NRF_WIFI_STATUS_FAIL) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: hal_rpu_irq_ack failed\n", + __func__); + goto out; + } +out: + return status; +} diff --git a/nrf_wifi/hw_if/hal/src/hal_mem.c b/nrf_wifi/hw_if/hal/src/hal_mem.c new file mode 100644 index 0000000000..115647dd61 --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/hal_mem.c @@ -0,0 +1,480 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing memory read/write specific definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "pal.h" +#include "hal_api.h" +#include "hal_common.h" +#include "hal_reg.h" +#include "hal_mem.h" + + +static bool hal_rpu_is_mem_ram(enum RPU_PROC_TYPE proc, unsigned int addr_val) +{ + if (((addr_val >= RPU_ADDR_GRAM_START) && + (addr_val <= RPU_ADDR_GRAM_END)) || + ((addr_val >= RPU_ADDR_PKTRAM_START) && + (addr_val <= RPU_ADDR_GRAM_END)) || + ((addr_val >= RPU_ADDR_PKTRAM_START) && + (addr_val <= RPU_ADDR_PKTRAM_END))) { + return true; + } else { + return false; + } +} + + +static bool hal_rpu_is_mem_bev(unsigned int addr_val) +{ + if (((addr_val >= RPU_ADDR_BEV_START) && + (addr_val <= RPU_ADDR_BEV_END))) { + return true; + } else { + return false; + } +} + +static bool hal_rpu_is_mem_core_direct(enum RPU_PROC_TYPE proc, + unsigned int addr_val) +{ + return pal_check_rpu_mcu_regions(proc, addr_val); +} + + +static bool hal_rpu_is_mem_core_indirect(enum RPU_PROC_TYPE proc, + unsigned int addr_val) +{ + return ((addr_val & 0xFF000000) == RPU_MCU_CORE_INDIRECT_BASE); +} + + +static bool hal_rpu_is_mem_readable(enum RPU_PROC_TYPE proc, unsigned int addr) +{ + return hal_rpu_is_mem_ram(proc, addr); +} + + +static bool hal_rpu_is_mem_writable(enum RPU_PROC_TYPE proc, + unsigned int addr) +{ + if (hal_rpu_is_mem_ram(proc, addr) || + hal_rpu_is_mem_core_indirect(proc, addr) || + hal_rpu_is_mem_core_direct(proc, addr) || + hal_rpu_is_mem_bev(addr)) { + return true; + } + + return false; +} + + +static enum nrf_wifi_status rpu_mem_read_ram(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + void *src_addr, + unsigned int ram_addr_val, + unsigned int len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned long addr_offset = 0; +#ifdef CONFIG_NRF_WIFI_LOW_POWER + unsigned long flags = 0; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + status = pal_rpu_addr_offset_get(hal_dev_ctx->hpriv->opriv, + ram_addr_val, + &addr_offset, + hal_dev_ctx->curr_proc); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: pal_rpu_addr_offset_get failed\n", + __func__); + return status; + } + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); + + status = hal_rpu_ps_wake(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: RPU wake failed\n", + __func__); + goto out; + } +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + nrf_wifi_bal_read_block(hal_dev_ctx->bal_dev_ctx, + src_addr, + addr_offset, + len); + + status = NRF_WIFI_STATUS_SUCCESS; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +out: + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + return status; +} + + +static enum nrf_wifi_status rpu_mem_write_ram(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int ram_addr_val, + void *src_addr, + unsigned int len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned long addr_offset = 0; +#ifdef CONFIG_NRF_WIFI_LOW_POWER + unsigned long flags = 0; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + status = pal_rpu_addr_offset_get(hal_dev_ctx->hpriv->opriv, + ram_addr_val, + &addr_offset, + hal_dev_ctx->curr_proc); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: pal_rpu_addr_offset_get failed\n", + __func__); + return status; + } + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); + + status = hal_rpu_ps_wake(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: RPU wake failed\n", + __func__); + goto out; + } +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + nrf_wifi_bal_write_block(hal_dev_ctx->bal_dev_ctx, + addr_offset, + src_addr, + len); + + status = NRF_WIFI_STATUS_SUCCESS; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +out: + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + return status; +} + + +static enum nrf_wifi_status rpu_mem_write_core(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int core_addr_val, + void *src_addr, + unsigned int len) +{ + int status = NRF_WIFI_STATUS_FAIL; + unsigned int addr_reg = 0; + unsigned int data_reg = 0; + unsigned int addr = 0; + unsigned int data = 0; + unsigned int i = 0; + + /* The RPU core address is expected to be in multiples of 4 bytes (word + * size). If not then something is amiss. + */ + if (!hal_rpu_is_mem_core_indirect(hal_dev_ctx->curr_proc, + core_addr_val)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid memory address\n", + __func__); + goto out; + } + + if (core_addr_val % 4 != 0) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Address not multiple of 4 bytes\n", + __func__); + goto out; + } + + /* The register expects the word address offset to be programmed + * (i.e. it will write 4 bytes at once to the given address). + * whereas we receive the address in byte address offset. + */ + addr = (core_addr_val & RPU_ADDR_MASK_OFFSET) / 4; + + addr_reg = RPU_REG_MIPS_MCU_SYS_CORE_MEM_CTRL; + data_reg = RPU_REG_MIPS_MCU_SYS_CORE_MEM_WDATA; + + if (hal_dev_ctx->curr_proc == RPU_PROC_TYPE_MCU_UMAC) { + addr_reg = RPU_REG_MIPS_MCU2_SYS_CORE_MEM_CTRL; + data_reg = RPU_REG_MIPS_MCU2_SYS_CORE_MEM_WDATA; + } + + status = hal_rpu_reg_write(hal_dev_ctx, + addr_reg, + addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to address reg failed\n", + __func__); + goto out; + } + + for (i = 0; i < (len / sizeof(int)); i++) { + data = *((unsigned int *)src_addr + i); + + status = hal_rpu_reg_write(hal_dev_ctx, + data_reg, + data); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to data reg failed\n", + __func__); + goto out; + } + } +out: + return status; +} + + +static unsigned int rpu_get_bev_addr_remap(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int bev_addr_val) +{ + unsigned int addr = 0; + unsigned int offset = 0; + + offset = bev_addr_val & RPU_ADDR_MASK_BEV_OFFSET; + + /* Base of the Boot Exception Vector 0xBFC00000 maps to 0xA4000050 */ + addr = RPU_REG_MIPS_MCU_BOOT_EXCP_INSTR_0 + offset; + + if (hal_dev_ctx->curr_proc == RPU_PROC_TYPE_MCU_UMAC) { + addr = RPU_REG_MIPS_MCU2_BOOT_EXCP_INSTR_0 + offset; + } + + return addr; +} + + +static enum nrf_wifi_status rpu_mem_write_bev(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int bev_addr_val, + void *src_addr, + unsigned int len) +{ + int status = NRF_WIFI_STATUS_FAIL; + unsigned int addr = 0; + unsigned int data = 0; + unsigned int i = 0; + + /* The RPU BEV address is expected to be in multiples of 4 bytes (word + * size). If not then something is amiss. + */ + if ((bev_addr_val < RPU_ADDR_BEV_START) || + (bev_addr_val > RPU_ADDR_BEV_END) || + (bev_addr_val % 4 != 0)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Address not in range or not a multiple of 4 bytes\n", + __func__); + goto out; + } + + for (i = 0; i < (len / sizeof(int)); i++) { + /* The BEV addresses need remapping + * to an address on the SYSBUS. + */ + addr = rpu_get_bev_addr_remap(hal_dev_ctx, + bev_addr_val + + (i * sizeof(int))); + + data = *((unsigned int *)src_addr + i); + + status = hal_rpu_reg_write(hal_dev_ctx, + addr, + data); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Writing to BEV reg failed\n", + __func__); + goto out; + } + } + +out: + return status; +} + + +enum nrf_wifi_status hal_rpu_mem_read(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + void *src_addr, + unsigned int rpu_mem_addr_val, + unsigned int len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!hal_dev_ctx) { + goto out; + } + + if (!src_addr) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid params\n", + __func__); + goto out; + } + + if (!hal_rpu_is_mem_readable(hal_dev_ctx->curr_proc, rpu_mem_addr_val)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid memory address 0x%X\n", + __func__, + rpu_mem_addr_val); + goto out; + } + + status = rpu_mem_read_ram(hal_dev_ctx, + src_addr, + rpu_mem_addr_val, + len); +out: + return status; +} + + +enum nrf_wifi_status hal_rpu_mem_write(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int rpu_mem_addr_val, + void *src_addr, + unsigned int len) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + if (!hal_dev_ctx) { + return status; + } + + if (!src_addr) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid params\n", + __func__); + return status; + } + + if (!hal_rpu_is_mem_writable(hal_dev_ctx->curr_proc, + rpu_mem_addr_val)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid memory address 0x%X\n", + __func__, + rpu_mem_addr_val); + return status; + } + + if (hal_rpu_is_mem_core_indirect(hal_dev_ctx->curr_proc, + rpu_mem_addr_val)) { + status = rpu_mem_write_core(hal_dev_ctx, + rpu_mem_addr_val, + src_addr, + len); + } else if (hal_rpu_is_mem_core_direct(hal_dev_ctx->curr_proc, rpu_mem_addr_val) || + hal_rpu_is_mem_ram(hal_dev_ctx->curr_proc, rpu_mem_addr_val)) { + status = rpu_mem_write_ram(hal_dev_ctx, + rpu_mem_addr_val, + src_addr, + len); + } else if (hal_rpu_is_mem_bev(rpu_mem_addr_val)) { + status = rpu_mem_write_bev(hal_dev_ctx, + rpu_mem_addr_val, + src_addr, + len); + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid memory address 0x%X\n", + __func__, + rpu_mem_addr_val); + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status hal_rpu_mem_clr(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + enum RPU_PROC_TYPE proc, + enum HAL_RPU_MEM_TYPE mem_type) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int mem_addr = 0; + unsigned int start_addr = 0; + unsigned int end_addr = 0; + unsigned int mem_val = 0; + enum RPU_MCU_ADDR_REGIONS mcu_region = pal_mem_type_to_region(mem_type); + + if (!hal_dev_ctx) { + goto out; + } + + if (mem_type == HAL_RPU_MEM_TYPE_GRAM) { + start_addr = RPU_ADDR_GRAM_START; + end_addr = RPU_ADDR_GRAM_END; + } else if (mem_type == HAL_RPU_MEM_TYPE_PKTRAM) { + start_addr = RPU_ADDR_PKTRAM_START; + end_addr = RPU_ADDR_PKTRAM_END; + } else if (mcu_region != RPU_MCU_ADDR_REGION_MAX) { + const struct rpu_addr_map *map = &RPU_ADDR_MAP_MCU[proc]; + const struct rpu_addr_region *region = &map->regions[mcu_region]; + + start_addr = region->start; + end_addr = region->end; + } else { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid mem_type(%d)\n", + __func__, + mem_type); + goto out; + } + + for (mem_addr = start_addr; + mem_addr <= end_addr; + mem_addr += sizeof(mem_val)) { + status = hal_rpu_mem_write(hal_dev_ctx, + mem_addr, + &mem_val, + sizeof(mem_val)); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: hal_rpu_mem_write failed\n", + __func__); + goto out; + } + } + + + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} diff --git a/nrf_wifi/hw_if/hal/src/hal_reg.c b/nrf_wifi/hw_if/hal/src/hal_reg.c new file mode 100644 index 0000000000..6df171b22a --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/hal_reg.c @@ -0,0 +1,170 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing register read/write specific definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "pal.h" +#include "hal_api.h" +#include "hal_common.h" + + +static bool hal_rpu_is_reg(unsigned int addr_val) +{ + unsigned int addr_base = (addr_val & RPU_ADDR_MASK_BASE); + + if ((addr_base == RPU_ADDR_SBUS_START) || + (addr_base == RPU_ADDR_PBUS_START)) { + return true; + } else { + return false; + } +} + + +enum nrf_wifi_status hal_rpu_reg_read(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int *val, + unsigned int rpu_reg_addr) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned long addr_offset = 0; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + unsigned long flags = 0; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + if (!hal_dev_ctx) { + return status; + } + + if ((val == NULL) || + !hal_rpu_is_reg(rpu_reg_addr)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid params, val = %p, rpu_reg (0x%x)\n", + __func__, + val, + rpu_reg_addr); + return status; + } + + status = pal_rpu_addr_offset_get(hal_dev_ctx->hpriv->opriv, + rpu_reg_addr, + &addr_offset, + hal_dev_ctx->curr_proc); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: pal_rpu_addr_offset_get failed\n", + __func__); + return status; + } + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); + + status = hal_rpu_ps_wake(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: RPU wake failed\n", + __func__); + goto out; + } +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + *val = nrf_wifi_bal_read_word(hal_dev_ctx->bal_dev_ctx, + addr_offset); + + if (*val == 0xFFFFFFFF) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Error !! Value read at addr_offset = %lx is = %X\n", + __func__, + addr_offset, + *val); + status = NRF_WIFI_STATUS_FAIL; + goto out; + } + + status = NRF_WIFI_STATUS_SUCCESS; +out: +#ifdef CONFIG_NRF_WIFI_LOW_POWER + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + return status; +} + +enum nrf_wifi_status hal_rpu_reg_write(struct nrf_wifi_hal_dev_ctx *hal_dev_ctx, + unsigned int rpu_reg_addr, + unsigned int val) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned long addr_offset = 0; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + unsigned long flags = 0; +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + if (!hal_dev_ctx) { + return status; + } + + if (!hal_rpu_is_reg(rpu_reg_addr)) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: Invalid params, rpu_reg_addr (0x%X)\n", + __func__, + rpu_reg_addr); + return status; + } + + status = pal_rpu_addr_offset_get(hal_dev_ctx->hpriv->opriv, + rpu_reg_addr, + &addr_offset, + hal_dev_ctx->curr_proc); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: pal_rpu_get_region_offset failed\n", + __func__); + return status; + } + +#ifdef CONFIG_NRF_WIFI_LOW_POWER + nrf_wifi_osal_spinlock_irq_take(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); + + status = hal_rpu_ps_wake(hal_dev_ctx); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_dev_ctx->hpriv->opriv, + "%s: RPU wake failed\n", + __func__); + goto out; + } +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + nrf_wifi_bal_write_word(hal_dev_ctx->bal_dev_ctx, + addr_offset, + val); + + status = NRF_WIFI_STATUS_SUCCESS; + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +out: + nrf_wifi_osal_spinlock_irq_rel(hal_dev_ctx->hpriv->opriv, + hal_dev_ctx->rpu_ps_lock, + &flags); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + return status; +} diff --git a/nrf_wifi/hw_if/hal/src/hpqm.c b/nrf_wifi/hw_if/hal/src/hpqm.c new file mode 100644 index 0000000000..e22a223bae --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/hpqm.c @@ -0,0 +1,72 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing HPQM interface specific definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "hal_reg.h" +#include "hal_mem.h" +#include "hal_common.h" + +enum nrf_wifi_status hal_rpu_hpq_enqueue(struct nrf_wifi_hal_dev_ctx *hal_ctx, + struct host_rpu_hpq *hpq, + unsigned int val) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = hal_rpu_reg_write(hal_ctx, + hpq->enqueue_addr, + val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_ctx->hpriv->opriv, + "%s: Writing to enqueue address failed\n", + __func__); + goto out; + } + +out: + return status; +} + + +enum nrf_wifi_status hal_rpu_hpq_dequeue(struct nrf_wifi_hal_dev_ctx *hal_ctx, + struct host_rpu_hpq *hpq, + unsigned int *val) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + status = hal_rpu_reg_read(hal_ctx, + val, + hpq->dequeue_addr); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_ctx->hpriv->opriv, + "%s: Dequeue failed, val (0x%X)\n", + __func__, + *val); + goto out; + } + + /* Pop the element only if it is valid */ + if (*val) { + status = hal_rpu_reg_write(hal_ctx, + hpq->dequeue_addr, + *val); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + nrf_wifi_osal_log_err(hal_ctx->hpriv->opriv, + "%s: Writing to dequeue address failed, val (0x%X)\n", + __func__, + *val); + goto out; + } + } +out: + return status; +} diff --git a/nrf_wifi/hw_if/hal/src/pal.c b/nrf_wifi/hw_if/hal/src/pal.c new file mode 100644 index 0000000000..61df23d38d --- /dev/null +++ b/nrf_wifi/hw_if/hal/src/pal.c @@ -0,0 +1,122 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing SoC specific definitions for the + * HAL Layer of the Wi-Fi driver. + */ + +#include "pal.h" +#include "hal_api.h" + +bool pal_check_rpu_mcu_regions(enum RPU_PROC_TYPE proc, unsigned int addr_val) +{ + const struct rpu_addr_map *map = &RPU_ADDR_MAP_MCU[proc]; + enum RPU_MCU_ADDR_REGIONS region_type; + + if (proc >= RPU_PROC_TYPE_MAX) { + return false; + } + + for (region_type = 0; region_type < RPU_MCU_ADDR_REGION_MAX; region_type++) { + const struct rpu_addr_region *region = &map->regions[region_type]; + + if ((addr_val >= region->start) && (addr_val <= region->end)) { + return true; + } + } + + return false; +} + +enum nrf_wifi_status pal_rpu_addr_offset_get(struct nrf_wifi_osal_priv *opriv, + unsigned int rpu_addr, + unsigned long *addr, + enum RPU_PROC_TYPE proc) +{ + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + unsigned int addr_base = (rpu_addr & RPU_ADDR_MASK_BASE); + unsigned long region_offset = 0; + + if (addr_base == RPU_ADDR_SBUS_START) { + region_offset = SOC_MMAP_ADDR_OFFSET_SYSBUS; + } else if ((rpu_addr >= RPU_ADDR_GRAM_START) && + (rpu_addr <= RPU_ADDR_GRAM_END)) { + region_offset = SOC_MMAP_ADDR_OFFSET_GRAM_PKD; + } else if (addr_base == RPU_ADDR_PBUS_START) { + region_offset = SOC_MMAP_ADDR_OFFSET_PBUS; + } else if (addr_base == RPU_ADDR_PKTRAM_START) { + region_offset = SOC_MMAP_ADDR_OFFSET_PKTRAM_HOST_VIEW; + } else if (pal_check_rpu_mcu_regions(proc, rpu_addr)) { + region_offset = SOC_MMAP_ADDR_OFFSETS_MCU[proc]; + } else { + nrf_wifi_osal_log_err(opriv, + "%s: Invalid rpu_addr 0x%X\n", + __func__, + rpu_addr); + goto out; + } + + *addr = region_offset + (rpu_addr & RPU_ADDR_MASK_OFFSET); + + status = NRF_WIFI_STATUS_SUCCESS; +out: + return status; +} + + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +unsigned long pal_rpu_ps_ctrl_reg_addr_get(void) +{ + return SOC_MMAP_ADDR_RPU_PS_CTRL; +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + +char *pal_ops_get_fw_loc(struct nrf_wifi_osal_priv *opriv, + enum nrf_wifi_fw_type fw_type, + enum nrf_wifi_fw_subtype fw_subtype) +{ + char *fw_loc = NULL; + + switch (fw_type) { + case NRF_WIFI_FW_TYPE_LMAC_PATCH: + if (fw_subtype == NRF_WIFI_FW_SUBTYPE_PRI) { + fw_loc = NRF_WIFI_FW_LMAC_PATCH_LOC_PRI; + } else if (fw_subtype == NRF_WIFI_FW_SUBTYPE_SEC) { + fw_loc = NRF_WIFI_FW_LMAC_PATCH_LOC_SEC; + } else { + nrf_wifi_osal_log_err(opriv, + "%s: Invalid LMAC FW sub-type = %d\n", + __func__, + fw_subtype); + goto out; + } + break; + case NRF_WIFI_FW_TYPE_UMAC_PATCH: + if (fw_subtype == NRF_WIFI_FW_SUBTYPE_PRI) { + fw_loc = NRF_WIFI_FW_UMAC_PATCH_LOC_PRI; + } else if (fw_subtype == NRF_WIFI_FW_SUBTYPE_SEC) { + fw_loc = NRF_WIFI_FW_UMAC_PATCH_LOC_SEC; + } else { + nrf_wifi_osal_log_err(opriv, + "%s: Invalid UMAC FW sub-type = %d\n", + __func__, + fw_subtype); + goto out; + } + break; + default: + nrf_wifi_osal_log_err(opriv, + "%s: Invalid FW type = %d\n", + __func__, + fw_type); + goto out; + } + +out: + return fw_loc; +} diff --git a/nrf_wifi/os_if/inc/osal_api.h b/nrf_wifi/os_if/inc/osal_api.h new file mode 100644 index 0000000000..7505b432cb --- /dev/null +++ b/nrf_wifi/os_if/inc/osal_api.h @@ -0,0 +1,1586 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing declarations for the + * OSAL Layer of the Wi-Fi driver. + */ + +#ifndef __OSAL_API_H__ +#define __OSAL_API_H__ + +#include +#include "osal_structs.h" + +/* Have to match zephyr/include/zephyr/logging/log_core.h */ +#define NRF_WIFI_LOG_LEVEL_ERR 1U +#define NRF_WIFI_LOG_LEVEL_INF 3U +#define NRF_WIFI_LOG_LEVEL_DBG 4U + +#ifndef CONFIG_NRF700X_LOG_VERBOSE +#define __func__ "" +#endif /* CONFIG_NRF700X_LOG_VERBOSE */ + +/** + * nrf_wifi_osal_init() - Initialize the OSAL layer. + * + * Initializes the OSAL layer and is expected to be called + * before using the OSAL layer. Returns a pointer to the OSAL context + * which might need to be passed to further API calls. + * + * Return: Pointer to instance of OSAL context. + */ +struct nrf_wifi_osal_priv *nrf_wifi_osal_init(void); + + +/** + * nrf_wifi_osal_deinit() - Deinitialize the OSAL layer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Deinitializes the OSAL layer and is expected to be called after done using + * the OSAL layer. + * + * Return: None. + */ +void nrf_wifi_osal_deinit(struct nrf_wifi_osal_priv *opriv); + + +/** + * nrf_wifi_osal_mem_alloc() - Allocate memory. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @size: Size of the memory to be allocated in bytes. + * + * Allocates memory of @size bytes and returns a pointer to the start + * of the memory allocated. + * + * Return: + * Pass: Pointer to start of allocated memory. + * Error: NULL. + */ +void *nrf_wifi_osal_mem_alloc(struct nrf_wifi_osal_priv *opriv, + size_t size); + +/** + * nrf_wifi_osal_mem_zalloc() - Allocated zero-initialized memory. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @size: Size of the memory to be allocated in bytes. + * + * Allocates memory of @size bytes, zeroes it out and returns a pointer to the + * start of the memory allocated. + * + * Return: + * Pass: Pointer to start of allocated memory. + * Error: NULL. + */ +void *nrf_wifi_osal_mem_zalloc(struct nrf_wifi_osal_priv *opriv, + size_t size); + +/** + * nrf_wifi_osal_mem_free() - Free previously allocated memory. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @buf: Pointer to the memory to be freed. + * + * Free up memory which has been allocated using @nrf_wifi_osal_mem_alloc or + * @nrf_wifi_osal_mem_zalloc. + * + * Return: None. + */ +void nrf_wifi_osal_mem_free(struct nrf_wifi_osal_priv *opriv, + void *buf); + +/** + * nrf_wifi_osal_mem_cpy() - Copy contents from one memory location to another. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @dest: Pointer to the memory location where contents are to be copied. + * @src: Pointer to the memory location from where contents are to be copied. + * @count: Number of bytes to be copied. + * + * Copies @count number of bytes from @src location in memory to @dest + * location in memory. + * + * Return: + * Pass: Pointer to destination memory. + * Error: NULL. + */ +void *nrf_wifi_osal_mem_cpy(struct nrf_wifi_osal_priv *opriv, + void *dest, + const void *src, + size_t count); + +/** + * nrf_wifi_osal_mem_set() - Fill a block of memory with a particular value. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @start: Pointer to the memory location whose contents are to be set. + * @val: Value to be set. + * @size: Number of bytes to be set. + * + * Fills a block of memory of @size bytes starting at @start with a particular + * value represented by @val. + * + * Return: + * Pass: Pointer to memory location which was set. + * Error: NULL. + */ +void *nrf_wifi_osal_mem_set(struct nrf_wifi_osal_priv *opriv, + void *start, + int val, + size_t size); + + +/** + * nrf_wifi_osal_iomem_mmap() - Memory map IO memory into CPU space. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @addr: Address of the IO memory to be mapped. + * @size: Size of the IO memory in bytes. + * + * Maps IO memory of @size bytes pointed to by @addr into CPU space. + * + * Return: + * Pass: Pointer to the mapped IO memory. + * Error: NULL. + */ +void *nrf_wifi_osal_iomem_mmap(struct nrf_wifi_osal_priv *opriv, + unsigned long addr, + unsigned long size); + +/** + * nrf_wifi_osal_iomem_unmap() - Unmap previously mapped IO memory from CPU space. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @addr: Pointer to mapped IO memory to be unmapped. + * + * Unmaps IO memory from CPU space that was mapped using @nrf_wifi_osal_iomem_mmap. + * + * Return: None. + */ +void nrf_wifi_osal_iomem_unmap(struct nrf_wifi_osal_priv *opriv, + volatile void *addr); + +/** + * nrf_wifi_osal_iomem_read_reg32() - Read value from a 32 bit IO memory mapped + * register. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @addr: Pointer to the IO memory mapped register address. + * + * Reads value from a 32 bit device register using a memory mapped + * address(@addr). + * + * Return: 32 bit value read from register. + */ +unsigned int nrf_wifi_osal_iomem_read_reg32(struct nrf_wifi_osal_priv *opriv, + const volatile void *addr); + +/** + * nrf_wifi_osal_iomem_write_reg32() - Write a 32 bit value to a IO memory mapped register. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @addr: Pointer to the IO memory mapped register address. + * @val: Value to be written to the register. + * + * Writes a 32 bit value (@val) to a 32 bit device register using a memory + * mapped address(@addr). + * + * Return: None. + */ +void nrf_wifi_osal_iomem_write_reg32(struct nrf_wifi_osal_priv *opriv, + volatile void *addr, + unsigned int val); + +/** + * nrf_wifi_osal_iomem_cpy_from() - Copy data from the memory of a memory + * mapped IO device to host memory. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @dest: Pointer to the host memory where data is to be copied. + * @src: Pointer to the memory of the memory mapped IO device from where + * data is to be copied. + * @count: The size of the data to be copied in bytes. + * + * Copies a block of data of size @count bytes from memory mapped device + * memory(@src) to host memory(@dest). + * + * Return: None. + */ +void nrf_wifi_osal_iomem_cpy_from(struct nrf_wifi_osal_priv *opriv, + void *dest, + const volatile void *src, + size_t count); + +/** + * nrf_wifi_osal_iomem_cpy_to() - Copy data to the memory of a memory + * mapped IO device from host memory. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @dest: Pointer to the memory of the memory mapped IO device where + * data is to be copied. + * @src: Pointer to the host memory from where data is to be copied. + * @count: The size of the data to be copied in bytes. + * + * Copies a block of data of size @count bytes from host memory (@src) to + * memory mapped device memory(@dest). + * + * Return: None. + */ +void nrf_wifi_osal_iomem_cpy_to(struct nrf_wifi_osal_priv *opriv, + volatile void *dest, + const void *src, + size_t count); + + +/** + * nrf_wifi_osal_spinlock_alloc() - Allocate a busy lock. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Allocates a busy lock. + * + * Return: + * Pass: Pointer to the busy lock instance. + * Error: NULL. + */ +void *nrf_wifi_osal_spinlock_alloc(struct nrf_wifi_osal_priv *opriv); + +/** + * nrf_wifi_osal_spinlock_free() - Free a busy lock. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @lock: Pointer to a busy lock instance. + * + * Frees a busy lock (@lock) allocated by @nrf_wifi_osal_spinlock_alloc + * + * Return: None. + */ +void nrf_wifi_osal_spinlock_free(struct nrf_wifi_osal_priv *opriv, + void *lock); + + +/** + * nrf_wifi_osal_spinlock_init() - Initialize a busy lock. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @lock: Pointer to a busy lock instance. + * + * Initializes a busy lock (@lock) allocated by @nrf_wifi_osal_spinlock_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_spinlock_init(struct nrf_wifi_osal_priv *opriv, + void *lock); + + +/** + * nrf_wifi_osal_spinlock_take() - Acquire a buys lock. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @lock: Pointer to a busy lock instance. + * + * Acquires a busy lock (@lock) allocated by @nrf_wifi_osal_spinlock_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_spinlock_take(struct nrf_wifi_osal_priv *opriv, + void *lock); + + +/** + * nrf_wifi_osal_spinlock_rel() - Releases a busy lock. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @lock: Pointer to a busy lock instance. + * + * Releases a busy lock (@lock) acquired by @nrf_wifi_osal_spinlock_take. + * + * Return: None. + */ +void nrf_wifi_osal_spinlock_rel(struct nrf_wifi_osal_priv *opriv, + void *lock); + + +/** + * nrf_wifi_osal_spinlock_irq_take() - Acquire a busy lock and disable + * interrupts. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @lock: Pointer to a busy lock instance. + * @flags: Interrupt state flags. + * + * Saves interrupt states (@flags), disable interrupts and take a + * busy lock (@lock). + * + * Return: None. + */ +void nrf_wifi_osal_spinlock_irq_take(struct nrf_wifi_osal_priv *opriv, + void *lock, + unsigned long *flags); + + +/** + * nrf_wifi_osal_spinlock_irq_rel() - Release a busy lock and enable interrupts. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @lock: Pointer to a busy lock instance. + * @flags: Interrupt state flags. + * + * Restores interrupt states (@flags) and releases busy lock (@lock) acquired + * using @nrf_wifi_osal_spinlock_irq_take. + * + * Return: None. + */ +void nrf_wifi_osal_spinlock_irq_rel(struct nrf_wifi_osal_priv *opriv, + void *lock, + unsigned long *flags); + + +#if CONFIG_WIFI_NRF700X_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_DBG +/** + * nrf_wifi_osal_log_dbg() - Log a debug message. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @fmt: Format string. + * @...: Variable arguments. + * + * Logs a debug message. + * + * Return: Number of characters of the message logged. + */ +int nrf_wifi_osal_log_dbg(struct nrf_wifi_osal_priv *opriv, + const char *fmt, ...); +#else +#define nrf_wifi_osal_log_dbg(level, fmt, ...) +#endif + + +#if CONFIG_WIFI_NRF700X_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_INF +/** + * nrf_wifi_osal_log_info() - Log a informational message. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @fmt: Format string. + * @...: Variable arguments. + * + * Logs an informational message. + * + * Return: Number of characters of the message logged. + */ +int nrf_wifi_osal_log_info(struct nrf_wifi_osal_priv *opriv, + const char *fmt, ...); +#else +#define nrf_wifi_osal_log_info(level, fmt, ...) +#endif + + +#if CONFIG_WIFI_NRF700X_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_ERR +/** + * nrf_wifi_osal_log_err() - Logs an error message. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @fmt: Format string. + * @...: Variable arguments. + * + * Logs an error message. + * + * Return: Number of characters of the message logged. + */ +int nrf_wifi_osal_log_err(struct nrf_wifi_osal_priv *opriv, + const char *fmt, ...); +#else +#define nrf_wifi_osal_log_err(level, fmt, ...) +#endif + + +/** + * nrf_wifi_osal_llist_node_alloc() - Allocate a linked list mode. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Allocates a linked list node. + * + * Return: + * Pass: Pointer to the linked list node allocated. + * Error: NULL. + */ +void *nrf_wifi_osal_llist_node_alloc(struct nrf_wifi_osal_priv *opriv); + + +/** + * nrf_wifi_osal_llist_node_free() - Free a linked list node. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @node: Pointer to a linked list node. + * + * Frees a linked list node(@node) which was allocated by + * @nrf_wifi_osal_llist_node_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_llist_node_free(struct nrf_wifi_osal_priv *opriv, + void *node); + +/** + * nrf_wifi_osal_llist_node_data_get() - Get data stored in a linked list node. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @node: Pointer to a linked list node. + * + * Gets the pointer to the data which the linked list node(@node) points to. + * + * Return: + * Pass: Pointer to the data stored in the linked list node. + * Error: NULL. + */ +void *nrf_wifi_osal_llist_node_data_get(struct nrf_wifi_osal_priv *opriv, + void *node); + + +/** + * nrf_wifi_osal_llist_node_data_set() - Set data in a linked list node. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @node: Pointer to a linked list node. + * @data: Pointer to the data to be stored in the linked list node. + * + * Stores the pointer to the data(@data) in a linked list node(@node). + * + * + * Return: None. + */ +void nrf_wifi_osal_llist_node_data_set(struct nrf_wifi_osal_priv *opriv, + void *node, + void *data); + + +/** + * nrf_wifi_osal_llist_alloc() - Allocate a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Allocates a linked list. + * + * Return: + * Pass: Pointer to the allocated linked list. + * Error: NULL. + */ +void *nrf_wifi_osal_llist_alloc(struct nrf_wifi_osal_priv *opriv); + + +/** + * nrf_wifi_osal_llist_free() - Free a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * + * Frees a linked list(@llist) allocated by @nrf_wifi_osal_llist_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_llist_free(struct nrf_wifi_osal_priv *opriv, + void *llist); + + +/** + * nrf_wifi_osal_llist_init() - Initialize a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * + * Initializes a linked list(@llist) allocated by @nrf_wifi_osal_llist_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_llist_init(struct nrf_wifi_osal_priv *opriv, + void *llist); + + +/** + * nrf_wifi_osal_llist_add_node_tail() - Add a node to the tail of a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * @llist_node: Pointer to a linked list node. + * + * Adds a linked list node(@llist_node) allocated by @nrf_wifi_osal_llist_node_alloc + * to the tail of a linked list(@llist) allocated by @nrf_wifi_osal_llist_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_llist_add_node_tail(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node); + + +/** + * nrf_wifi_osal_llist_add_node_head() - Add a node to the head of a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * @llist_node: Pointer to a linked list node. + * + * Adds a linked list node(@llist_node) allocated by @nrf_wifi_osal_llist_node_alloc + * to the head of a linked list(@llist) allocated by @nrf_wifi_osal_llist_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_llist_add_node_head(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node); +/** + * nrf_wifi_osal_llist_get_node_head() - Get the head of a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * + * Returns the head node from a linked list(@llist) while still leaving the + * node as part of the linked list. If the linked list is empty + * returns NULL. + * + * Return: + * Pass: Pointer to the head of the linked list. + * Error: NULL. + */ +void *nrf_wifi_osal_llist_get_node_head(struct nrf_wifi_osal_priv *opriv, + void *llist); + + +/** + * nrf_wifi_osal_llist_get_node_nxt() - Get the next node in a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * @llist_node: Pointer to a linked list node. + * + * Return the node next to the node passed in the @llist_node parameter. + * The node returned is not removed from the linked list. + * + * Return: + * Pass: Pointer to the next node in the linked list. + * Error: NULL. + */ +void *nrf_wifi_osal_llist_get_node_nxt(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node); + + +/** + * nrf_wifi_osal_llist_del_node() - Delete node from a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * @llist_node: Pointer to a linked list node. + * + * Removes the node passed in the @llist_node parameter from the linked list + * passed in the @llist parameter. + * + * Return: None. + */ +void nrf_wifi_osal_llist_del_node(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node); + + +/** + * nrf_wifi_osal_llist_len() - Get length of a linked list. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @llist: Pointer to a linked list. + * + * Returns the length of the linked list(@llist). + * + * Return: Linked list length in bytes. + */ +unsigned int nrf_wifi_osal_llist_len(struct nrf_wifi_osal_priv *opriv, + void *llist); + + +/** + * nrf_wifi_osal_nbuf_alloc() - Allocate a network buffer + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @size: Size in bytes of the network buffer to allocated. + * + * Allocates a network buffer of size @size. + * + * Return: + * Pass: Pointer to the allocated network buffer. + * Error: NULL. + */ +void *nrf_wifi_osal_nbuf_alloc(struct nrf_wifi_osal_priv *opriv, + unsigned int size); + + +/** + * nrf_wifi_osal_nbuf_free() - Free a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * + * Frees a network buffer(@nbuf) which was allocated by + * @nrf_wifi_osal_nbuf_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_nbuf_free(struct nrf_wifi_osal_priv *opriv, + void *nbuf); + + +/** + * nrf_wifi_osal_nbuf_headroom_res() - Reserve headroom space in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * @size: Size in bytes of the headroom to be reserved. + * + * Reserves headroom of size(@size) bytes at the beginning of the data area of + * a network buffer(@nbuf). + * + * Return: None. + */ +void nrf_wifi_osal_nbuf_headroom_res(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size); + + + +/** + * nrf_wifi_osal_nbuf_headroom_get() - Get the size of the headroom in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * + * Gets the size of the reserved headroom at the beginning + * of the data area of a network buffer(@nbuf). + * + * Return: Size of the network buffer data headroom in bytes. + */ +unsigned int nrf_wifi_osal_nbuf_headroom_get(struct nrf_wifi_osal_priv *opriv, + void *nbuf); + +/** + * nrf_wifi_osal_nbuf_data_size() - Get the size of data in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * + * Gets the size of the data area of a network buffer(@nbuf). + * + * Return: Size of the network buffer data in bytes. + */ +unsigned int nrf_wifi_osal_nbuf_data_size(struct nrf_wifi_osal_priv *opriv, + void *nbuf); + + +/** + * nrf_wifi_osal_nbuf_data_get() - Get a handle to the data in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * + * Gets the pointer to the data area of a network buffer(@nbuf). + * + * Return: + * Pass: Pointer to the data in the network buffer. + * Error: NULL. + */ +void *nrf_wifi_osal_nbuf_data_get(struct nrf_wifi_osal_priv *opriv, + void *nbuf); + + +/** + * nrf_wifi_osal_nbuf_data_put() - Extend the tail portion of the data + * in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * @size: Size in bytes, of the extension. + * + * Increases the data area of a network buffer(@nbuf) by @size bytes at the + * end of the area and returns the pointer to the beginning of + * the data area. + * + * Return: + * Pass: Updated pointer to the data in the network buffer. + * Error: NULL. + */ +void *nrf_wifi_osal_nbuf_data_put(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size); + + +/** + * nrf_wifi_osal_nbuf_data_push() - Extend the head portion of the data + * in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * @size: Size in bytes, of the extension. + * + * Increases the data area of a network buffer(@nbuf) by @size bytes at the + * start of the area and returns the pointer to the beginning of the + * data area. + * + * Return: + * Pass: Updated pointer to the data in the network buffer. + * Error: NULL. + */ +void *nrf_wifi_osal_nbuf_data_push(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size); + + +/** + * nrf_wifi_osal_nbuf_data_pull() - Reduce the head portion of the data + * in a network buffer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * @size: Size in bytes, of the reduction. + * + * Decreases the data area of a network buffer(@nbuf) by @size bytes at the + * start of the area and returns the pointer to the beginning + * of the data area. + * + * Return: + * Pass: Updated pointer to the data in the network buffer. + * Error: NULL. + */ +void *nrf_wifi_osal_nbuf_data_pull(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size); + + +/** + * nrf_wifi_osal_nbuf_get_priority() - Get the priority of a network buffer. + * + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @nbuf: Pointer to a network buffer. + * + * Gets the priority of a network buffer(@nbuf). + * + * Return: Priority of the network buffer. + */ +unsigned char nrf_wifi_osal_nbuf_get_priority(struct nrf_wifi_osal_priv *opriv, + void *nbuf); +/** + * nrf_wifi_osal_tasklet_alloc() - Allocate a tasklet. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @type: Type of tasklet. + * + * Allocates a tasklet structure and returns a pointer to it. + * + * Return: + * Pass: Pointer to the tasklet instance allocated. + * Error: NULL. + */ +void *nrf_wifi_osal_tasklet_alloc(struct nrf_wifi_osal_priv *opriv, int type); + + +/** + * nrf_wifi_osal_tasklet_free() - Free a tasklet. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @tasklet: Pointer to a tasklet. + * + * Frees a tasklet structure that had been allocated using + * @nrf_wifi_osal_tasklet_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_tasklet_free(struct nrf_wifi_osal_priv *opriv, + void *tasklet); + + +/** + * nrf_wifi_osal_tasklet_init() - Initialize a tasklet. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @tasklet: Pointer to a tasklet. + * @callbk_fn: Callback function to be invoked by the tasklet. + * @data: Data to be passed to the callback function when the tasklet + * invokes it. + * + * Initializes a tasklet structure(@tasklet) that had been allocated using + * @nrf_wifi_osal_tasklet_alloc. Needs to be passed a callback + * function (@callbk_fn) which should get invoked when the tasklet is + * scheduled and the data(@data) which needs to be passed to the + * callback function. + * + * Return: None. + */ +void nrf_wifi_osal_tasklet_init(struct nrf_wifi_osal_priv *opriv, + void *tasklet, + void (*callbk_fn)(unsigned long), + unsigned long data); + + +/** + * nrf_wifi_osal_tasklet_schedule() - Schedule a tasklet. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @tasklet: Pointer to a tasklet. + * + * Schedules a tasklet that had been allocated using + * @nrf_wifi_osal_tasklet_alloc and initialized using + * @nrf_wifi_osal_tasklet_init. + * + * Return: None. + */ +void nrf_wifi_osal_tasklet_schedule(struct nrf_wifi_osal_priv *opriv, + void *tasklet); + + +/** + * nrf_wifi_osal_tasklet_kill() - Terminate a tasklet. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @tasklet: Pointer to a tasklet. + * + * Terminates a tasklet(@tasklet) that had been scheduled by + * @nrf_wifi_osal_tasklet_schedule. + * + * Return: None. + */ +void nrf_wifi_osal_tasklet_kill(struct nrf_wifi_osal_priv *opriv, + void *tasklet); + + +/** + * nrf_wifi_osal_sleep_ms() - Sleep for a specified duration in milliseconds. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @msecs: Sleep duration in milliseconds. + * + * Puts the calling thread to sleep for atleast @msecs milliseconds. + * + * Return: None. + */ +void nrf_wifi_osal_sleep_ms(struct nrf_wifi_osal_priv *opriv, + unsigned int msecs); + + +/** + * nrf_wifi_osal_delay_us() - Delay for a specified duration in microseconds. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @usecs: Delay duration in microseconds. + * + * Delays execution of calling thread for @usecs microseconds. This is + * busy-waiting and won't allow other threads to execute during + * the time lapse. + * + * Return: None. + */ +void nrf_wifi_osal_delay_us(struct nrf_wifi_osal_priv *opriv, + unsigned long usecs); + + +/** + * nrf_wifi_osal_time_get_curr_us() - Get current system uptime in microseconds. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Gets the current system uptime in microseconds. + * + * Return: System uptime in microseconds. + */ +unsigned long nrf_wifi_osal_time_get_curr_us(struct nrf_wifi_osal_priv *opriv); + + +/** + * nrf_wifi_osal_time_elapsed_us() - Get elapsed time in microseconds + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @start_time_us: The timestamp in microseconds from which elapsed + * time is to be measured. + * + * Returns the time elapsed in microseconds since some + * time instant (@start_time_us). + * + * Return: Elapsed time in microseconds. + */ +unsigned int nrf_wifi_osal_time_elapsed_us(struct nrf_wifi_osal_priv *opriv, + unsigned long start_time_us); + + + +/** + * nrf_wifi_osal_bus_pcie_init() - Initialize a PCIe driver. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @dev_name: Name of the PCIe device. + * @vendor_id: Vendor ID of the PCIe device. + * @sub_vendor_id: Sub-vendor ID of the PCIE device. + * @device_id: Device ID of the PCIe device. + * @sub_device_id: Sub-device ID of the PCIe device. + * + * Registers a PCIe device driver to the OS's PCIe core. + * + * Return: OS specific PCIe device context. + */ +void *nrf_wifi_osal_bus_pcie_init(struct nrf_wifi_osal_priv *opriv, + const char *dev_name, + unsigned int vendor_id, + unsigned int sub_vendor_id, + unsigned int device_id, + unsigned int sub_device_id); + + +/** + * nrf_wifi_osal_bus_pcie_deinit() - Deinitialize a PCIe device driver. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_priv: OS specific PCIe context. + * + * This API should be called when the PCIe device driver is + * to be unregistered from the OS's PCIe core. + * + * Return: None. + */ +void nrf_wifi_osal_bus_pcie_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_priv); + + +/** + * nrf_wifi_osal_bus_pcie_dev_add() - Add a PCIe device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @osal_pcie_dev_ctx: Pointer to the OSAL PCIe device context. + * + * Function to be invoked when a matching PCIe device is added to the system. + * It expects the pointer to a OS specific PCIe device context to be returned. + * + * Return: OS specific PCIe device context. + */ +void *nrf_wifi_osal_bus_pcie_dev_add(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_priv, + void *osal_pcie_dev_ctx); + + +/** + * nrf_wifi_osal_bus_pcie_dev_rem() - Remove a PCIe device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: Pointer to the OS specific PCIe device context which was + * returned by @nrf_wifi_osal_bus_pcie_dev_add. + * + * Function to be invoked when a matching PCIe device is removed from the system. + * + * Return: None. + */ +void nrf_wifi_osal_bus_pcie_dev_rem(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx); + + +/** + * nrf_wifi_osal_bus_pcie_dev_init() - Initialize a PCIe device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: Pointer to the OS specific PCIe device context which was + * returned by @nrf_wifi_osal_bus_pcie_dev_add. + * + * Function to be invoked when a PCIe device is to be initialized. + * + * Return: + * Pass: NRF_WIFI_STATUS_SUCCESS. + * Fail: NRF_WIFI_STATUS_FAIL. + */ +enum nrf_wifi_status nrf_wifi_osal_bus_pcie_dev_init(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx); + + +/** + * nrf_wifi_osal_bus_pcie_dev_deinit() - Deinitialize a PCIe device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: Pointer to the OS specific PCIe device context which was + * returned by @nrf_wifi_osal_bus_pcie_dev_add. + * + * Function to be invoked when a PCIe device is to be deinitialized. + * + * Return: None. + */ +void nrf_wifi_osal_bus_pcie_dev_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx); + + +/** + * nrf_wifi_osal_bus_pcie_dev_intr_reg() - Register a interrupt handler for a PCIe device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: OS specific PCIe device context. + * @callbk_data: Data to be passed to the ISR. + * @callbk_fn: ISR to be invoked on receiving an interrupt. + * + * Registers an interrupt handler to the OS. This API also passes the callback + * data to be passed to the ISR when an interrupt is received. + * + * Return: + * Pass: NRF_WIFI_STATUS_SUCCESS. + * Fail: NRF_WIFI_STATUS_FAIL. + */ +enum nrf_wifi_status nrf_wifi_osal_bus_pcie_dev_intr_reg(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + void *callbk_data, + int (*callbk_fn)(void *callbk_data)); + + +/** + * nrf_wifi_osal_bus_pcie_dev_intr_unreg() - Unregister an interrupt handler for a PCIe device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: OS specific PCIe device context. + * + * Unregisters the interrupt handler that was registered using + * @nrf_wifi_osal_bus_pcie_dev_intr_reg. + * + * Return: None. + */ +void nrf_wifi_osal_bus_pcie_dev_intr_unreg(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx); + + +/** + * nrf_wifi_osal_bus_pcie_dev_dma_map() - Map host memory for DMA access. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: Pointer to a OS specific PCIe device handle. + * @virt_addr: Virtual host address to be DMA mapped. + * @size: Size in bytes of the host memory to be DMA mapped. + * @dir: DMA direction. + * + * Maps host memory of @size bytes pointed to by the virtual address + * @virt_addr to be used by the device(@dma_dev) for DMAing contents. + * The contents are available for DMAing to the device if @dir has a + * value of @NRF_WIFI_OSAL_DMA_DIR_TO_DEV. Conversely the device can DMA + * contents to the host memory if @dir has a value of + * @NRF_WIFI_OSAL_DMA_DIR_FROM_DEV. The function returns the DMA address + * of the mapped memory. + * + * Return: + * Pass: Pointer to the DMA mapped physical address. + * Error: NULL. + */ +void *nrf_wifi_osal_bus_pcie_dev_dma_map(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + void *virt_addr, + size_t size, + enum nrf_wifi_osal_dma_dir dir); + + +/** + * nrf_wifi_osal_bus_pcie_dev_dma_unmap() - Unmap DMA mapped host memory. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: Pointer to a OS specific PCIe device handle. + * @dma_addr: DMA mapped physical host memory address. + * @size: Size in bytes of the DMA mapped host memory. + * @dir: DMA direction. + * + * Unmaps the host memory which was mapped for DMA using @nrf_wifi_osal_dma_map. + * + * Return: None. + */ +void nrf_wifi_osal_bus_pcie_dev_dma_unmap(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + void *dma_addr, + size_t size, + enum nrf_wifi_osal_dma_dir dir); + + +/** + * nrf_wifi_osal_bus_pcie_dev_host_map_get() - Get host mapped address for a PCIe device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_pcie_dev_ctx: OS specific PCIe device context. + * @host_map: Host map address information. + * + * Gets the host map address for a PCIe device. + * + * Return: None. + */ +void nrf_wifi_osal_bus_pcie_dev_host_map_get(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + struct nrf_wifi_osal_host_map *host_map); + + + + +/** + * nrf_wifi_osal_bus_qspi_init() - Initialize a qspi driver. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Registers a qspi device driver to the OS's qspi core. + * + * Return: OS specific qspi device context. + */ +void *nrf_wifi_osal_bus_qspi_init(struct nrf_wifi_osal_priv *opriv); + + +/** + * nrf_wifi_osal_bus_qspi_deinit() - Deinitialize a qspi device driver. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_priv: OS specific qspi context. + * + * This API should be called when the qspi device driver is + * to be unregistered from the OS's qspi core. + * + * Return: None. + */ +void nrf_wifi_osal_bus_qspi_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv); + + +/** + * nrf_wifi_osal_bus_qspi_dev_add() - Add a qspi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @osal_qspi_dev_ctx: Pointer to the OSAL qspi device context. + * + * Function to be invoked when a matching qspi device is added to the system. + * It expects the pointer to a OS specific qspi device context to be returned. + * + * Return: OS specific qspi device context. + */ +void *nrf_wifi_osal_bus_qspi_dev_add(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv, + void *osal_qspi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_qspi_dev_rem() - Remove a qspi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_dev_ctx: Pointer to the OS specific qspi device context which was + * returned by @nrf_wifi_osal_bus_qspi_dev_add. + * + * Function to be invoked when a matching qspi device is removed from the system. + * + * Return: None. + */ +void nrf_wifi_osal_bus_qspi_dev_rem(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_qspi_dev_init() - Initialize a qspi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_dev_ctx: Pointer to the OS specific qspi device context which was + * returned by @nrf_wifi_osal_bus_qspi_dev_add. + * + * Function to be invoked when a qspi device is to be initialized. + * + * Return: + * Pass: NRF_WIFI_STATUS_SUCCESS. + * Fail: NRF_WIFI_STATUS_FAIL. + */ +enum nrf_wifi_status nrf_wifi_osal_bus_qspi_dev_init(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_qspi_dev_deinit() - Deinitialize a qspi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_dev_ctx: Pointer to the OS specific qspi device context which was + * returned by @nrf_wifi_osal_bus_qspi_dev_add. + * + * Function to be invoked when a qspi device is to be deinitialized. + * + * Return: None. + */ +void nrf_wifi_osal_bus_qspi_dev_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_qspi_dev_intr_reg() - Register a interrupt handler for a qspi device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_dev_ctx: OS specific qspi device context. + * @callbk_data: Data to be passed to the ISR. + * @callbk_fn: ISR to be invoked on receiving an interrupt. + * + * Registers an interrupt handler to the OS. This API also passes the callback + * data to be passed to the ISR when an interrupt is received. + * + * Return: + * Pass: NRF_WIFI_STATUS_SUCCESS. + * Fail: NRF_WIFI_STATUS_FAIL. + */ +enum nrf_wifi_status nrf_wifi_osal_bus_qspi_dev_intr_reg(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx, + void *callbk_data, + int (*callbk_fn)(void *callbk_data)); + + +/** + * nrf_wifi_osal_bus_qspi_dev_intr_unreg() - Unregister an interrupt handler for a qspi device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_dev_ctx: OS specific qspi device context. + * + * Unregisters the interrupt handler that was registered using + * @nrf_wifi_osal_bus_qspi_dev_intr_reg. + * + * Return: None. + */ +void nrf_wifi_osal_bus_qspi_dev_intr_unreg(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_qspi_dev_host_map_get() - Get host mapped address for a qspi device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_qspi_dev_ctx: OS specific qspi device context. + * @host_map: Host map address information. + * + * Gets the host map address for a qspi device. + * + * Return: None. + */ +void nrf_wifi_osal_bus_qspi_dev_host_map_get(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx, + struct nrf_wifi_osal_host_map *host_map); + +/** + * nrf_wifi_osal_qspi_read_reg32() - Read value from a 32 bit register on a + * QSPI slave device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @addr: Address of the register to read from. + * + * Reads value from a 32 bit device register at address(@addr) on + * a QSPI slave device. + * + * Return: 32 bit value read from register. + */ +unsigned int nrf_wifi_osal_qspi_read_reg32(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr); + +/** + * nrf_wifi_osal_qspi_write_reg32() - + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @addr: Address of the register to write to. + * @val: Value to be written to the register. + * + * Writes a 32 bit value (@val) to a 32 bit device register at address(@addr) + * on a QSPI slave device. + * + * Return: None. + */ +void nrf_wifi_osal_qspi_write_reg32(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr, + unsigned int val); + +/** + * nrf_wifi_osal_qspi_cpy_from() - + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @dest: + * @src: + * @count: + * + * + * Return: None. + */ +void nrf_wifi_osal_qspi_cpy_from(struct nrf_wifi_osal_priv *opriv, + void *priv, + void *dest, + unsigned long addr, + size_t count); + +/** + * nrf_wifi_osal_qspi_cpy_to() - + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @dest: + * @src: + * @count: + * + * + * Return: None. + */ +void nrf_wifi_osal_qspi_cpy_to(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr, + const void *src, + size_t count); + +/** + * nrf_wifi_osal_bus_spi_init() - Initialize a spi driver. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Registers a spi device driver to the OS's spi core. + * + * Return: OS specific spi device context. + */ +void *nrf_wifi_osal_bus_spi_init(struct nrf_wifi_osal_priv *opriv); + +/** + * nrf_wifi_osal_bus_spi_deinit() - Deinitialize a spi device driver. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_priv: OS specific spi context. + * + * This API should be called when the spi device driver is + * to be unregistered from the OS's spi core. + * + * Return: None. + */ +void nrf_wifi_osal_bus_spi_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_spi_priv); + + +/** + * nrf_wifi_osal_bus_spi_dev_add() - Add a spi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @osal_spi_dev_ctx: Pointer to the OSAL spi device context. + * + * Function to be invoked when a matching spi device is added to the system. + * It expects the pointer to a OS specific spi device context to be returned. + * + * Return: OS specific spi device context. + */ +void *nrf_wifi_osal_bus_spi_dev_add(struct nrf_wifi_osal_priv *opriv, + void *os_spi_priv, + void *osal_spi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_spi_dev_rem() - Remove a spi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_dev_ctx: Pointer to the OS specific spi device context which was + * returned by @nrf_wifi_osal_bus_spi_dev_add. + * + * Function to be invoked when a matching spi device is removed from the system. + * + * Return: None. + */ +void nrf_wifi_osal_bus_spi_dev_rem(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_spi_dev_init() - Initialize a spi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_dev_ctx: Pointer to the OS specific spi device context which was + * returned by @nrf_wifi_osal_bus_spi_dev_add. + * + * Function to be invoked when a spi device is to be initialized. + * + * Return: + * Pass: nrf_wifi_STATUS_SUCCESS. + * Fail: nrf_wifi_STATUS_FAIL. + */ +enum nrf_wifi_status nrf_wifi_osal_bus_spi_dev_init(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_spi_dev_deinit() - Deinitialize a spi device instance. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_dev_ctx: Pointer to the OS specific spi device context which was + * returned by @nrf_wifi_osal_bus_spi_dev_add. + * + * Function to be invoked when a spi device is to be deinitialized. + * + * Return: None. + */ +void nrf_wifi_osal_bus_spi_dev_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_spi_dev_intr_reg() - Register a interrupt handler for a spi device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_dev_ctx: OS specific spi device context. + * @callbk_data: Data to be passed to the ISR. + * @callbk_fn: ISR to be invoked on receiving an interrupt. + * + * Registers an interrupt handler to the OS. This API also passes the callback + * data to be passed to the ISR when an interrupt is received. + * + * Return: + * Pass: nrf_wifi_STATUS_SUCCESS. + * Fail: nrf_wifi_STATUS_FAIL. + */ +enum nrf_wifi_status nrf_wifi_osal_bus_spi_dev_intr_reg(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + void *callbk_data, + int (*callbk_fn)(void *callbk_data)); + + +/** + * nrf_wifi_osal_bus_spi_dev_intr_unreg() - Unregister an interrupt handler for a spi device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_dev_ctx: OS specific spi device context. + * + * Unregisters the interrupt handler that was registered using + * @nrf_wifi_osal_bus_spi_dev_intr_reg. + * + * Return: None. + */ +void nrf_wifi_osal_bus_spi_dev_intr_unreg(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx); + + +/** + * nrf_wifi_osal_bus_spi_dev_host_map_get() - Get host mapped address for a spi device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @os_spi_dev_ctx: OS specific spi device context. + * @host_map: Host map address information. + * + * Gets the host map address for a spi device. + * + * Return: None. + */ +void nrf_wifi_osal_bus_spi_dev_host_map_get(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + struct nrf_wifi_osal_host_map *host_map); + +/** + * nrf_wifi_osal_spi_read_reg32() - Read value from a 32 bit register on a + * Linux SPI slave device. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @addr: Address of the register to read from. + * + * Reads value from a 32 bit device register at address(@addr) on + * a QSPI slave device. + * + * Return: 32 bit value read from register. + */ +unsigned int nrf_wifi_osal_spi_read_reg32(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr); + +/** + * nrf_wifi_osal_spi_write_reg32() - + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @addr: Address of the register to write to. + * @val: Value to be written to the register. + * + * Writes a 32 bit value (@val) to a 32 bit device register at address(@addr) + * on a Linux SPI slave device. + * + * Return: None. + */ +void nrf_wifi_osal_spi_write_reg32(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr, + unsigned int val); + +/** + * nrf_wifi_osal_spi_cpy_from() - + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @dest: + * @src: + * @count: + * + * + * Return: None. + */ +void nrf_wifi_osal_spi_cpy_from(struct nrf_wifi_osal_priv *opriv, + void *priv, + void *dest, + unsigned long addr, + size_t count); + +/** + * nrf_wifi_osal_spi_cpy_to() - + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @priv: + * @dest: + * @src: + * @count: + * + * + * Return: None. + */ +void nrf_wifi_osal_spi_cpy_to(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr, + const void *src, + size_t count); + + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +/** + * nrf_wifi_osal_timer_alloc() - Allocate a timer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * + * Allocates a timer instance. + * + * Return: Pointer to the allocated timer instance. + */ +void *nrf_wifi_osal_timer_alloc(struct nrf_wifi_osal_priv *opriv); + + +/** + * nrf_wifi_osal_timer_free() - Free a timer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @timer: Pointer to a timer instance. + * + * Frees/Deallocates a timer that has been allocated using + * @nrf_wifi_osal_timer_alloc. + * + * Return: None. + */ +void nrf_wifi_osal_timer_free(struct nrf_wifi_osal_priv *opriv, + void *timer); + + +/** + * nrf_wifi_osal_timer_init() - Initialize a timer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @timer: Pointer to a timer instance. + * @callbk_fn: Callback function to be invoked when the timer expires. + * @data: Data to be passed to the callback function. + * + * Initializes a timer that has been allocated using @nrf_wifi_osal_timer_alloc + * Need to pass (@callbk_fn) callback function with the data(@data) to be + * passed to the callback function, whenever the timer expires. + * + * Return: None. + */ +void nrf_wifi_osal_timer_init(struct nrf_wifi_osal_priv *opriv, + void *timer, + void (*callbk_fn)(unsigned long), + unsigned long data); + + +/** + * nrf_wifi_osal_timer_schedule() - Schedule a timer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @timer: Pointer to a timer instance. + * @duration: Duration of the timer in seconds. + * + * Schedules a timer with a @duration seconds that has been allocated using + * @nrf_wifi_osal_timer_alloc and initialized with @nrf_wifi_osal_timer_init. + * + * Return: None. + */ +void nrf_wifi_osal_timer_schedule(struct nrf_wifi_osal_priv *opriv, + void *timer, + unsigned long duration); + + +/** + * nrf_wifi_osal_timer_kill() - Kill a timer. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @timer: Pointer to a timer instance. + * + * Kills a timer that has been scheduled using @nrf_wifi_osal_timer_schedule. + * + * Return: None. + */ +void nrf_wifi_osal_timer_kill(struct nrf_wifi_osal_priv *opriv, + void *timer); + + + +int nrf_wifi_osal_bus_qspi_ps_sleep(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv); + +int nrf_wifi_osal_bus_qspi_ps_wake(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv); + +int nrf_wifi_osal_bus_qspi_ps_status(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + +/** + * nrf_wifi_osal_assert() - Assert a condition with a value. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @test: Variable to be tested. + * @val: Value to be checked for the @test + * @op: type of operation to be done during assertion check. + * @msg: Assertion message. + * + * Compares @test aith @val. If true prints assert message. + * + * Return: + * None + */ +void nrf_wifi_osal_assert(struct nrf_wifi_osal_priv *opriv, + int test, + int val, + enum nrf_wifi_assert_op_type op, + char *msg); + +/** + * nrf_wifi_osal_strlen() - Gives the length of the string @str. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @str: Pointer to the memory location of the string. + * + * Calculates the length of the string pointed to by @str + * + * Return: + * returns the number of bytes of the string @str. + */ +unsigned int nrf_wifi_osal_strlen(struct nrf_wifi_osal_priv *opriv, + const void *str); + +/** + * nrf_wifi_osal_mem_cmp() - Compare contents from one memory location to another. + * @opriv: Pointer to the OSAL context returned by the @nrf_wifi_osal_init API. + * @addr1: Pointer to the memory location of first address. + * @addr2: Pointer to the memory location of second address. + * @count: Number of bytes to be compared. + * + * Compares @count number of bytes from @addr1 location in memory to @addr2 + * location in memory. + * + * Return: + * returns an integer less than, equal to, or greater than zero + */ +int nrf_wifi_osal_mem_cmp(struct nrf_wifi_osal_priv *opriv, + const void *addr1, + const void *addr2, + size_t count); +#endif /* __OSAL_API_H__ */ diff --git a/nrf_wifi/os_if/inc/osal_ops.h b/nrf_wifi/os_if/inc/osal_ops.h new file mode 100644 index 0000000000..0d9d876002 --- /dev/null +++ b/nrf_wifi/os_if/inc/osal_ops.h @@ -0,0 +1,349 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing OPs declarations for the + * OSAL Layer of the Wi-Fi driver. + */ + +#ifndef __OSAL_OPS_H__ +#define __OSAL_OPS_H__ + +#include +#include "osal_structs.h" + + +/** + * struct nrf_wifi_osal_ops - Ops to be provided by a specific OS implementation. + * @init: Initialize the OS shim. This is expected to return any OS Shim + * specific context information that might be needed. + * + * @mem_alloc: Allocate memory of @size bytes and return a pointer to the start + * of the memory allocated. + * @mem_zalloc: Allocate memory of @size bytes, zero out the memory and return + * a pointer to the start of the zeroed out memory. + * @mem_free: Free up memory which has been allocated using @mem_alloc or + * @mem_zalloc. + * @mem_cpy: Copy @count number of bytes from @src location in memory to @dest + * location in memory. + * @mem_set: Fill a block of memory of @size bytes starting at @start with a + * particular value represented by @val. + * @mem_cmp: Compares @size bytes starting at @addr1 with @addr2 location in + * memory. + * + * @iomem_mmap: Map IO memory of @size pointed to by @addr into CPU + * space. + * @iomem_unmap: Unmap IO memory from CPU space that was mapped using + * @iomem_mmap. + * @iomem_read_reg32: Read the value from a 32 bit device register using a memory + * mapped address(@addr). + * @iomem_write_reg32: Write a 32 bit value (@val) to a 32 bit device register + * using a memory mapped address(@addr). + * @iomem_cpy_from: Copy a block of data of size @count bytes from memory + * mapped device memory(@src) to host memory(@dest). + * @iomem_cpy_to: Copy a block of data of size @count bytes from host + * memory (@src) to memory mapped device memory(@dest). + * + * @spinlock_alloc: Allocate a busy lock. + * @spinlock_free: Free a busy lock (@lock) allocated by @spinlock_alloc + * @spinlock_init: Initialize a busy lock (@lock) allocated by @spinlock_alloc. + * @spinlock_take: Acquire a busy lock (@lock) allocated by @spinlock_alloc. + * @spinlock_rel: Release a busy lock (@lock) acquired by @spinlock_take. + * + * @spinlock_irq_take: Save interrupt states (@flags), disable interrupts and + * take a lock (@lock). + * @spinlock_irq_rel: Restore interrupt states (@flags) and release lock (@lock) + * acquired using @spinlock_irq_take. + * + * @log_dbg: Log a debug message. + * @log_info: Log an informational message. + * @log_err: Log an error message. + * + * @llist_node_alloc: Allocate a linked list node. + * @llist_node_free: Free a linked list node which was allocated by + * @llist_node_alloc. + * @llist_node_data_get: Get the pointer to the data which the linked list node + * points to. + * @llist_node_data_set: Store the pointer to the data in the linked list node. + * + * @llist_alloc: Allocate a linked list. + * @llist_free: Free a linked list allocated by @llist_alloc. + * @llist_init: Initialize a linked list allocated by @llist_alloc. + * @llist_add_node_tail: Add a linked list node allocated by @llist_node_alloc + * to the tail of a linked list allocated by @llist_alloc. + * @llist_add_node_head: Add a linked list node allocated by @llist_node_alloc + * to the head of a linked list allocated by @llist_alloc. + * @llist_get_node_head: Return the head node from a linked list while still + * leaving the node as part of the linked list. If the + * linked list is empty return NULL. + * @llist_get_node_nxt: Return the node next to the node passed in the + * @llist_node parameter. The node returned is not removed + * from the linked list. + * @llist_del_node: Remove the node passed in the @llist_node parameter from the + * linked list passed in the @llist parameter. + * @llist_len: Return the length of the linked list. + * + * @nbuf_alloc: Allocate a network buffer of size @size. + * @nbuf_free: Free a network buffer(@nbuf) which was allocated by @nbuf_alloc. + * @nbuf_headroom_res: Reserve headroom at the beginning of the data area of a + * network buffer(@nbuf). + * @nbuf_headroom_get: Get the size of the reserved headroom at the beginning + * of the data area of a network buffer(@nbuf). + * @nbuf_data_size: Get the size of the data area of a network buffer(@nbuf). + * @nbuf_data_get: Get the pointer to the data area of a network buffer(@nbuf). + * @nbuf_data_put: Increase the data area of a network buffer(@nbuf) by @size + * bytes at the end of the area and return the pointer to the + * beginning of the data area. + * @nbuf_data_push: Increase the data area of a network buffer(@nbuf) by @size + * bytes at the start of the area and return the pointer to the + * beginning of the data area. + * @nbuf_data_pull: Decrease the data area of a network buffer(@nbuf) by @size + * bytes at the start of the area and return the pointer to the + * beginning of the data area. + * @nbuf_get_priority: Get the priority of a network buffer(@nbuf). + * + * @tasklet_alloc: Allocate a tasklet structure and return a pointer to it. + * @tasklet_free: Free a tasklet structure that had been allocated using + * @tasklet_alloc. + * @tasklet_init: Initialize a tasklet structure(@tasklet) that had been + * allocated using @tasklet_alloc. Need to pass a callback + * function (@callback) which should get invoked when the + * tasklet is scheduled and the data(@data) to be passed to the + * callback function. + * @tasklet_schedule: Schedule a tasklet that had been allocated using + * @tasklet_alloc and initialized using @tasklet_init. + * @tasklet_kill: Terminate a tasklet that had been scheduled + * @tasklet_schedule. + * + * + * @sleep_ms: Sleep for @msecs milliseconds. + * @delay_us: Delay for @usecs microseconds. + * + * @time_get_curr_us: Get the current time of the day in microseconds. + * @time_elapsed_us: Return the time elapsed in microseconds since + * some time instant (@start_time_us). + * + * @bus_pcie_reg_drv: This Op will be called when a PCIe device driver is to be + * registered to the OS's PCIe core. + * @bus_pcie_unreg_drv: This Op will be called when the PCIe device driver is + * to be unregistered from the OS's PCIe core. + * @bus_pcie_dev_add: This Op will be called when a new PCIe device has + * been detected. This will return a pointer to a OS + * specific PCIe device context. + * @bus_pcie_dev_rem: This Op will be called when a PCIe device has been + * removed. + * @bus_pcie_dev_intr_reg: Register the interrupt to the OS for a PCIe device. + * This Op also passes the callback data and the + * function to be called with this data when an + * interrupt is received. + * @bus_pcie_dev_intr_unreg: Unregister the interrupt that was registered using + * @bus_pcie_dev_intr_reg. + * @bus_pcie_dev_dma_map: Map host memory of size @size pointed to by the virtual address + * @virt_addr to be used by the PCIe device for DMAing contents. + * The contents are available for DMAing to the device if @dir has a + * value of @NRF_WIFI_OSAL_DMA_DIR_TO_DEV. Conversely the device can DMA + * contents to the host memory if @dir has a value of + * @NRF_WIFI_OSAL_DMA_DIR_FROM_DEV. The function returns the DMA address + * of the mapped memory. + * @bus_pcie_dev_dma_unmap: Unmap the host memory which was mapped for DMA using + * @bus_pcie_dev_dma_map. + * The address that will be passed to this Op to be unmapped will + * be the DMA address returned by @dma_bus_pcie_dev_map. + * @bus_pcie_dev_host_map_get: Get the host mapped address for a PCIe device. + * + * @timer_alloc: Allocates a timer and returns a pointer. + * @timer_free: Frees/Deallocates a timer that has been allocated + * using @timer_alloc. + * @timer_init: Initializes a timer that has been allocated using @timer_alloc + * Need to pass (@callback) callback function with + * the data(@data) to be passed to the callback function, + * whenever the timer expires. + * @timer_schedule: Schedules a timer with a @duration + * that has been allocated using @timer_alloc and + * initialized with @timer_init. + * @timer_kill: Kills a timer that has been scheduled @timer_schedule. + * + * @assert: Asserts a @test_val with the @val for operation @op. + * If true prints @assert_msg. + * + * @strlen: Calculate the length of the string @str. + * + * This structure exposes Ops which need to be implemented by the underlying OS + * in order for the WLAN driver to work. The Ops can be directly mapped to OS + * primitives where a one-to-one mapping is available. In case a mapping is not + * available an equivalent function will need to be implemented and that + * function will then need to be mapped to the corresponding Op. + * + */ +struct nrf_wifi_osal_ops { + void *(*mem_alloc)(size_t size); + void *(*mem_zalloc)(size_t size); + void (*mem_free)(void *buf); + void *(*mem_cpy)(void *dest, const void *src, size_t count); + void *(*mem_set)(void *start, int val, size_t size); + int (*mem_cmp)(const void *addr1, const void *addr2, size_t size); + + void *(*iomem_mmap)(unsigned long addr, unsigned long size); + void (*iomem_unmap)(volatile void *addr); + unsigned int (*iomem_read_reg32)(const volatile void *addr); + void (*iomem_write_reg32)(volatile void *addr, unsigned int val); + void (*iomem_cpy_from)(void *dest, const volatile void *src, size_t count); + void (*iomem_cpy_to)(volatile void *dest, const void *src, size_t count); + + unsigned int (*qspi_read_reg32)(void *priv, unsigned long addr); + void (*qspi_write_reg32)(void *priv, unsigned long addr, unsigned int val); + void (*qspi_cpy_from)(void *priv, void *dest, unsigned long addr, size_t count); + void (*qspi_cpy_to)(void *priv, unsigned long addr, const void *src, size_t count); + + unsigned int (*spi_read_reg32)(void *priv, unsigned long addr); + void (*spi_write_reg32)(void *priv, unsigned long addr, unsigned int val); + void (*spi_cpy_from)(void *priv, void *dest, unsigned long addr, size_t count); + void (*spi_cpy_to)(void *priv, unsigned long addr, const void *src, size_t count); + + void *(*spinlock_alloc)(void); + void (*spinlock_free)(void *lock); + void (*spinlock_init)(void *lock); + void (*spinlock_take)(void *lock); + void (*spinlock_rel)(void *lock); + + void (*spinlock_irq_take)(void *lock, unsigned long *flags); + void (*spinlock_irq_rel)(void *lock, unsigned long *flags); + + int (*log_dbg)(const char *fmt, va_list args); + int (*log_info)(const char *fmt, va_list args); + int (*log_err)(const char *fmt, va_list args); + + void *(*llist_node_alloc)(void); + void (*llist_node_free)(void *node); + void *(*llist_node_data_get)(void *node); + void (*llist_node_data_set)(void *node, void *data); + + void *(*llist_alloc)(void); + void (*llist_free)(void *llist); + void (*llist_init)(void *llist); + void (*llist_add_node_tail)(void *llist, void *llist_node); + void (*llist_add_node_head)(void *llist, void *llist_node); + void *(*llist_get_node_head)(void *llist); + void *(*llist_get_node_nxt)(void *llist, void *llist_node); + void (*llist_del_node)(void *llist, void *llist_node); + unsigned int (*llist_len)(void *llist); + + void *(*nbuf_alloc)(unsigned int size); + void (*nbuf_free)(void *nbuf); + void (*nbuf_headroom_res)(void *nbuf, unsigned int size); + unsigned int (*nbuf_headroom_get)(void *nbuf); + unsigned int (*nbuf_data_size)(void *nbuf); + void *(*nbuf_data_get)(void *nbuf); + void *(*nbuf_data_put)(void *nbuf, unsigned int size); + void *(*nbuf_data_push)(void *nbuf, unsigned int size); + void *(*nbuf_data_pull)(void *nbuf, unsigned int size); + unsigned char (*nbuf_get_priority)(void *nbuf); + + void *(*tasklet_alloc)(int type); + void (*tasklet_free)(void *tasklet); + void (*tasklet_init)(void *tasklet, + void (*callback)(unsigned long), + unsigned long data); + void (*tasklet_schedule)(void *tasklet); + void (*tasklet_kill)(void *tasklet); + + + int (*sleep_ms)(int msecs); + int (*delay_us)(int usecs); + unsigned long (*time_get_curr_us)(void); + unsigned int (*time_elapsed_us)(unsigned long start_time_us); + + void *(*bus_pcie_init)(const char *dev_name, + unsigned int vendor_id, + unsigned int sub_vendor_id, + unsigned int device_id, + unsigned int sub_device_id); + void (*bus_pcie_deinit)(void *os_pcie_priv); + void *(*bus_pcie_dev_add)(void *pcie_priv, + void *osal_pcie_dev_ctx); + void (*bus_pcie_dev_rem)(void *os_pcie_dev_ctx); + + enum nrf_wifi_status (*bus_pcie_dev_init)(void *os_pcie_dev_ctx); + void (*bus_pcie_dev_deinit)(void *os_pcie_dev_ctx); + + enum nrf_wifi_status (*bus_pcie_dev_intr_reg)(void *os_pcie_dev_ctx, + void *callbk_data, + int (*callback_fn)(void *callbk_data)); + void (*bus_pcie_dev_intr_unreg)(void *os_pcie_dev_ctx); + void *(*bus_pcie_dev_dma_map)(void *os_pcie_dev_ctx, + void *virt_addr, + size_t size, + enum nrf_wifi_osal_dma_dir dir); + void (*bus_pcie_dev_dma_unmap)(void *os_pcie_dev_ctx, + void *dma_addr, + size_t size, + enum nrf_wifi_osal_dma_dir dir); + void (*bus_pcie_dev_host_map_get)(void *os_pcie_dev_ctx, + struct nrf_wifi_osal_host_map *host_map); + + void *(*bus_qspi_init)(void); + void (*bus_qspi_deinit)(void *os_qspi_priv); + void *(*bus_qspi_dev_add)(void *qspi_priv, + void *osal_qspi_dev_ctx); + void (*bus_qspi_dev_rem)(void *os_qspi_dev_ctx); + + enum nrf_wifi_status (*bus_qspi_dev_init)(void *os_qspi_dev_ctx); + void (*bus_qspi_dev_deinit)(void *os_qspi_dev_ctx); + + enum nrf_wifi_status (*bus_qspi_dev_intr_reg)(void *os_qspi_dev_ctx, + void *callbk_data, + int (*callback_fn)(void *callbk_data)); + void (*bus_qspi_dev_intr_unreg)(void *os_qspi_dev_ctx); + void (*bus_qspi_dev_host_map_get)(void *os_qspi_dev_ctx, + struct nrf_wifi_osal_host_map *host_map); + void *(*bus_spi_init)(void); + void (*bus_spi_deinit)(void *os_spi_priv); + void *(*bus_spi_dev_add)(void *spi_priv, + void *osal_spi_dev_ctx); + void (*bus_spi_dev_rem)(void *os_spi_dev_ctx); + + enum nrf_wifi_status (*bus_spi_dev_init)(void *os_spi_dev_ctx); + void (*bus_spi_dev_deinit)(void *os_spi_dev_ctx); + + enum nrf_wifi_status (*bus_spi_dev_intr_reg)(void *os_spi_dev_ctx, + void *callbk_data, + int (*callback_fn)(void *callbk_data)); + void (*bus_spi_dev_intr_unreg)(void *os_spi_dev_ctx); + void (*bus_spi_dev_host_map_get)(void *os_spi_dev_ctx, + struct nrf_wifi_osal_host_map *host_map); +#ifdef CONFIG_NRF_WIFI_LOW_POWER + void *(*timer_alloc)(void); + void (*timer_free)(void *timer); + void (*timer_init)(void *timer, + void (*callback)(unsigned long), + unsigned long data); + void (*timer_schedule)(void *timer, unsigned long duration); + void (*timer_kill)(void *timer); + int (*bus_qspi_ps_sleep)(void *os_qspi_priv); + int (*bus_qspi_ps_wake)(void *os_qspi_priv); + int (*bus_qspi_ps_status)(void *os_qspi_priv); +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + + void (*assert)(int test_val, + int val, + enum nrf_wifi_assert_op_type op, + char *assert_msg); + + unsigned int (*strlen)(const void *str); +}; + + +/** + * get_os_ops() - The OSAL layer expects this Op return a initialized instance + * of OS specific Ops. + * + * This Op is expected to be implemented by a specific OS shim and is expected + * to return a pointer to a initialized instance of struct nrf_wifi_osal_ops. + * + * Returns: Pointer to instance of OS specific Ops. + */ +const struct nrf_wifi_osal_ops *get_os_ops(void); +#endif /* __OSAL_OPS_H__ */ diff --git a/nrf_wifi/os_if/inc/osal_structs.h b/nrf_wifi/os_if/inc/osal_structs.h new file mode 100644 index 0000000000..e8ed526eee --- /dev/null +++ b/nrf_wifi/os_if/inc/osal_structs.h @@ -0,0 +1,105 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing structure declarations for the + * OSAL Layer of the Wi-Fi driver. + */ + +#ifndef __OSAL_STRUCTS_H__ +#define __OSAL_STRUCTS_H__ + +#include + +/** + * enum nrf_wifi_status - The status of an operation performed by the + * RPU driver. + * @NRF_WIFI_STATUS_SUCCESS: The operation was successful. + * @NRF_WIFI_STATUS_FAIL: The operation failed. + * + * This enum lists the possible outcomes of an operation performed by the + * RPU driver. + */ +enum nrf_wifi_status { + NRF_WIFI_STATUS_SUCCESS, + NRF_WIFI_STATUS_FAIL = -1, +}; + + +/** + * enum nrf_wifi_osal_dma_dir - DMA direction for a DMA operation + * @NRF_WIFI_OSAL_DMA_DIR_TO_DEV: Data needs to be DMAed to the device. + * @NRF_WIFI_DMA_DIR_FROM_DEV: Data needs to be DMAed from the device. + * @NRF_WIFI_DMA_DIR_BIDI: Data can be DMAed in either direction i.e to + * or from the device. + * + * This enum lists the possible directions for a DMA operation i.e whether the + * DMA operation is for transferring data to or from a device + */ +enum nrf_wifi_osal_dma_dir { + NRF_WIFI_OSAL_DMA_DIR_TO_DEV, + NRF_WIFI_OSAL_DMA_DIR_FROM_DEV, + NRF_WIFI_OSAL_DMA_DIR_BIDI +}; + +/** + * enum nrf_wifi_tasklet_type - The type of a tasklet + * @NRF_WIFI_TASKLET_TYPE_BH: The tasklet is a bottom half tasklet i.e it is + * scheduled from an interrupt context used for all except + * TX done tasklets. + * @NRF_WIFI_TASKLET_TYPE_IRQ: The tasklet is an IRQ tasklet. It is scheduled + * from the Bus ISR, used internally by the SHIM layer. + * @NRF_WIFI_TASKLET_TYPE_TX_DONE: The tasklet is a TX done tasklet. It is + * scheduled from the BH tasklet for TX done interrupts. + * @NRF_WIFI_TASKLET_TYPE_RX: The tasklet is an RX tasklet. It is scheduled + * from the BH tasklet for RX interrupts. + * @NRF_WIFI_TASKLET_TYPE_MAX: The maximum number of tasklet types. + * + * This enum lists the possible types of a tasklet. + * Each tasklet type is associated with its own work queue. + */ +enum nrf_wifi_tasklet_type { + NRF_WIFI_TASKLET_TYPE_BH, + NRF_WIFI_TASKLET_TYPE_IRQ, + NRF_WIFI_TASKLET_TYPE_TX_DONE, + NRF_WIFI_TASKLET_TYPE_RX, + NRF_WIFI_TASKLET_TYPE_MAX +}; + +struct nrf_wifi_osal_host_map { + unsigned long addr; + unsigned long size; +}; + + +struct nrf_wifi_osal_priv { + const struct nrf_wifi_osal_ops *ops; +}; + +/** + * enum nrf_wifi_assert_type - The type of assertion operation has to be done + * @NRF_WIFI_ASSERT_EQUAL_TO: The assertion check for equality. + * @NRF_WIFI_ASSERT_NOT_EQUAL_TO: The assertion check for non-equality. + * @NRF_WIFI_ASSERT_LESS_THAN: The assertion check for lesser value. + * @NRF_WIFI_ASSERT_LESS_THAN_OR_EQUAL_TO: The assertion check + * for equal or lesser. + * @NRF_WIFI_ASSERT_MORE_THAN: The assertion check for condition + * of more than value. + * @NRF_WIFI_ASSERT_MORE_THAN_OR_EQUAL_TO: The assertion check for condition + * equal or more than value. + * + * This enum lists the possible type of operation in the assertion + * check should be taken. + */ +enum nrf_wifi_assert_op_type { + NRF_WIFI_ASSERT_EQUAL_TO, + NRF_WIFI_ASSERT_NOT_EQUAL_TO, + NRF_WIFI_ASSERT_LESS_THAN, + NRF_WIFI_ASSERT_LESS_THAN_EQUAL_TO, + NRF_WIFI_ASSERT_GREATER_THAN, + NRF_WIFI_ASSERT_GREATER_THAN_EQUAL_TO, +}; +#endif /* __OSAL_STRUCTS_H__ */ diff --git a/nrf_wifi/os_if/src/osal.c b/nrf_wifi/os_if/src/osal.c new file mode 100644 index 0000000000..3fd456ecdc --- /dev/null +++ b/nrf_wifi/os_if/src/osal.c @@ -0,0 +1,912 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Implements OSAL APIs to abstract OS primitives. + */ + +#include "osal_api.h" +#include "osal_ops.h" + +struct nrf_wifi_osal_priv *nrf_wifi_osal_init(void) +{ + struct nrf_wifi_osal_priv *opriv = NULL; + const struct nrf_wifi_osal_ops *ops = NULL; + + ops = get_os_ops(); + + opriv = ops->mem_zalloc(sizeof(struct nrf_wifi_osal_priv)); + + if (!opriv) { + goto out; + } + + opriv->ops = ops; + +out: + return opriv; +} + + +void nrf_wifi_osal_deinit(struct nrf_wifi_osal_priv *opriv) +{ + const struct nrf_wifi_osal_ops *ops = NULL; + + ops = opriv->ops; + + ops->mem_free(opriv); +} + + +void *nrf_wifi_osal_mem_alloc(struct nrf_wifi_osal_priv *opriv, + size_t size) +{ + return opriv->ops->mem_alloc(size); +} + + +void *nrf_wifi_osal_mem_zalloc(struct nrf_wifi_osal_priv *opriv, + size_t size) +{ + return opriv->ops->mem_zalloc(size); +} + + +void nrf_wifi_osal_mem_free(struct nrf_wifi_osal_priv *opriv, + void *buf) +{ + opriv->ops->mem_free(buf); +} + + +void *nrf_wifi_osal_mem_cpy(struct nrf_wifi_osal_priv *opriv, + void *dest, + const void *src, + size_t count) +{ + return opriv->ops->mem_cpy(dest, + src, + count); +} + + +void *nrf_wifi_osal_mem_set(struct nrf_wifi_osal_priv *opriv, + void *start, + int val, + size_t size) +{ + return opriv->ops->mem_set(start, + val, + size); +} + + +int nrf_wifi_osal_mem_cmp(struct nrf_wifi_osal_priv *opriv, + const void *addr1, + const void *addr2, + size_t size) +{ + return opriv->ops->mem_cmp(addr1, + addr2, + size); +} + + +void *nrf_wifi_osal_iomem_mmap(struct nrf_wifi_osal_priv *opriv, + unsigned long addr, + unsigned long size) +{ + return opriv->ops->iomem_mmap(addr, + size); +} + + +void nrf_wifi_osal_iomem_unmap(struct nrf_wifi_osal_priv *opriv, + volatile void *addr) +{ + opriv->ops->iomem_unmap(addr); +} + + +unsigned int nrf_wifi_osal_iomem_read_reg32(struct nrf_wifi_osal_priv *opriv, + const volatile void *addr) +{ + return opriv->ops->iomem_read_reg32(addr); +} + + +void nrf_wifi_osal_iomem_write_reg32(struct nrf_wifi_osal_priv *opriv, + volatile void *addr, + unsigned int val) +{ + opriv->ops->iomem_write_reg32(addr, + val); +} + + +void nrf_wifi_osal_iomem_cpy_from(struct nrf_wifi_osal_priv *opriv, + void *dest, + const volatile void *src, + size_t count) +{ + opriv->ops->iomem_cpy_from(dest, + src, + count); +} + + +void nrf_wifi_osal_iomem_cpy_to(struct nrf_wifi_osal_priv *opriv, + volatile void *dest, + const void *src, + size_t count) +{ + opriv->ops->iomem_cpy_to(dest, + src, + count); +} + + +void *nrf_wifi_osal_spinlock_alloc(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->spinlock_alloc(); +} + + +void nrf_wifi_osal_spinlock_free(struct nrf_wifi_osal_priv *opriv, + void *lock) +{ + opriv->ops->spinlock_free(lock); +} + + +void nrf_wifi_osal_spinlock_init(struct nrf_wifi_osal_priv *opriv, + void *lock) +{ + opriv->ops->spinlock_init(lock); +} + + +void nrf_wifi_osal_spinlock_take(struct nrf_wifi_osal_priv *opriv, + void *lock) +{ + opriv->ops->spinlock_take(lock); +} + + +void nrf_wifi_osal_spinlock_rel(struct nrf_wifi_osal_priv *opriv, + void *lock) +{ + opriv->ops->spinlock_rel(lock); +} + +void nrf_wifi_osal_spinlock_irq_take(struct nrf_wifi_osal_priv *opriv, + void *lock, + unsigned long *flags) +{ + opriv->ops->spinlock_irq_take(lock, + flags); +} + + +void nrf_wifi_osal_spinlock_irq_rel(struct nrf_wifi_osal_priv *opriv, + void *lock, + unsigned long *flags) +{ + opriv->ops->spinlock_irq_rel(lock, + flags); +} + + +#if CONFIG_WIFI_NRF700X_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_DBG +int nrf_wifi_osal_log_dbg(struct nrf_wifi_osal_priv *opriv, + const char *fmt, + ...) +{ + va_list args; + int ret = -1; + + va_start(args, fmt); + + ret = opriv->ops->log_dbg(fmt, args); + + va_end(args); + + return ret; +} +#endif /* CONFIG_WIFI_NRF700X_LOG_LEVEL_DBG */ + + +#if CONFIG_WIFI_NRF700X_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_INF +int nrf_wifi_osal_log_info(struct nrf_wifi_osal_priv *opriv, + const char *fmt, + ...) +{ + va_list args; + int ret = -1; + + va_start(args, fmt); + + ret = opriv->ops->log_info(fmt, args); + + va_end(args); + + return ret; +} +#endif /* CONFIG_WIFI_NRF700X_LOG_LEVEL_INF */ + + +#if CONFIG_WIFI_NRF700X_LOG_LEVEL >= NRF_WIFI_LOG_LEVEL_ERR +int nrf_wifi_osal_log_err(struct nrf_wifi_osal_priv *opriv, + const char *fmt, + ...) +{ + va_list args; + int ret = -1; + + va_start(args, fmt); + + ret = opriv->ops->log_err(fmt, args); + + va_end(args); + + return ret; +} +#endif /* CONFIG_WIFI_NRF700X_LOG_LEVEL_ERR */ + + +void *nrf_wifi_osal_llist_node_alloc(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->llist_node_alloc(); +} + + +void nrf_wifi_osal_llist_node_free(struct nrf_wifi_osal_priv *opriv, + void *node) +{ + opriv->ops->llist_node_free(node); +} + + +void *nrf_wifi_osal_llist_node_data_get(struct nrf_wifi_osal_priv *opriv, + void *node) +{ + return opriv->ops->llist_node_data_get(node); +} + + +void nrf_wifi_osal_llist_node_data_set(struct nrf_wifi_osal_priv *opriv, + void *node, + void *data) +{ + opriv->ops->llist_node_data_set(node, + data); +} + + +void *nrf_wifi_osal_llist_alloc(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->llist_alloc(); +} + + +void nrf_wifi_osal_llist_free(struct nrf_wifi_osal_priv *opriv, + void *llist) +{ + return opriv->ops->llist_free(llist); +} + + +void nrf_wifi_osal_llist_init(struct nrf_wifi_osal_priv *opriv, + void *llist) +{ + return opriv->ops->llist_init(llist); +} + + +void nrf_wifi_osal_llist_add_node_tail(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node) +{ + return opriv->ops->llist_add_node_tail(llist, + llist_node); +} + +void nrf_wifi_osal_llist_add_node_head(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node) +{ + return opriv->ops->llist_add_node_head(llist, + llist_node); +} + + +void *nrf_wifi_osal_llist_get_node_head(struct nrf_wifi_osal_priv *opriv, + void *llist) +{ + return opriv->ops->llist_get_node_head(llist); +} + + +void *nrf_wifi_osal_llist_get_node_nxt(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node) +{ + return opriv->ops->llist_get_node_nxt(llist, + llist_node); +} + + +void nrf_wifi_osal_llist_del_node(struct nrf_wifi_osal_priv *opriv, + void *llist, + void *llist_node) +{ + opriv->ops->llist_del_node(llist, + llist_node); +} + + +unsigned int nrf_wifi_osal_llist_len(struct nrf_wifi_osal_priv *opriv, + void *llist) +{ + return opriv->ops->llist_len(llist); +} + + +void *nrf_wifi_osal_nbuf_alloc(struct nrf_wifi_osal_priv *opriv, + unsigned int size) +{ + return opriv->ops->nbuf_alloc(size); +} + + +void nrf_wifi_osal_nbuf_free(struct nrf_wifi_osal_priv *opriv, + void *nbuf) +{ + opriv->ops->nbuf_free(nbuf); +} + + +void nrf_wifi_osal_nbuf_headroom_res(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size) +{ + opriv->ops->nbuf_headroom_res(nbuf, + size); +} + + +unsigned int nrf_wifi_osal_nbuf_headroom_get(struct nrf_wifi_osal_priv *opriv, + void *nbuf) +{ + return opriv->ops->nbuf_headroom_get(nbuf); +} + + +unsigned int nrf_wifi_osal_nbuf_data_size(struct nrf_wifi_osal_priv *opriv, + void *nbuf) +{ + return opriv->ops->nbuf_data_size(nbuf); +} + + +void *nrf_wifi_osal_nbuf_data_get(struct nrf_wifi_osal_priv *opriv, + void *nbuf) +{ + return opriv->ops->nbuf_data_get(nbuf); +} + + +void *nrf_wifi_osal_nbuf_data_put(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size) +{ + return opriv->ops->nbuf_data_put(nbuf, + size); +} + + +void *nrf_wifi_osal_nbuf_data_push(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size) +{ + return opriv->ops->nbuf_data_push(nbuf, + size); +} + + +void *nrf_wifi_osal_nbuf_data_pull(struct nrf_wifi_osal_priv *opriv, + void *nbuf, + unsigned int size) +{ + return opriv->ops->nbuf_data_pull(nbuf, + size); +} + +unsigned char nrf_wifi_osal_nbuf_get_priority(struct nrf_wifi_osal_priv *opriv, + void *nbuf) +{ + return opriv->ops->nbuf_get_priority(nbuf); +} + + +void *nrf_wifi_osal_tasklet_alloc(struct nrf_wifi_osal_priv *opriv, int type) +{ + return opriv->ops->tasklet_alloc(type); +} + + +void nrf_wifi_osal_tasklet_free(struct nrf_wifi_osal_priv *opriv, + void *tasklet) +{ + opriv->ops->tasklet_free(tasklet); +} + + +void nrf_wifi_osal_tasklet_init(struct nrf_wifi_osal_priv *opriv, + void *tasklet, + void (*callbk_fn)(unsigned long), + unsigned long data) +{ + opriv->ops->tasklet_init(tasklet, + callbk_fn, + data); +} + + +void nrf_wifi_osal_tasklet_schedule(struct nrf_wifi_osal_priv *opriv, + void *tasklet) +{ + opriv->ops->tasklet_schedule(tasklet); +} + + +void nrf_wifi_osal_tasklet_kill(struct nrf_wifi_osal_priv *opriv, + void *tasklet) +{ + opriv->ops->tasklet_kill(tasklet); +} + + +void nrf_wifi_osal_sleep_ms(struct nrf_wifi_osal_priv *opriv, + unsigned int msecs) +{ + opriv->ops->sleep_ms(msecs); +} + + +void nrf_wifi_osal_delay_us(struct nrf_wifi_osal_priv *opriv, + unsigned long usecs) +{ + opriv->ops->delay_us(usecs); +} + + +unsigned long nrf_wifi_osal_time_get_curr_us(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->time_get_curr_us(); +} + + +unsigned int nrf_wifi_osal_time_elapsed_us(struct nrf_wifi_osal_priv *opriv, + unsigned long start_time_us) +{ + return opriv->ops->time_elapsed_us(start_time_us); +} + + +void *nrf_wifi_osal_bus_pcie_init(struct nrf_wifi_osal_priv *opriv, + const char *dev_name, + unsigned int vendor_id, + unsigned int sub_vendor_id, + unsigned int device_id, + unsigned int sub_device_id) +{ + return opriv->ops->bus_pcie_init(dev_name, + vendor_id, + sub_vendor_id, + device_id, + sub_device_id); +} + + +void nrf_wifi_osal_bus_pcie_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_priv) +{ + opriv->ops->bus_pcie_deinit(os_pcie_priv); +} + + +void *nrf_wifi_osal_bus_pcie_dev_add(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_priv, + void *osal_pcie_dev_ctx) +{ + return opriv->ops->bus_pcie_dev_add(os_pcie_priv, + osal_pcie_dev_ctx); + +} + + +void nrf_wifi_osal_bus_pcie_dev_rem(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx) +{ + return opriv->ops->bus_pcie_dev_rem(os_pcie_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_osal_bus_pcie_dev_init(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx) +{ + return opriv->ops->bus_pcie_dev_init(os_pcie_dev_ctx); + +} + + +void nrf_wifi_osal_bus_pcie_dev_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx) +{ + return opriv->ops->bus_pcie_dev_deinit(os_pcie_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_osal_bus_pcie_dev_intr_reg(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + void *callbk_data, + int (*callbk_fn)(void *callbk_data)) +{ + return opriv->ops->bus_pcie_dev_intr_reg(os_pcie_dev_ctx, + callbk_data, + callbk_fn); +} + + +void nrf_wifi_osal_bus_pcie_dev_intr_unreg(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx) +{ + opriv->ops->bus_pcie_dev_intr_unreg(os_pcie_dev_ctx); +} + + +void *nrf_wifi_osal_bus_pcie_dev_dma_map(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + void *virt_addr, + size_t size, + enum nrf_wifi_osal_dma_dir dir) +{ + return opriv->ops->bus_pcie_dev_dma_map(os_pcie_dev_ctx, + virt_addr, + size, + dir); +} + + +void nrf_wifi_osal_bus_pcie_dev_dma_unmap(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + void *dma_addr, + size_t size, + enum nrf_wifi_osal_dma_dir dir) +{ + opriv->ops->bus_pcie_dev_dma_unmap(os_pcie_dev_ctx, + dma_addr, + size, + dir); +} + + +void nrf_wifi_osal_bus_pcie_dev_host_map_get(struct nrf_wifi_osal_priv *opriv, + void *os_pcie_dev_ctx, + struct nrf_wifi_osal_host_map *host_map) +{ + opriv->ops->bus_pcie_dev_host_map_get(os_pcie_dev_ctx, + host_map); +} + + +void *nrf_wifi_osal_bus_qspi_init(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->bus_qspi_init(); +} + + +void nrf_wifi_osal_bus_qspi_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv) +{ + opriv->ops->bus_qspi_deinit(os_qspi_priv); +} + + +void *nrf_wifi_osal_bus_qspi_dev_add(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv, + void *osal_qspi_dev_ctx) +{ + return opriv->ops->bus_qspi_dev_add(os_qspi_priv, + osal_qspi_dev_ctx); +} + + +void nrf_wifi_osal_bus_qspi_dev_rem(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx) +{ + opriv->ops->bus_qspi_dev_rem(os_qspi_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_osal_bus_qspi_dev_init(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx) +{ + return opriv->ops->bus_qspi_dev_init(os_qspi_dev_ctx); +} + + +void nrf_wifi_osal_bus_qspi_dev_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx) +{ + opriv->ops->bus_qspi_dev_deinit(os_qspi_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_osal_bus_qspi_dev_intr_reg(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx, + void *callbk_data, + int (*callbk_fn)(void *callbk_data)) +{ + return opriv->ops->bus_qspi_dev_intr_reg(os_qspi_dev_ctx, + callbk_data, + callbk_fn); +} + + +void nrf_wifi_osal_bus_qspi_dev_intr_unreg(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx) +{ + opriv->ops->bus_qspi_dev_intr_unreg(os_qspi_dev_ctx); +} + + +void nrf_wifi_osal_bus_qspi_dev_host_map_get(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_dev_ctx, + struct nrf_wifi_osal_host_map *host_map) +{ + opriv->ops->bus_qspi_dev_host_map_get(os_qspi_dev_ctx, + host_map); +} + + +unsigned int nrf_wifi_osal_qspi_read_reg32(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr) +{ + return opriv->ops->qspi_read_reg32(priv, + addr); +} + + +void nrf_wifi_osal_qspi_write_reg32(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr, + unsigned int val) +{ + opriv->ops->qspi_write_reg32(priv, + addr, + val); +} + + +void nrf_wifi_osal_qspi_cpy_from(struct nrf_wifi_osal_priv *opriv, + void *priv, + void *dest, + unsigned long addr, + size_t count) +{ + opriv->ops->qspi_cpy_from(priv, + dest, + addr, + count); +} + + +void nrf_wifi_osal_qspi_cpy_to(struct nrf_wifi_osal_priv *opriv, + void *priv, + unsigned long addr, + const void *src, + size_t count) +{ + opriv->ops->qspi_cpy_to(priv, + addr, + src, + count); +} + + +void *nrf_wifi_osal_bus_spi_init(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->bus_spi_init(); +} + + +void nrf_wifi_osal_bus_spi_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_spi_priv) +{ + opriv->ops->bus_spi_deinit(os_spi_priv); +} + + +void *nrf_wifi_osal_bus_spi_dev_add(struct nrf_wifi_osal_priv *opriv, + void *os_spi_priv, + void *osal_spi_dev_ctx) +{ + return opriv->ops->bus_spi_dev_add(os_spi_priv, + osal_spi_dev_ctx); +} + + +void nrf_wifi_osal_bus_spi_dev_rem(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx) +{ + opriv->ops->bus_spi_dev_rem(os_spi_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_osal_bus_spi_dev_init(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx) +{ + return opriv->ops->bus_spi_dev_init(os_spi_dev_ctx); +} + + +void nrf_wifi_osal_bus_spi_dev_deinit(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx) +{ + opriv->ops->bus_spi_dev_deinit(os_spi_dev_ctx); +} + + +enum nrf_wifi_status nrf_wifi_osal_bus_spi_dev_intr_reg(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + void *callbk_data, + int (*callbk_fn)(void *callbk_data)) +{ + return opriv->ops->bus_spi_dev_intr_reg(os_spi_dev_ctx, + callbk_data, + callbk_fn); +} + + +void nrf_wifi_osal_bus_spi_dev_intr_unreg(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx) +{ + opriv->ops->bus_spi_dev_intr_unreg(os_spi_dev_ctx); +} + + +void nrf_wifi_osal_bus_spi_dev_host_map_get(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + struct nrf_wifi_osal_host_map *host_map) +{ + opriv->ops->bus_spi_dev_host_map_get(os_spi_dev_ctx, + host_map); +} + +unsigned int nrf_wifi_osal_spi_read_reg32(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + unsigned long addr) +{ + return opriv->ops->spi_read_reg32(os_spi_dev_ctx, addr); +} + + +void nrf_wifi_osal_spi_write_reg32(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + unsigned long addr, + unsigned int val) +{ + opriv->ops->spi_write_reg32(os_spi_dev_ctx, + addr, + val); +} + + +void nrf_wifi_osal_spi_cpy_from(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + void *dest, + unsigned long addr, + size_t count) +{ + opriv->ops->spi_cpy_from(os_spi_dev_ctx, + dest, + addr, + count); +} + + +void nrf_wifi_osal_spi_cpy_to(struct nrf_wifi_osal_priv *opriv, + void *os_spi_dev_ctx, + unsigned long addr, + const void *src, + size_t count) +{ + opriv->ops->spi_cpy_to(os_spi_dev_ctx, + addr, + src, + count); +} + +#ifdef CONFIG_NRF_WIFI_LOW_POWER +void *nrf_wifi_osal_timer_alloc(struct nrf_wifi_osal_priv *opriv) +{ + return opriv->ops->timer_alloc(); +} + + +void nrf_wifi_osal_timer_free(struct nrf_wifi_osal_priv *opriv, + void *timer) +{ + opriv->ops->timer_free(timer); +} + + +void nrf_wifi_osal_timer_init(struct nrf_wifi_osal_priv *opriv, + void *timer, + void (*callbk_fn)(unsigned long), + unsigned long data) +{ + opriv->ops->timer_init(timer, + callbk_fn, + data); +} + + +void nrf_wifi_osal_timer_schedule(struct nrf_wifi_osal_priv *opriv, + void *timer, + unsigned long duration) +{ + opriv->ops->timer_schedule(timer, + duration); +} + + +void nrf_wifi_osal_timer_kill(struct nrf_wifi_osal_priv *opriv, + void *timer) +{ + opriv->ops->timer_kill(timer); +} + + + +int nrf_wifi_osal_bus_qspi_ps_sleep(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv) +{ + return opriv->ops->bus_qspi_ps_sleep(os_qspi_priv); +} + + +int nrf_wifi_osal_bus_qspi_ps_wake(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv) +{ + return opriv->ops->bus_qspi_ps_wake(os_qspi_priv); +} + + +int nrf_wifi_osal_bus_qspi_ps_status(struct nrf_wifi_osal_priv *opriv, + void *os_qspi_priv) +{ + return opriv->ops->bus_qspi_ps_status(os_qspi_priv); +} +#endif /* CONFIG_NRF_WIFI_LOW_POWER */ + +void nrf_wifi_osal_assert(struct nrf_wifi_osal_priv *opriv, + int test_val, + int val, + enum nrf_wifi_assert_op_type op, + char *msg) +{ + return opriv->ops->assert(test_val, val, op, msg); +} + +unsigned int nrf_wifi_osal_strlen(struct nrf_wifi_osal_priv *opriv, + const void *str) +{ + return opriv->ops->strlen(str); +} diff --git a/nrf_wifi/utils/inc/list.h b/nrf_wifi/utils/inc/list.h new file mode 100644 index 0000000000..9284774ec6 --- /dev/null +++ b/nrf_wifi/utils/inc/list.h @@ -0,0 +1,50 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing linked list specific declarations + * for the Wi-Fi driver. + */ + +#ifndef __LIST_H__ +#define __LIST_H__ + +#include +#include "osal_api.h" + +void *nrf_wifi_utils_list_alloc(struct nrf_wifi_osal_priv *opriv); + +void nrf_wifi_utils_list_free(struct nrf_wifi_osal_priv *opriv, + void *list); + +enum nrf_wifi_status nrf_wifi_utils_list_add_tail(struct nrf_wifi_osal_priv *opriv, + void *list, + void *data); + +enum nrf_wifi_status nrf_wifi_utils_list_add_head(struct nrf_wifi_osal_priv *opriv, + void *list, + void *data); + +void nrf_wifi_utils_list_del_node(struct nrf_wifi_osal_priv *opriv, + void *list, + void *data); + +void *nrf_wifi_utils_list_del_head(struct nrf_wifi_osal_priv *opriv, + void *list); + +void *nrf_wifi_utils_list_peek(struct nrf_wifi_osal_priv *opriv, + void *list); + +unsigned int nrf_wifi_utils_list_len(struct nrf_wifi_osal_priv *opriv, + void *list); + +enum nrf_wifi_status +nrf_wifi_utils_list_traverse(struct nrf_wifi_osal_priv *opriv, + void *list, + void *callbk_data, + enum nrf_wifi_status (*callbk_func)(void *callbk_data, + void *data)); +#endif /* __LIST_H__ */ diff --git a/nrf_wifi/utils/inc/queue.h b/nrf_wifi/utils/inc/queue.h new file mode 100644 index 0000000000..5f92f9667d --- /dev/null +++ b/nrf_wifi/utils/inc/queue.h @@ -0,0 +1,39 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing queue specific declarations + * for the Wi-Fi driver. + */ + +#ifndef __QUEUE_H__ +#define __QUEUE_H__ + +#include +#include "osal_ops.h" + +void *nrf_wifi_utils_q_alloc(struct nrf_wifi_osal_priv *opriv); + +void nrf_wifi_utils_q_free(struct nrf_wifi_osal_priv *opriv, + void *q); + +enum nrf_wifi_status nrf_wifi_utils_q_enqueue(struct nrf_wifi_osal_priv *opriv, + void *q, + void *q_node); + +enum nrf_wifi_status nrf_wifi_utils_q_enqueue_head(struct nrf_wifi_osal_priv *opriv, + void *q, + void *q_node); + +void *nrf_wifi_utils_q_dequeue(struct nrf_wifi_osal_priv *opriv, + void *q); + +void *nrf_wifi_utils_q_peek(struct nrf_wifi_osal_priv *opriv, + void *q); + +unsigned int nrf_wifi_utils_q_len(struct nrf_wifi_osal_priv *opriv, + void *q); +#endif /* __QUEUE_H__ */ diff --git a/nrf_wifi/utils/inc/util.h b/nrf_wifi/utils/inc/util.h new file mode 100644 index 0000000000..501fe1706e --- /dev/null +++ b/nrf_wifi/utils/inc/util.h @@ -0,0 +1,38 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief Header containing utility function declarations for the + * Wi-Fi driver. + */ + +#ifndef __UTIL_H__ +#define __UTIL_H__ + +#include +#include +#include "osal_api.h" +#include "host_rpu_umac_if.h" + +#ifndef ARRAY_SIZE +#define ARRAY_SIZE(array) (sizeof(array) / sizeof((array)[0])) +#endif + +/* Convert power from mBm to dBm */ +#define MBM_TO_DBM(gain) ((gain) / 100) + +int nrf_wifi_utils_hex_str_to_val(struct nrf_wifi_osal_priv *opriv, + unsigned char *hex_arr, + unsigned int hex_arr_sz, + unsigned char *str); + +bool nrf_wifi_utils_is_mac_addr_valid(struct nrf_wifi_osal_priv *opriv, + const char *mac_addr); + +int nrf_wifi_utils_chan_to_freq(struct nrf_wifi_osal_priv *opriv, + enum nrf_wifi_band band, + unsigned short chan); +#endif /* __UTIL_H__ */ diff --git a/nrf_wifi/utils/src/list.c b/nrf_wifi/utils/src/list.c new file mode 100644 index 0000000000..fabda4fcad --- /dev/null +++ b/nrf_wifi/utils/src/list.c @@ -0,0 +1,216 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing linked list specific definitions + * for the Wi-Fi driver. + */ + + +#include "list.h" + +void *nrf_wifi_utils_list_alloc(struct nrf_wifi_osal_priv *opriv) +{ + void *list = NULL; + + list = nrf_wifi_osal_llist_alloc(opriv); + + if (!list) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate list\n", + __func__); + goto out; + } + + nrf_wifi_osal_llist_init(opriv, + list); + +out: + return list; + +} + + +void nrf_wifi_utils_list_free(struct nrf_wifi_osal_priv *opriv, + void *list) +{ + nrf_wifi_osal_llist_free(opriv, + list); +} + + +enum nrf_wifi_status nrf_wifi_utils_list_add_tail(struct nrf_wifi_osal_priv *opriv, + void *list, + void *data) +{ + void *list_node = NULL; + + list_node = nrf_wifi_osal_llist_node_alloc(opriv); + + if (!list_node) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate list node\n", + __func__); + return NRF_WIFI_STATUS_FAIL; + } + + nrf_wifi_osal_llist_node_data_set(opriv, + list_node, + data); + + nrf_wifi_osal_llist_add_node_tail(opriv, + list, + list_node); + + return NRF_WIFI_STATUS_SUCCESS; +} + +enum nrf_wifi_status nrf_wifi_utils_list_add_head(struct nrf_wifi_osal_priv *opriv, + void *list, + void *data) +{ + void *list_node = NULL; + + list_node = nrf_wifi_osal_llist_node_alloc(opriv); + + if (!list_node) { + nrf_wifi_osal_log_err(opriv, + "%s: Unable to allocate list node\n", + __func__); + return NRF_WIFI_STATUS_FAIL; + } + + nrf_wifi_osal_llist_node_data_set(opriv, + list_node, + data); + + nrf_wifi_osal_llist_add_node_head(opriv, + list, + list_node); + + return NRF_WIFI_STATUS_SUCCESS; +} + +void nrf_wifi_utils_list_del_node(struct nrf_wifi_osal_priv *opriv, + void *list, + void *data) +{ + void *stored_data; + void *list_node = NULL; + void *list_node_next = NULL; + + list_node = nrf_wifi_osal_llist_get_node_head(opriv, + list); + + while (list_node) { + stored_data = nrf_wifi_osal_llist_node_data_get(opriv, + list_node); + + list_node_next = nrf_wifi_osal_llist_get_node_nxt(opriv, + list, + list_node); + + if (stored_data == data) { + nrf_wifi_osal_llist_del_node(opriv, + list, + list_node); + + nrf_wifi_osal_llist_node_free(opriv, + list_node); + } + + list_node = list_node_next; + } +} + +void *nrf_wifi_utils_list_del_head(struct nrf_wifi_osal_priv *opriv, + void *list) +{ + void *list_node = NULL; + void *data = NULL; + + list_node = nrf_wifi_osal_llist_get_node_head(opriv, + list); + + if (!list_node) { + goto out; + } + + data = nrf_wifi_osal_llist_node_data_get(opriv, + list_node); + + nrf_wifi_osal_llist_del_node(opriv, + list, + list_node); + nrf_wifi_osal_llist_node_free(opriv, + list_node); + +out: + return data; +} + + +void *nrf_wifi_utils_list_peek(struct nrf_wifi_osal_priv *opriv, + void *list) +{ + void *list_node = NULL; + void *data = NULL; + + list_node = nrf_wifi_osal_llist_get_node_head(opriv, + list); + + if (!list_node) { + goto out; + } + + data = nrf_wifi_osal_llist_node_data_get(opriv, + list_node); + +out: + return data; +} + + +unsigned int nrf_wifi_utils_list_len(struct nrf_wifi_osal_priv *opriv, + void *list) +{ + return nrf_wifi_osal_llist_len(opriv, + list); +} + + +enum nrf_wifi_status +nrf_wifi_utils_list_traverse(struct nrf_wifi_osal_priv *opriv, + void *list, + void *callbk_data, + enum nrf_wifi_status (*callbk_func)(void *callbk_data, + void *data)) +{ + void *list_node = NULL; + void *data = NULL; + enum nrf_wifi_status status = NRF_WIFI_STATUS_FAIL; + + list_node = nrf_wifi_osal_llist_get_node_head(opriv, + list); + + while (list_node) { + data = nrf_wifi_osal_llist_node_data_get(opriv, + list_node); + + status = callbk_func(callbk_data, + data); + + if (status != NRF_WIFI_STATUS_SUCCESS) { + goto out; + } + + list_node = nrf_wifi_osal_llist_get_node_nxt(opriv, + list, + list_node); + } +out: + return status; +} diff --git a/nrf_wifi/utils/src/queue.c b/nrf_wifi/utils/src/queue.c new file mode 100644 index 0000000000..5f5012130b --- /dev/null +++ b/nrf_wifi/utils/src/queue.c @@ -0,0 +1,69 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing queue specific definitions + * for the Wi-Fi driver. + */ + +#include "list.h" +#include "queue.h" + +void *nrf_wifi_utils_q_alloc(struct nrf_wifi_osal_priv *opriv) +{ + return nrf_wifi_utils_list_alloc(opriv); +} + + +void nrf_wifi_utils_q_free(struct nrf_wifi_osal_priv *opriv, + void *q) +{ + nrf_wifi_utils_list_free(opriv, + q); +} + + +enum nrf_wifi_status nrf_wifi_utils_q_enqueue(struct nrf_wifi_osal_priv *opriv, + void *q, + void *data) +{ + return nrf_wifi_utils_list_add_tail(opriv, + q, + data); +} + +enum nrf_wifi_status nrf_wifi_utils_q_enqueue_head(struct nrf_wifi_osal_priv *opriv, + void *q, + void *data) +{ + return nrf_wifi_utils_list_add_head(opriv, + q, + data); +} + + +void *nrf_wifi_utils_q_dequeue(struct nrf_wifi_osal_priv *opriv, + void *q) +{ + return nrf_wifi_utils_list_del_head(opriv, + q); +} + + +void *nrf_wifi_utils_q_peek(struct nrf_wifi_osal_priv *opriv, + void *q) +{ + return nrf_wifi_utils_list_peek(opriv, + q); +} + + +unsigned int nrf_wifi_utils_q_len(struct nrf_wifi_osal_priv *opriv, + void *q) +{ + return nrf_wifi_utils_list_len(opriv, + q); +} diff --git a/nrf_wifi/utils/src/util.c b/nrf_wifi/utils/src/util.c new file mode 100644 index 0000000000..9aebb29fe8 --- /dev/null +++ b/nrf_wifi/utils/src/util.c @@ -0,0 +1,139 @@ +/* + * Copyright (c) 2022 Nordic Semiconductor ASA + * + * SPDX-License-Identifier: BSD-3-Clause + */ + +/** + * @brief File containing utility function definitions for the + * Wi-Fi driver. + */ + +#include +#include "host_rpu_data_if.h" + + +int nrf_wifi_utils_hex_str_to_val(struct nrf_wifi_osal_priv *opriv, + unsigned char *hex_arr, + unsigned int hex_arr_sz, + unsigned char *str) +{ + unsigned int i = 0; + unsigned int j = 0; + unsigned char ch = 0; + unsigned char val = 0; + unsigned int len = 0; + int ret = -1; + + len = nrf_wifi_osal_strlen(opriv, str); + + if (len / 2 > hex_arr_sz) { + nrf_wifi_osal_log_err(opriv, + "%s: String length (%d) greater than array size (%d)\n", + __func__, + len, + hex_arr_sz); + goto out; + } + + if (len % 2) { + nrf_wifi_osal_log_err(opriv, + "%s:String length = %d, is not a multiple of 2\n", + __func__, + len); + goto out; + } + + for (i = 0; i < len; i++) { + /* Convert each character to lower case */ + ch = ((str[i] >= 'A' && str[i] <= 'Z') ? str[i] + 32 : str[i]); + + if ((ch < '0' || ch > '9') && (ch < 'a' || ch > 'f')) { + nrf_wifi_osal_log_err(opriv, + "%s: Invalid hex character in string %d\n", + __func__, + ch); + goto out; + } + + if (ch >= '0' && ch <= '9') { + ch = ch - '0'; + } else { + ch = ch - 'a' + 10; + } + + val += ch; + + if (!(i % 2)) { + val <<= 4; + } else { + hex_arr[j] = val; + j++; + val = 0; + } + } + + ret = j; +out: + return ret; +} + + +bool nrf_wifi_utils_is_mac_addr_valid(struct nrf_wifi_osal_priv *opriv, + const char *mac_addr) +{ + unsigned char zero_addr[NRF_WIFI_ETH_ADDR_LEN] = {0}; + + return (mac_addr && + (nrf_wifi_osal_mem_cmp(opriv, + mac_addr, + zero_addr, + sizeof(zero_addr)) != 0) && + !(mac_addr[0] & 0x1)); +} + + +int nrf_wifi_utils_chan_to_freq(struct nrf_wifi_osal_priv *opriv, + enum nrf_wifi_band band, + unsigned short chan) +{ + int freq = -1; + unsigned short valid_5g_chans[] = {32, 36, 40, 44, 48, 52, 56, 60, 64, 68, 96, 100, 104, + 108, 112, 116, 120, 124, 128, 132, 136, 140, 144, 149, 153, 157, 159, 161, 163, + 165, 167, 169, 171, 173, 175, 177}; + unsigned char i = 0; + + switch (band) { + case NRF_WIFI_BAND_2GHZ: + if ((chan >= 1) && (chan <= 13)) { + freq = (((chan - 1) * 5) + 2412); + } else if (chan == 14) { + freq = 2484; + } else { + nrf_wifi_osal_log_err(opriv, + "%s: Invalid channel value %d\n", + __func__, + chan); + goto out; + } + break; + case NRF_WIFI_BAND_5GHZ: + for (i = 0; i < ARRAY_SIZE(valid_5g_chans); i++) { + if (chan == valid_5g_chans[i]) { + freq = (chan * 5) + 5000; + break; + } + } + + break; + default: + nrf_wifi_osal_log_err(opriv, + "%s: Invalid band value %d\n", + __func__, + band); + goto out; + } +out: + return freq; + +}